* [PATCH bpf v2] bpf: Add nelems overflow check in btf_find_field_one()
@ 2026-05-23 7:47 Himanshu Anand
2026-05-23 8:20 ` sashiko-bot
2026-05-23 8:30 ` Alexei Starovoitov
0 siblings, 2 replies; 3+ messages in thread
From: Himanshu Anand @ 2026-05-23 7:47 UTC (permalink / raw)
To: ast, daniel, andrii, martin.lau; +Cc: bpf, linux-kernel, Himanshu Anand
btf_find_field_one() multiplies a u32 nelems accumulator by each
nested array level's element count without checking for overflow.
The sibling function __btf_resolve_size() already guards against
the same overflow pattern (btf.c line 2110).
Currently the BTF array verifier (btf_array_resolve) rejects BTF
blobs whose total array size would overflow u32, so this code path
is not reachable with crafted BTF input on kernels that include
that check. Add check_mul_overflow() anyway to keep
btf_find_field_one() self-consistent with __btf_resolve_size()
and to guard against future changes in the validation ordering.
Fixes: 994796c0256c ("bpf: create repeated fields for arrays.")
Signed-off-by: Himanshu Anand <anand.himanshu17@gmail.com>
---
kernel/bpf/btf.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index a62d78581207..b767a9fcf095 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -3765,7 +3765,8 @@ static int btf_find_field_one(const struct btf *btf,
*/
for (i = 0; i < MAX_RESOLVE_DEPTH && btf_type_is_array(var_type); i++) {
array = btf_array(var_type);
- nelems *= array->nelems;
+ if (check_mul_overflow(nelems, array->nelems, &nelems))
+ return -E2BIG;
var_type = btf_type_by_id(btf, array->type);
}
if (i == MAX_RESOLVE_DEPTH)
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH bpf v2] bpf: Add nelems overflow check in btf_find_field_one()
2026-05-23 7:47 [PATCH bpf v2] bpf: Add nelems overflow check in btf_find_field_one() Himanshu Anand
@ 2026-05-23 8:20 ` sashiko-bot
2026-05-23 8:30 ` Alexei Starovoitov
1 sibling, 0 replies; 3+ messages in thread
From: sashiko-bot @ 2026-05-23 8:20 UTC (permalink / raw)
To: Himanshu Anand; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [Critical] The patch leaves a critical 32-bit integer overflow in `btf_repeat_fields()` unprotected, leading to a stack buffer overflow.
--
commit d1acecf46d6faa37ff66d19a08184489e682b397
Author: Himanshu Anand <anand.himanshu17@gmail.com>
bpf: Add nelems overflow check in btf_find_field_one()
This commit adds an overflow check when multiplying nested array element
counts in btf_find_field_one(). This aims to make the logic consistent with
__btf_resolve_size() and guards against future validation ordering changes.
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index a62d785812076..b767a9fcf095d 100644
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
> @@ -3765,7 +3765,8 @@ static int btf_find_field_one(const struct btf *btf,
> */
> for (i = 0; i < MAX_RESOLVE_DEPTH && btf_type_is_array(var_type); i++) {
> array = btf_array(var_type);
> - nelems *= array->nelems;
> + if (check_mul_overflow(nelems, array->nelems, &nelems))
> + return -E2BIG;
> var_type = btf_type_by_id(btf, array->type);
> }
> if (i == MAX_RESOLVE_DEPTH)
[Severity: Critical]
This isn't a bug introduced by this patch, but does the bounds check in
btf_repeat_fields() further down in this function still have a 32-bit
integer overflow?
The commit message mentions that btf_array_resolve() prevents the total
array size from overflowing u32, meaning sz * nelems <= U32_MAX. However,
could a crafted BTF union with 11 struct members (field_cnt = 11) and an
element size of 8 bypass the validation if nelems is 390451573?
The array size check would pass since 390451573 * 8 = 3123612584 <= U32_MAX.
When btf_repeat_fields() is called at the end of this function:
if (nelems > 1) {
ret = btf_repeat_fields(info, info_cnt, 1, nelems - 1, sz);
...
}
Is the multiplication field_cnt * (repeat_cnt + 1) inside
btf_repeat_fields() evaluated as a 32-bit operation? If so,
11 * 390451573 = 4294967303, which wraps around to 7.
Since 7 <= 11, wouldn't this bypass the bounds check and lead to an
out-of-bounds memcpy on the stack-allocated info_arr[BTF_FIELDS_MAX],
potentially overwriting kernel stack memory?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260523074736.222994-1-anand.himanshu17@gmail.com?part=1
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH bpf v2] bpf: Add nelems overflow check in btf_find_field_one()
2026-05-23 7:47 [PATCH bpf v2] bpf: Add nelems overflow check in btf_find_field_one() Himanshu Anand
2026-05-23 8:20 ` sashiko-bot
@ 2026-05-23 8:30 ` Alexei Starovoitov
1 sibling, 0 replies; 3+ messages in thread
From: Alexei Starovoitov @ 2026-05-23 8:30 UTC (permalink / raw)
To: Himanshu Anand
Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, bpf, LKML
On Sat, May 23, 2026 at 9:47 AM Himanshu Anand
<anand.himanshu17@gmail.com> wrote:
>
> btf_find_field_one() multiplies a u32 nelems accumulator by each
> nested array level's element count without checking for overflow.
> The sibling function __btf_resolve_size() already guards against
> the same overflow pattern (btf.c line 2110).
>
> Currently the BTF array verifier (btf_array_resolve) rejects BTF
> blobs whose total array size would overflow u32, so this code path
> is not reachable with crafted BTF input on kernels that include
> that check. Add check_mul_overflow() anyway to keep
> btf_find_field_one() self-consistent with __btf_resolve_size()
> and to guard against future changes in the validation ordering.
>
> Fixes: 994796c0256c ("bpf: create repeated fields for arrays.")
> Signed-off-by: Himanshu Anand <anand.himanshu17@gmail.com>
> ---
> kernel/bpf/btf.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index a62d78581207..b767a9fcf095 100644
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
> @@ -3765,7 +3765,8 @@ static int btf_find_field_one(const struct btf *btf,
> */
> for (i = 0; i < MAX_RESOLVE_DEPTH && btf_type_is_array(var_type); i++) {
> array = btf_array(var_type);
> - nelems *= array->nelems;
> + if (check_mul_overflow(nelems, array->nelems, &nelems))
> + return -E2BIG;
It's unnecessary.
see __btf_resolve_size() and btf_array_resolve().
pw-bot: cr
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-05-23 8:30 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-23 7:47 [PATCH bpf v2] bpf: Add nelems overflow check in btf_find_field_one() Himanshu Anand
2026-05-23 8:20 ` sashiko-bot
2026-05-23 8:30 ` Alexei Starovoitov
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.