From: David Laight <david.laight.linux@gmail.com>
To: Brahmajit Das <listout@listout.xyz>
Cc: syzbot+d1b7fa1092def3628bd7@syzkaller.appspotmail.com,
andrii@kernel.org, ast@kernel.org, bpf@vger.kernel.org,
contact@arnaud-lcm.com, daniel@iogearbox.net, eddyz87@gmail.com,
haoluo@google.com, john.fastabend@gmail.com, jolsa@kernel.org,
kpsingh@kernel.org, linux-kernel@vger.kernel.org,
martin.lau@linux.dev, netdev@vger.kernel.org, sdf@fomichev.me,
song@kernel.org, syzkaller-bugs@googlegroups.com,
yonghong.song@linux.dev
Subject: Re: [PATCH bpf-next v3] bpf: Clamp trace length in __bpf_get_stack to fix OOB write
Date: Wed, 12 Nov 2025 13:35:46 +0000 [thread overview]
Message-ID: <20251112133546.4246533f@pumpkin> (raw)
In-Reply-To: <20251111081254.25532-1-listout@listout.xyz>
On Tue, 11 Nov 2025 13:42:54 +0530
Brahmajit Das <listout@listout.xyz> wrote:
> syzbot reported a stack-out-of-bounds write in __bpf_get_stack()
> triggered via bpf_get_stack() when capturing a kernel stack trace.
>
> After the recent refactor that introduced stack_map_calculate_max_depth(),
> the code in stack_map_get_build_id_offset() (and related helpers) stopped
> clamping the number of trace entries (`trace_nr`) to the number of elements
> that fit into the stack map value (`num_elem`).
>
> As a result, if the captured stack contained more frames than the map value
> can hold, the subsequent memcpy() would write past the end of the buffer,
> triggering a KASAN report like:
>
> BUG: KASAN: stack-out-of-bounds in __bpf_get_stack+0x...
> Write of size N at addr ... by task syz-executor...
>
> Restore the missing clamp by limiting `trace_nr` to `num_elem` before
> computing the copy length. This mirrors the pre-refactor logic and ensures
> we never copy more bytes than the destination buffer can hold.
>
> No functional change intended beyond reintroducing the missing bound check.
>
> Reported-by: syzbot+d1b7fa1092def3628bd7@syzkaller.appspotmail.com
> Fixes: e17d62fedd10 ("bpf: Refactor stack map trace depth calculation into helper function")
> Signed-off-by: Brahmajit Das <listout@listout.xyz>
> ---
> Changes in v3:
> Revert back to num_elem based logic for setting trace_nr. This was
> suggested by bpf-ci bot, mainly pointing out the chances of underflow
> when max_depth < skip.
>
> Quoting the bot's reply:
> The stack_map_calculate_max_depth() function can return a value less than
> skip when sysctl_perf_event_max_stack is lowered below the skip value:
>
> max_depth = size / elem_size;
> max_depth += skip;
> if (max_depth > curr_sysctl_max_stack)
> return curr_sysctl_max_stack;
>
> If sysctl_perf_event_max_stack = 10 and skip = 20, this returns 10.
>
> Then max_depth - skip = 10 - 20 underflows to 4294967286 (u32 wraps),
> causing min_t() to not limit trace_nr at all. This means the original OOB
> write is not fixed in cases where skip > max_depth.
>
> With the default sysctl_perf_event_max_stack = 127 and skip up to 255, this
> scenario is reachable even without admin changing sysctls.
>
> Changes in v2:
> - Use max_depth instead of num_elem logic, this logic is similar to what
> we are already using __bpf_get_stackid
> Link: https://lore.kernel.org/all/20251111003721.7629-1-listout@listout.xyz/
>
> Changes in v1:
> - RFC patch that restores the number of trace entries by setting
> trace_nr to trace_nr or num_elem based on whichever is the smallest.
> Link: https://lore.kernel.org/all/20251110211640.963-1-listout@listout.xyz/
> ---
> kernel/bpf/stackmap.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c
> index 2365541c81dd..cef79d9517ab 100644
> --- a/kernel/bpf/stackmap.c
> +++ b/kernel/bpf/stackmap.c
> @@ -426,7 +426,7 @@ static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task,
> struct perf_callchain_entry *trace_in,
> void *buf, u32 size, u64 flags, bool may_fault)
> {
> - u32 trace_nr, copy_len, elem_size, max_depth;
> + u32 trace_nr, copy_len, elem_size, num_elem, max_depth;
> bool user_build_id = flags & BPF_F_USER_BUILD_ID;
> bool crosstask = task && task != current;
> u32 skip = flags & BPF_F_SKIP_FIELD_MASK;
> @@ -480,6 +480,8 @@ static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task,
> }
>
> trace_nr = trace->nr - skip;
> + num_elem = size / elem_size;
> + trace_nr = min_t(u32, trace_nr, num_elem);
Please can we have no unnecessary min_t().
You wouldn't write:
x = (u32)a < (u32)b ? (u32)a : (u32)b;
David
> copy_len = trace_nr * elem_size;
>
> ips = trace->ip + skip;
next prev parent reply other threads:[~2025-11-12 13:35 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-10 18:41 [syzbot] [bpf?] KASAN: stack-out-of-bounds Write in __bpf_get_stack syzbot
2025-11-10 19:01 ` Forwarded: " syzbot
2025-11-10 19:17 ` syzbot
2025-11-10 20:58 ` syzbot
2025-11-10 21:16 ` [RFC bpf-next PATCH] bpf: Clamp trace length in __bpf_get_stack to fix OOB write Brahmajit Das
2025-11-10 23:43 ` Forwarded: Re: [syzbot] [bpf?] KASAN: stack-out-of-bounds Write in __bpf_get_stack syzbot
2025-11-11 0:21 ` syzbot
2025-11-11 0:37 ` [PATCH bpf-next v2] bpf: Clamp trace length in __bpf_get_stack to fix OOB write Brahmajit Das
2025-11-11 1:04 ` bot+bpf-ci
2025-11-11 8:12 ` [PATCH bpf-next v3] " Brahmajit Das
2025-11-12 1:44 ` Yonghong Song
2025-11-12 8:40 ` Lecomte, Arnaud
2025-11-12 8:58 ` Brahmajit Das
2025-11-13 12:49 ` Brahmajit Das
2025-11-13 13:26 ` Lecomte, Arnaud
2025-11-13 13:49 ` Brahmajit Das
2025-11-12 13:35 ` David Laight [this message]
2025-11-12 14:47 ` Brahmajit Das
2025-11-12 16:11 ` Lecomte, Arnaud
2025-11-12 21:37 ` David Laight
2026-01-04 18:29 ` #syz test Arnaud Lecomte
2026-01-04 20:09 ` [syzbot] [bpf?] KASAN: stack-out-of-bounds Write in __bpf_get_stack syzbot
2026-01-04 18:30 ` #syz test Arnaud Lecomte
2026-01-04 20:43 ` [syzbot] [bpf?] KASAN: stack-out-of-bounds Write in __bpf_get_stack syzbot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251112133546.4246533f@pumpkin \
--to=david.laight.linux@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=contact@arnaud-lcm.com \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=haoluo@google.com \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=kpsingh@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=listout@listout.xyz \
--cc=martin.lau@linux.dev \
--cc=netdev@vger.kernel.org \
--cc=sdf@fomichev.me \
--cc=song@kernel.org \
--cc=syzbot+d1b7fa1092def3628bd7@syzkaller.appspotmail.com \
--cc=syzkaller-bugs@googlegroups.com \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.