All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.