summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@kernel.org>2026-08-03 23:01:42 +0200
committerAndrii Nakryiko <andrii@kernel.org>2026-08-05 11:32:29 -0700
commit15f1bd8574662f1b7b26aaa2e23ebf4066f0117d (patch)
treed862a627a30cda3b47afad8adf2d99e4b6e8bcb4 /kernel
parent09b3fd6caa0b57f8a39254ee5db3af30bdd53c18 (diff)
bpf: Disable preemption in bpf_get_stackid
The get_perf_callchain call needs disabled preemption plus we need it disabled as long as we access its returned trace entries buffer. Note the bpf_get_stackid_pe function is executed already with preemption disabled. Fixes: d5a3b1f69186 ("bpf: introduce BPF_MAP_TYPE_STACK_TRACE") Reported-by: Tao Chen <chen.dylane@linux.dev> Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/bpf/20260803210149.296496-6-jolsa@kernel.org Closes: https://lore.kernel.org/bpf/20260206090653.1336687-2-chen.dylane@linux.dev/
Diffstat (limited to 'kernel')
-rw-r--r--kernel/bpf/stackmap.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c
index 3ee0034daf52..5b18d728f4b8 100644
--- a/kernel/bpf/stackmap.c
+++ b/kernel/bpf/stackmap.c
@@ -632,20 +632,22 @@ BPF_CALL_3(bpf_get_stackid, struct pt_regs *, regs, struct bpf_map *, map,
return -EINVAL;
max_depth = stack_map_calculate_max_depth(map->value_size, elem_size, flags);
- trace = get_perf_callchain(regs, kernel, user, max_depth,
- false, false, 0);
- if (unlikely(!trace))
- /* couldn't fetch the stack trace */
- return -EFAULT;
+ scoped_guard(preempt) {
+ trace = get_perf_callchain(regs, kernel, user, max_depth,
+ false, false, 0);
+ if (unlikely(!trace))
+ /* couldn't fetch the stack trace */
+ return -EFAULT;
- err = stackid_fastpath(&stackid, map, trace, flags);
- if (err != -ENOENT)
- return err;
+ err = stackid_fastpath(&stackid, map, trace, flags);
+ if (err != -ENOENT)
+ return err;
- new_bucket = stackid_new_bucket(&stackid, map);
- if (!new_bucket)
- return -ENOMEM;
+ new_bucket = stackid_new_bucket(&stackid, map);
+ if (!new_bucket)
+ return -ENOMEM;
+ }
return stackid_install(&stackid, map, new_bucket, flags);
}