Re: [PATCH bpf] bpf: unconditionally reset backtrack_state masks on global func exit

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

 



On Mon, Sep 18, 2023 at 2:01 PM Andrii Nakryiko <andrii@xxxxxxxxxx> wrote:
>
> In mark_chain_precision() logic, when we reach the entry to a global
> func, it is expected that R1-R5 might be still requested to be marked
> precise. This would correspond to some integer input arguments being
> tracked as precise. This is all expected and handled as a special case.
>
> What's not expected is that we'll leave backtrack_state structure with
> some register bits set. This is because for subsequent precision
> propagations backtrack_state is reused without clearing masks, as all
> code paths are carefully written in a way to leave empty backtrack_state
> with zeroed out masks, for speed.
>
> The fix is trivial, we always clear register bit in the register mask, and
> then, optionally, set reg->precise if register is SCALAR_VALUE type.
>
> Reported-by: Chris Mason <clm@xxxxxxxx>
> Fixes: be2ef8161572 ("bpf: allow precision tracking for programs with subprogs")
> Signed-off-by: Andrii Nakryiko <andrii@xxxxxxxxxx>
> ---
>  kernel/bpf/verifier.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index bb78212fa5b2..c0c7d137066a 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -4047,11 +4047,9 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno)
>                                 bitmap_from_u64(mask, bt_reg_mask(bt));
>                                 for_each_set_bit(i, mask, 32) {
>                                         reg = &st->frame[0]->regs[i];
> -                                       if (reg->type != SCALAR_VALUE) {
> -                                               bt_clear_reg(bt, i);
> -                                               continue;
> -                                       }
> -                                       reg->precise = true;
> +                                       bt_clear_reg(bt, i);
> +                                       if (reg->type == SCALAR_VALUE)
> +                                               reg->precise = true;

Looks good, but is there a selftest that can demonstrate the issue?





[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