From: sashiko-bot@kernel.org
To: "Alexei Starovoitov" <alexei.starovoitov@gmail.com>, bpf@vger.kernel.org
Subject: Re: [PATCH bpf-next 17/38] bpf: Bound the nesting that the BTF show code follows
Date: Sat, 17 Oct 2026 01:46:21 +0000 [thread overview]
Message-ID: <sashiko-outbox-175149@kernel.org> (raw)
In-Reply-To: <20261017012451.364800-9-alexei.starovoitov@gmail.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] bpf: btf_show_obj_safe() clobbers -E2BIG set by btf_show_start_aggr_type()
- [Medium] bpf: btf_show_start_array_type() leaks array_encoding on max depth error
--
commit f2e2b108df464bcad9ef6d63627fcf113f33d61f
Author: Josef Bacik <josef@toxicpanda.com>
bpf: Bound the nesting that the BTF show code follows
This commit limits the recursion depth in btf_show_start_aggr_type() to
BTF_SHOW_MAX_DEPTH (32) and sets show->state.status to -E2BIG to prevent
kernel stack overflows when pretty-printing deeply nested BTF structs and
arrays.
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index 64c78434fa050..a9bf4c3c0a273 100644
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
> @@ -1081,6 +1081,8 @@ static const struct btf_type *btf_type_skip_qualifiers(const struct btf *btf,
> }
>
> #define BTF_SHOW_MAX_ITER 10
> +/* nested structs and arrays shown; __btf_show_indent() has as many columns */
> +#define BTF_SHOW_MAX_DEPTH 32
>
> #define BTF_KIND_BIT(kind) (1ULL << kind)
>
> @@ -1474,8 +1476,18 @@ static void *btf_show_start_aggr_type(struct btf_show *show,
> const struct btf_type *t,
> u32 type_id, void *data)
> {
> - void *safe_data = btf_show_start_type(show, t, type_id, data);
> + void *safe_data;
>
> + /*
> + * Structs and arrays are shown by recursion. BTF loading bounds the
> + * depth of one resolve walk, not how deep resolved types may nest.
> + */
> + if (show->state.depth >= BTF_SHOW_MAX_DEPTH) {
> + show->state.status = -E2BIG;
> + return NULL;
> + }
[Severity: Medium]
Can show->state.status = -E2BIG get overwritten by a subsequent call to
btf_show_obj_safe()?
Returning NULL from btf_show_start_aggr_type() stops the current aggregate at
depth 32, but enclosing callers in __btf_struct_show() and __btf_array_show()
continue iterating over their remaining members or elements (as well as running
the second display pass after the depth_check pass in btf_struct_show() and
btf_array_show() when BTF_SHOW_ZERO is not set).
When bpf_snprintf_btf() or bpf_seq_printf_btf() runs, BTF_SHOW_UNSAFE is not
set. If any subsequent member or pass calls
btf_show_start_type()->btf_show_obj_safe() for data outside the current 32-byte
show->obj.safe window, btf_show_obj_safe() unconditionally overwrites
show->state.status:
kernel/bpf/btf.c:btf_show_obj_safe() {
if (!safe) {
size_left = btf_show_obj_size_left(show, data);
if (size_left > BTF_SHOW_OBJ_SAFE_SIZE)
size_left = BTF_SHOW_OBJ_SAFE_SIZE;
show->state.status = copy_from_kernel_nofault(show->obj.safe,
data, size_left);
if (!show->state.status) {
show->obj.data = data;
safe = show->obj.safe;
}
}
}
When copy_from_kernel_nofault() succeeds, show->state.status is reset to 0, so
btf_type_snprintf_show() and btf_type_seq_show_flags() will return success
instead of -E2BIG.
[Severity: Medium]
Also, when btf_show_start_aggr_type() returns NULL at BTF_SHOW_MAX_DEPTH, does
btf_show_start_array_type() leave show->state.array_encoding set?
In __btf_array_show(), a 1-byte integer array sets encoding = BTF_INT_CHAR and
calls btf_show_start_array_type(), which sets show->state.array_encoding before
calling btf_show_start_aggr_type():
kernel/bpf/btf.c:btf_show_start_array_type() {
show->state.array_encoding = array_encoding;
show->state.array_terminated = 0;
return btf_show_start_aggr_type(show, t, type_id, data);
}
When btf_show_start_aggr_type() returns NULL, __btf_array_show() returns early
without calling btf_show_end_array_type() to clear show->state.array_encoding:
kernel/bpf/btf.c:__btf_array_show() {
if (!btf_show_start_array_type(show, t, type_id, encoding, data))
return;
}
When recursion unwinds to enclosing structs, any subsequent scalar 8-bit
integer member visited by btf_int_show() will see
show->state.array_encoding == BTF_INT_CHAR, causing printable bytes to be
formatted as character literals and a zero byte to set
show->state.array_terminated = 1, suppressing subsequent 8-bit integer fields:
kernel/bpf/btf.c:btf_int_show() {
case 8:
if (show->state.array_encoding == BTF_INT_CHAR) {
/* check for null terminator */
if (show->state.array_terminated)
break;
if (*(char *)data == '\0') {
show->state.array_terminated = 1;
break;
}
}
> +
> + safe_data = btf_show_start_type(show, t, type_id, data);
> if (!safe_data)
> return safe_data;
>
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261017012058.355787-1-alexei.starovoitov@gmail.com?part=17
next prev parent reply other threads:[~2026-10-17 1:46 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-17 1:20 [PATCH bpf-next 00/38] bpf: Memory safety, lifetime and locking fixes Alexei Starovoitov
2026-10-17 1:20 ` [PATCH bpf-next 01/38] bpf: use the frame mem type in devmap egress XDP Alexei Starovoitov
2026-10-17 1:20 ` [PATCH bpf-next 02/38] bpf: forbid sleeping in hash map for_each callbacks Alexei Starovoitov
2026-10-17 1:20 ` [PATCH bpf-next 03/38] bpf: don't leak the inode when token creation fails Alexei Starovoitov
2026-10-17 1:20 ` [PATCH bpf-next 04/38] bpf: don't hand out a linked element as extra element Alexei Starovoitov
2026-10-17 1:45 ` sashiko-bot
2026-10-17 1:52 ` bot+bpf-ci
2026-10-17 1:20 ` [PATCH bpf-next 05/38] bpf: reject sleepable programs for task_vma iterator Alexei Starovoitov
2026-10-17 1:20 ` [PATCH bpf-next 06/38] bpf: forbid sleeping in bpf_find_vma() callbacks Alexei Starovoitov
2026-10-17 1:20 ` [PATCH bpf-next 07/38] bpf: look at all 64 bits of a BPF_JSET mask on 32-bit Alexei Starovoitov
2026-10-17 1:20 ` [PATCH bpf-next 08/38] bpf: don't let bpf_skb_adjust_room() use up the MSS Alexei Starovoitov
2026-10-17 1:51 ` sashiko-bot
2026-10-17 1:24 ` [PATCH bpf-next 09/38] bpf: Read the probe of a perf event under event_mutex Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 10/38] bpf: Don't saturate owner_refcnt on the last unpin Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 11/38] bpf: Validate the SRH which End.DT6 uncovers in End.BPF Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 12/38] bpf: Pull the inner header for End.DT6 " Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 13/38] bpf: Update the SRH state if End.B6 fails late Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 14/38] bpf: Clear sk_refcnt of a clone before its storage is linked Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 15/38] bpf: Fix NULL deref in the sk_storage map iterator Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 16/38] bpf: Hold the socket " Alexei Starovoitov
2026-10-17 2:02 ` bot+bpf-ci
2026-10-17 1:24 ` [PATCH bpf-next 17/38] bpf: Bound the nesting that the BTF show code follows Alexei Starovoitov
2026-10-17 1:46 ` sashiko-bot [this message]
2026-10-17 1:24 ` [PATCH bpf-next 18/38] bpf: Check the new program of an iterator link update Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 19/38] bpf: Fix stale offload->prog pointer after realloc Alexei Starovoitov
2026-10-17 1:45 ` sashiko-bot
2026-10-17 1:52 ` bot+bpf-ci
2026-10-17 1:24 ` [PATCH bpf-next 20/38] bpf: Don't bind a program to a netdev that goes away Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 21/38] bpf: Keep a program until its bpf_wq callback has ended Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 22/38] bpf: Count sleepable callbacks as sleepable map users Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 23/38] bpf: Check the maps that sleepable callbacks use Alexei Starovoitov
2026-10-17 1:58 ` sashiko-bot
2026-10-17 1:24 ` [PATCH bpf-next 24/38] bpf: Assume no bounds for buffers behind a tail call Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 25/38] bpf: Don't take an extension for an iterator program Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 26/38] bpf: Assume no bounds for a writable tp with tail calls Alexei Starovoitov
2026-10-17 2:05 ` sashiko-bot
2026-10-17 1:24 ` [PATCH bpf-next 27/38] bpf: Keep iterator programs off special map fields Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 28/38] bpf: Free what map_free() unlinks for sleepable readers Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 29/38] bpf: Keep values of a dead owner for sleepable programs Alexei Starovoitov
2026-10-17 2:10 ` sashiko-bot
2026-10-17 1:24 ` [PATCH bpf-next 30/38] bpf: Keep the symbols of a program until it has ended Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 31/38] bpf: Use the socket of a sk_lookup test run under RCU Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 32/38] bpf, cpumap: Hold the device of frames in the queue Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 33/38] bpf: Drop packet pointers behind kfuncs writing an skb Alexei Starovoitov
2026-10-17 2:10 ` sashiko-bot
2026-10-17 1:24 ` [PATCH bpf-next 34/38] bpf: Let bpf_dynptr_write() mark a global function Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 35/38] bpf: Don't take a dynptr argument for a local dynptr Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 36/38] bpf: Follow the head if an skb is written from a slice Alexei Starovoitov
2026-10-17 2:05 ` sashiko-bot
2026-10-17 1:24 ` [PATCH bpf-next 37/38] bpf: Use memmove() to store bytes in an skb Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 38/38] bpf: Refuse packet slices for packet-changing helpers Alexei Starovoitov
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=sashiko-outbox-175149@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=alexei.starovoitov@gmail.com \
--cc=bpf@vger.kernel.org \
--cc=sashiko-reviews@lists.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.