Re: [PATCH bpf-next v4 2/2] bpf: guard stack limits against 32bit overflow

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Dec 6, 2023 at 8:58 AM Andrei Matei <andreimatei1@xxxxxxxxx> wrote:
>
> This patch promotes the arithmetic around checking stack bounds to be
> done in the 64-bit domain, instead of the current 32bit. The arithmetic
> implies adding together a 64-bit register with a int offset. The
> register was checked to be below 1<<29 when it was variable, but not
> when it was fixed. The offset either comes from an instruction (in which
> case it is 16 bit), from another register (in which case the caller
> checked it to be below 1<<29 [1]), or from the size of an argument to a
> kfunc (in which case it can be a u32 [2]). Between the register being
> inconsistently checked to be below 1<<29, and the offset being up to an
> u32, it appears that we were open to overflowing the `int`s which were
> currently used for arithmetic.
>
> [1] https://github.com/torvalds/linux/blob/815fb87b753055df2d9e50f6cd80eb10235fe3e9/kernel/bpf/verifier.c#L7494-L7498
> [2] https://github.com/torvalds/linux/blob/815fb87b753055df2d9e50f6cd80eb10235fe3e9/kernel/bpf/verifier.c#L11904
>
> Signed-off-by: Andrei Matei <andreimatei1@xxxxxxxxx>
> Reported-by: Andrii Nakryiko <andrii.nakryiko@xxxxxxxxx>
> ---
>  kernel/bpf/verifier.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>

LGTM

Acked-by: Andrii Nakryiko <andrii@xxxxxxxxxx>

> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 137240681fa9..6832ed743765 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -6577,7 +6577,7 @@ static int check_ptr_to_map_access(struct bpf_verifier_env *env,
>   * The minimum valid offset is -MAX_BPF_STACK for writes, and
>   * -state->allocated_stack for reads.
>   */
> -static int check_stack_slot_within_bounds(int off,
> +static int check_stack_slot_within_bounds(s64 off,
>                                           struct bpf_func_state *state,
>                                           enum bpf_access_type t)
>  {
> @@ -6606,7 +6606,7 @@ static int check_stack_access_within_bounds(
>         struct bpf_reg_state *regs = cur_regs(env);
>         struct bpf_reg_state *reg = regs + regno;
>         struct bpf_func_state *state = func(env, reg);
> -       int min_off, max_off;
> +       s64 min_off, max_off;
>         int err;
>         char *err_extra;
>
> @@ -6619,7 +6619,7 @@ static int check_stack_access_within_bounds(
>                 err_extra = " write to";
>
>         if (tnum_is_const(reg->var_off)) {
> -               min_off = reg->var_off.value + off;
> +               min_off = (s64)reg->var_off.value + off;
>                 max_off = min_off + access_size;
>         } else {
>                 if (reg->smax_value >= BPF_MAX_VAR_OFF ||
> --
> 2.39.2
>





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux