selftests/bpf: fix test_align
Subsystems (5)
PATCH 1/1 selftests/bpf: fix test_align
since commit 82abbf8d2fc4 the verifier rejects the bit-wise arithmetic on pointers earlier.
The test 'dubious pointer arithmetic' now has less output to match on. Adjust it.
--- tools/testing/selftests/bpf/test_align.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-)
tools/testing/selftests/bpf/test_align.c +1 -21
@@ -474,27 +474,7 @@ static struct bpf_align_test tests[] = { .result = REJECT, .matches = { {4, "R5=pkt(id=0,off=0,r=0,imm=0)"}, -/* ptr & 0x40 == either 0 or 0x40 */ - {5, "R5=inv(id=0,umax_value=64,var_off=(0x0; 0x40))"}, -/* ptr << 2 == unknown, (4n) */ - {7, "R5=inv(id=0,smax_value=9223372036854775804,umax_value=18446744073709551612,var_off=(0x0; 0xfffffffffffffffc))"}, -/* (4n) + 14 == (4n+2). We blow our bounds, because -* the add could overflow. -*/ - {8, "R5=inv(id=0,var_off=(0x2; 0xfffffffffffffffc))"}, -/* Checked s>=0 */ - {10, "R5=inv(id=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc))"}, -/* packet pointer + nonnegative (4n+2) */ - {12, "R6=pkt(id=1,off=0,r=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc))"}, - {14, "R4=pkt(id=1,off=4,r=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc))"}, -/* NET_IP_ALIGN + (4n+2) == (4n), alignment is fine. -* We checked the bounds, but it might have been able -* to overflow if the packet pointer started in the -* upper half of the address space. -* So we did not get a 'range' on R6, and the access -* attempt will fail. -*/ - {16, "R6=pkt(id=1,off=0,r=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc))"}, + /* R5 bitwise operator &= on pointer prohibited */ } }, {
Signature · 1 line
2.9.5
Quoted 35 lines · Alexei Starovoitov
since commit
82abbf8d2fc4the verifier rejects the bit-wise arithmetic on pointers earlier.
The test 'dubious pointer arithmetic' now has less output to match on. Adjust it.Fixes 82abbf8d2fc4 ("bpf: do not allow root to mangle valid pointers")Reported-by kernel test robot <[email protected]>Signed-off-by Alexei Starovoitov <[email protected]>--- tools/testing/selftests/bpf/test_align.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-)tools/testing/selftests/bpf/test_align.c +0
-15@@ -474,27 +474,7 @@ static struct bpf_align_test tests[] = { .result = REJECT, .matches = { {4, "R5=pkt(id=0,off=0,r=0,imm=0)"}, -/* ptr & 0x40 == either 0 or 0x40 */ - {5, "R5=inv(id=0,umax_value=64,var_off=(0x0; 0x40))"}, -/* ptr << 2 == unknown, (4n) */ - {7, "R5=inv(id=0,smax_value=9223372036854775804,umax_value=18446744073709551612,var_off=(0x0; 0xfffffffffffffffc))"}, -/* (4n) + 14 == (4n+2). We blow our bounds, because -* the add could overflow. -*/ - {8, "R5=inv(id=0,var_off=(0x2; 0xfffffffffffffffc))"}, -/* Checked s>=0 */ - {10, "R5=inv(id=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc))"}, -/* packet pointer + nonnegative (4n+2) */ - {12, "R6=pkt(id=1,off=0,r=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc))"}, - {14, "R4=pkt(id=1,off=4,r=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc))"}, -/* NET_IP_ALIGN + (4n+2) == (4n), alignment is fine. -* We checked the bounds, but it might have been able
tools/testing/selftests/bpf/test_align.c static struct bpf_align_test tests[] = { · line 480
Quoted 10 lines
tools/testing/selftests/bpf/test_align.c +1
-6-* to overflow if the packet pointer started in the -* upper half of the address space. -* So we did not get a 'range' on R6, and the access -* attempt will fail. -*/ - {16, "R6=pkt(id=1,off=0,r=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc))"}, +/* R5 bitwise operator &= on pointer prohibited */ } }, {
Rather than neutering this test, we should change it to keep the part where it tests that a large pkt_ptr offset prevents us getting a reg->range. Specifically, in this test we have
r2 = pkt
r5 = large unknown scalar
r6 = r2 + r5
r4 = r6 + 4
Then we check r4 < pkt_end, which normally would give r6->range = 4, but in this case must not do so since r6 could be (u64)(-2) in which case r4 = 2 < pkt_end despite r6 not pointing into the packet.
AFAICT there is not other coverage of this case in test_align, and I don't recall such a test being in test_verifier either. So please instead replace the insns that do prohibited ops on pointers with some other way of creating a large unknown scalar, and keep the rest of the test case intact.
-Ed
Quoted 52 lines · Edward Cree
Quoted 35 lines · Alexei Starovoitov
since commit
82abbf8d2fc4the verifier rejects the bit-wise arithmetic on pointers earlier.
The test 'dubious pointer arithmetic' now has less output to match on. Adjust it.Fixes 82abbf8d2fc4 ("bpf: do not allow root to mangle valid pointers")Reported-by kernel test robot <[email protected]>Signed-off-by Alexei Starovoitov <[email protected]>--- tools/testing/selftests/bpf/test_align.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-)tools/testing/selftests/bpf/test_align.c +0
-15@@ -474,27 +474,7 @@ static struct bpf_align_test tests[] = { .result = REJECT, .matches = { {4, "R5=pkt(id=0,off=0,r=0,imm=0)"}, -/* ptr & 0x40 == either 0 or 0x40 */ - {5, "R5=inv(id=0,umax_value=64,var_off=(0x0; 0x40))"}, -/* ptr << 2 == unknown, (4n) */ - {7, "R5=inv(id=0,smax_value=9223372036854775804,umax_value=18446744073709551612,var_off=(0x0; 0xfffffffffffffffc))"}, -/* (4n) + 14 == (4n+2). We blow our bounds, because -* the add could overflow. -*/ - {8, "R5=inv(id=0,var_off=(0x2; 0xfffffffffffffffc))"}, -/* Checked s>=0 */ - {10, "R5=inv(id=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc))"}, -/* packet pointer + nonnegative (4n+2) */ - {12, "R6=pkt(id=1,off=0,r=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc))"}, - {14, "R4=pkt(id=1,off=4,r=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc))"}, -/* NET_IP_ALIGN + (4n+2) == (4n), alignment is fine. -* We checked the bounds, but it might have been able tools/testing/selftests/bpf/test_align.c static struct bpf_align_test tests[] = { · line 480
Quoted 10 lines
tools/testing/selftests/bpf/test_align.c +1
-6-* to overflow if the packet pointer started in the -* upper half of the address space. -* So we did not get a 'range' on R6, and the access -* attempt will fail. -*/ - {16, "R6=pkt(id=1,off=0,r=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc))"}, +/* R5 bitwise operator &= on pointer prohibited */ } }, {Rather than neutering this test, we should change it to keep the part where
it tests that a largepkt_ptroffset prevents us getting areg->range.
Specifically, in this test we have
r2 = pkt
r5 = large unknown scalar
r6 = r2 + r5
Quoted 8 lines
r4 = r6 + 4
Then we check r4 <pkt_end, which normally would giver6->range= 4, but in
this case must not do so since r6 could be (u64)(-2) in which case r4 = 2 <pkt_enddespite r6 not pointing into the packet.
AFAICT there is not other coverage of this case intest_align, and I don't
recall such a test being intest_verifiereither. So please instead replace the insns that do prohibited ops on pointers with some other way of creating a large unknown scalar, and keep the rest of the test case intact.
makes sense. will send a follow up patch when security dust settles.