On Wed, Apr 24, 2024 at 3:41 PM Cupertino Miranda <cupertino.miranda@xxxxxxxxxx> wrote: > > Added a test for bound computation in XOR and OR when non constant > values are used and both registers have bounded ranges. > > Signed-off-by: Cupertino Miranda <cupertino.miranda@xxxxxxxxxx> > Cc: Yonghong Song <yonghong.song@xxxxxxxxx> > Cc: Alexei Starovoitov <alexei.starovoitov@xxxxxxxxx> > Cc: David Faust <david.faust@xxxxxxxxxx> > Cc: Jose Marchesi <jose.marchesi@xxxxxxxxxx> > Cc: Elena Zannoni <elena.zannoni@xxxxxxxxxx> > --- > .../selftests/bpf/progs/verifier_bounds.c | 42 +++++++++++++++++++ > 1 file changed, 42 insertions(+) > > diff --git a/tools/testing/selftests/bpf/progs/verifier_bounds.c b/tools/testing/selftests/bpf/progs/verifier_bounds.c > index 960998f16306..aeb88a9c7a86 100644 > --- a/tools/testing/selftests/bpf/progs/verifier_bounds.c > +++ b/tools/testing/selftests/bpf/progs/verifier_bounds.c > @@ -885,6 +885,48 @@ l1_%=: r0 = 0; \ > : __clobber_all); > } > > +SEC("socket") > +__description("bounds check for non const xor src dst") > +__success __log_level(2) > +__msg("5: (af) r0 ^= r6 ; R0_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=255,var_off=(0x0; 0xff))") > +__naked void non_const_xor_src_dst(void) > +{ > + asm volatile (" \ > + call %[bpf_get_prandom_u32]; \ > + r6 = r0; \ > + call %[bpf_get_prandom_u32]; \ > + r6 &= 0xff; \ > + r0 &= 0x0f; \ > + r0 ^= r6; \ > + exit; \ > +" : > + : __imm(bpf_map_lookup_elem), > + __imm_addr(map_hash_8b), > + __imm(bpf_get_prandom_u32) > + : __clobber_all); > +} > + > +SEC("socket") > +__description("bounds check for non const or src dst") > +__success __log_level(2) > +__msg("5: (4f) r0 |= r6 ; R0_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=255,var_off=(0x0; 0xff))") > +__naked void non_const_or_src_dst(void) > +{ > + asm volatile (" \ > + call %[bpf_get_prandom_u32]; \ > + r6 = r0; \ > + call %[bpf_get_prandom_u32]; \ > + r6 &= 0xff; \ > + r0 &= 0x0f; \ > + r0 |= r6; \ what if we make this case a bit more challenging and interesting and have some known bits in r0? like add `r0 |= 0x1a0;` before doing `r0 | = r6;` and make sure that we have a few known bits in var_off() and range is extended to be 511? Maybe do something like that for xor case as well, making sure that we have some bits known to be either zero or one? > + exit; \ > +" : > + : __imm(bpf_map_lookup_elem), > + __imm_addr(map_hash_8b), > + __imm(bpf_get_prandom_u32) > + : __clobber_all); > +} > + do we have an existing case for AND as well? That seems to be an interesting one, as verifier should be able to infer [0, 0xf] range > SEC("socket") > __description("bounds checks after 32-bit truncation. test 1") > __success __failure_unpriv __msg_unpriv("R0 leaks addr") > -- > 2.39.2 > >