bpf: add couple of test cases for signed extended imms
authorDaniel Borkmann <daniel@iogearbox.net>
Sat, 20 Jan 2018 00:24:31 +0000 (01:24 +0100)
committerAlexei Starovoitov <ast@kernel.org>
Sat, 20 Jan 2018 02:36:59 +0000 (18:36 -0800)
Add a couple of test cases for interpreter and JIT that are
related to an issue we faced some time ago in Cilium [1],
which is fixed in LLVM with commit e53750e1e086 ("bpf: fix
bug on silently truncating 64-bit immediate").

Test cases were run-time checking kernel to behave as intended
which should also provide some guidance for current or new
JITs in case they should trip over this. Added for cBPF and
eBPF.

  [1] https://github.com/cilium/cilium/pull/2162

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
lib/test_bpf.c

index f369889e521d7e7f1e237236651532e6a862e0f5..e3938e395cbac021309f22d8dd47bfa8a5f330fc 100644 (file)
@@ -6109,6 +6109,110 @@ static struct bpf_test tests[] = {
                { { ETH_HLEN, 42 } },
                .fill_helper = bpf_fill_ld_abs_vlan_push_pop2,
        },
+       /* Checking interpreter vs JIT wrt signed extended imms. */
+       {
+               "JNE signed compare, test 1",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R1, 0xfefbbc12),
+                       BPF_ALU32_IMM(BPF_MOV, R3, 0xffff0000),
+                       BPF_MOV64_REG(R2, R1),
+                       BPF_ALU64_REG(BPF_AND, R2, R3),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 1),
+                       BPF_JMP_IMM(BPF_JNE, R2, -17104896, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 2),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 1 } },
+       },
+       {
+               "JNE signed compare, test 2",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R1, 0xfefbbc12),
+                       BPF_ALU32_IMM(BPF_MOV, R3, 0xffff0000),
+                       BPF_MOV64_REG(R2, R1),
+                       BPF_ALU64_REG(BPF_AND, R2, R3),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 1),
+                       BPF_JMP_IMM(BPF_JNE, R2, 0xfefb0000, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 2),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 1 } },
+       },
+       {
+               "JNE signed compare, test 3",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R1, 0xfefbbc12),
+                       BPF_ALU32_IMM(BPF_MOV, R3, 0xffff0000),
+                       BPF_ALU32_IMM(BPF_MOV, R4, 0xfefb0000),
+                       BPF_MOV64_REG(R2, R1),
+                       BPF_ALU64_REG(BPF_AND, R2, R3),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 1),
+                       BPF_JMP_REG(BPF_JNE, R2, R4, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 2),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 2 } },
+       },
+       {
+               "JNE signed compare, test 4",
+               .u.insns_int = {
+                       BPF_LD_IMM64(R1, -17104896),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 1),
+                       BPF_JMP_IMM(BPF_JNE, R1, -17104896, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 2),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 2 } },
+       },
+       {
+               "JNE signed compare, test 5",
+               .u.insns_int = {
+                       BPF_LD_IMM64(R1, 0xfefb0000),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 1),
+                       BPF_JMP_IMM(BPF_JNE, R1, 0xfefb0000, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 2),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 1 } },
+       },
+       {
+               "JNE signed compare, test 6",
+               .u.insns_int = {
+                       BPF_LD_IMM64(R1, 0x7efb0000),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 1),
+                       BPF_JMP_IMM(BPF_JNE, R1, 0x7efb0000, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 2),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 2 } },
+       },
+       {
+               "JNE signed compare, test 7",
+               .u.insns = {
+                       BPF_STMT(BPF_LD | BPF_IMM, 0xffff0000),
+                       BPF_STMT(BPF_MISC | BPF_TAX, 0),
+                       BPF_STMT(BPF_LD | BPF_IMM, 0xfefbbc12),
+                       BPF_STMT(BPF_ALU | BPF_AND | BPF_X, 0),
+                       BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0xfefb0000, 1, 0),
+                       BPF_STMT(BPF_RET | BPF_K, 1),
+                       BPF_STMT(BPF_RET | BPF_K, 2),
+               },
+               CLASSIC | FLAG_NO_DATA,
+               {},
+               { { 0, 2 } },
+       },
 };
 
 static struct net_device dev;