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 Tue, Sep 19, 2023 at 2:06 AM Alexei Starovoitov
<alexei.starovoitov@xxxxxxxxx> wrote:
>
> 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?

I'll see if I can write something small and reliable.





[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