Skip to content

Commit 41f70fe

Browse files
jrfastabAlexei Starovoitov
authored andcommitted
bpf: Test_verifier, add alu32 bounds tracking tests
Its possible to have divergent ALU32 and ALU64 bounds when using JMP32 instructins and ALU64 arithmatic operations. Sometimes the clang will even generate this code. Because the case is a bit tricky lets add a specific test for it. Here is pseudocode asm version to illustrate the idea, 1 r0 = 0xffffffff00000001; 2 if w0 > 1 goto %l[fail]; 3 r0 += 1 5 if w0 > 2 goto %l[fail] 6 exit The intent here is the verifier will fail the load if the 32bit bounds are not tracked correctly through ALU64 op. Similarly we can check the 64bit bounds are correctly zero extended after ALU32 ops. 1 r0 = 0xffffffff00000001; 2 w0 += 1 2 if r0 > 3 goto %l[fail]; 6 exit The above will fail if we do not correctly zero extend 64bit bounds after 32bit op. Signed-off-by: John Fastabend <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Link: https://lore.kernel.org/bpf/158560430155.10843.514209255758200922.stgit@john-Precision-5820-Tower
1 parent 32f13a5 commit 41f70fe

File tree

1 file changed

+39
-0
lines changed
  • tools/testing/selftests/bpf/verifier

1 file changed

+39
-0
lines changed

tools/testing/selftests/bpf/verifier/bounds.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,3 +500,42 @@
500500
.errstr = "map_value pointer and 1000000000000",
501501
.result = REJECT
502502
},
503+
{
504+
"bounds check mixed 32bit and 64bit arithmatic. test1",
505+
.insns = {
506+
BPF_MOV64_IMM(BPF_REG_0, 0),
507+
BPF_MOV64_IMM(BPF_REG_1, -1),
508+
BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 32),
509+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
510+
/* r1 = 0xffffFFFF00000001 */
511+
BPF_JMP32_IMM(BPF_JGT, BPF_REG_1, 1, 3),
512+
/* check ALU64 op keeps 32bit bounds */
513+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
514+
BPF_JMP32_IMM(BPF_JGT, BPF_REG_1, 2, 1),
515+
BPF_JMP_A(1),
516+
/* invalid ldx if bounds are lost above */
517+
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, -1),
518+
BPF_EXIT_INSN(),
519+
},
520+
.result = ACCEPT
521+
},
522+
{
523+
"bounds check mixed 32bit and 64bit arithmatic. test2",
524+
.insns = {
525+
BPF_MOV64_IMM(BPF_REG_0, 0),
526+
BPF_MOV64_IMM(BPF_REG_1, -1),
527+
BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 32),
528+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
529+
/* r1 = 0xffffFFFF00000001 */
530+
BPF_MOV64_IMM(BPF_REG_2, 3),
531+
/* r1 = 0x2 */
532+
BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 1),
533+
/* check ALU32 op zero extends 64bit bounds */
534+
BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 1),
535+
BPF_JMP_A(1),
536+
/* invalid ldx if bounds are lost above */
537+
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, -1),
538+
BPF_EXIT_INSN(),
539+
},
540+
.result = ACCEPT
541+
},

0 commit comments

Comments
 (0)