Both bpf_get_task_stack and bpf_get_task_stack_sleepable helpers that use __bpf_get_task_stack have buf defined as ARG_PTR_TO_UNINIT_MEM argument and we should initialize the buf on every return path. Adding missing buf memset for __bpf_get_task_stack fail paths. This provides deterministic buffer contents, which is useful when the buffer is used directly as a map key.
Unified · Split
| @@ -884,14 +884,17 @@ static long __bpf_get_task_stack(struct task_struct *task, void *buf, u32 size, · 883 unmodified lines | |||
| 884 | struct pt_regs *regs; | 884 | struct pt_regs *regs; |
| 885 | long res = -EINVAL; | 885 | long res = -EINVAL; |
| 886 | 886 | ||
| 887 | if (!try_get_task_stack(task)) | 887 | if (!try_get_task_stack(task)) { |
| 888 | memset(buf, 0, size); | ||
| 888 | return -EFAULT; | 889 | return -EFAULT; |
| 890 | } | ||
| 889 | 891 | ||
| 890 | regs = task_pt_regs(task); | 892 | regs = task_pt_regs(task); |
| 891 | if (regs) | 893 | if (regs) |
| 892 | res = __bpf_get_stack(regs, task, buf, size, flags, may_fault); | 894 | res = __bpf_get_stack(regs, task, buf, size, flags, may_fault); |
| 895 | else | ||
| 896 | memset(buf, 0, size); | ||
| 893 | put_task_stack(task); | 897 | put_task_stack(task); |
| 894 | |||
| 895 | return res; | 898 | return res; |
| 896 | } | 899 | } |
| 897 | 900 | ||