Skip to contentSkip to conversation

selftests/bpf: fix test_align

PATCH In review Alexei Starovoitov 2 participants 3 messages Jan 5, 2018 – Jan 8, 2018

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

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.

Fixes 82abbf8d2fc4 ("bpf: do not allow root to mangle valid pointers")
---
 tools/testing/selftests/bpf/test_align.c | 22 +---------------------
 1 file changed, 1 insertion(+), 21 deletions(-)
tools/testing/selftests/bpf/test_align.c +1 -21
index 8591c89c0828..471bbbdb94db 100644
@@ -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
#1 lore raw
Quoted 35 lines · Alexei Starovoitov

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.

Fixes 82abbf8d2fc4 ("bpf: do not allow root to mangle valid pointers")
---
 tools/testing/selftests/bpf/test_align.c | 22 +---------------------
 1 file changed, 1 insertion(+), 21 deletions(-)
tools/testing/selftests/bpf/test_align.c +0 -15
index 8591c89c0828..471bbbdb94db 100644
@@ -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

#2 lore raw
Quoted 52 lines · Edward Cree
Quoted 35 lines · Alexei Starovoitov

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.

Fixes 82abbf8d2fc4 ("bpf: do not allow root to mangle valid pointers")
---
 tools/testing/selftests/bpf/test_align.c | 22 +---------------------
 1 file changed, 1 insertion(+), 21 deletions(-)
tools/testing/selftests/bpf/test_align.c +0 -15
index 8591c89c0828..471bbbdb94db 100644
@@ -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

Quoted 8 lines

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.

makes sense. will send a follow up patch when security dust settles.