bpf, tests: Add BPF_JMP32 test cases
authorJohan Almbladh <johan.almbladh@anyfinetworks.com>
Mon, 9 Aug 2021 09:18:16 +0000 (11:18 +0200)
committerDaniel Borkmann <daniel@iogearbox.net>
Tue, 10 Aug 2021 09:32:45 +0000 (11:32 +0200)
An eBPF JIT may implement JMP32 operations in a different way than JMP,
especially on 32-bit architectures. This patch adds a series of tests
for JMP32 operations, mainly for testing JITs.

Signed-off-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/bpf/20210809091829.810076-2-johan.almbladh@anyfinetworks.com
lib/test_bpf.c

index f6d5d30d01bf2e4caf420dac029a474b520aeb7c..377e866764cbec6701558dc2ff33df926995b725 100644 (file)
@@ -4398,6 +4398,517 @@ static struct bpf_test tests[] = {
                { { 0, 4134 } },
                .fill_helper = bpf_fill_stxdw,
        },
+       /* BPF_JMP32 | BPF_JEQ | BPF_K */
+       {
+               "JMP32_JEQ_K: Small immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 123),
+                       BPF_JMP32_IMM(BPF_JEQ, R0, 321, 1),
+                       BPF_JMP32_IMM(BPF_JEQ, R0, 123, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 123 } }
+       },
+       {
+               "JMP32_JEQ_K: Large immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 12345678),
+                       BPF_JMP32_IMM(BPF_JEQ, R0, 12345678 & 0xffff, 1),
+                       BPF_JMP32_IMM(BPF_JEQ, R0, 12345678, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 12345678 } }
+       },
+       {
+               "JMP32_JEQ_K: negative immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, -123),
+                       BPF_JMP32_IMM(BPF_JEQ, R0,  123, 1),
+                       BPF_JMP32_IMM(BPF_JEQ, R0, -123, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, -123 } }
+       },
+       /* BPF_JMP32 | BPF_JEQ | BPF_X */
+       {
+               "JMP32_JEQ_X",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 1234),
+                       BPF_ALU32_IMM(BPF_MOV, R1, 4321),
+                       BPF_JMP32_REG(BPF_JEQ, R0, R1, 2),
+                       BPF_ALU32_IMM(BPF_MOV, R1, 1234),
+                       BPF_JMP32_REG(BPF_JEQ, R0, R1, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 1234 } }
+       },
+       /* BPF_JMP32 | BPF_JNE | BPF_K */
+       {
+               "JMP32_JNE_K: Small immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 123),
+                       BPF_JMP32_IMM(BPF_JNE, R0, 123, 1),
+                       BPF_JMP32_IMM(BPF_JNE, R0, 321, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 123 } }
+       },
+       {
+               "JMP32_JNE_K: Large immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 12345678),
+                       BPF_JMP32_IMM(BPF_JNE, R0, 12345678, 1),
+                       BPF_JMP32_IMM(BPF_JNE, R0, 12345678 & 0xffff, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 12345678 } }
+       },
+       {
+               "JMP32_JNE_K: negative immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, -123),
+                       BPF_JMP32_IMM(BPF_JNE, R0, -123, 1),
+                       BPF_JMP32_IMM(BPF_JNE, R0,  123, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, -123 } }
+       },
+       /* BPF_JMP32 | BPF_JNE | BPF_X */
+       {
+               "JMP32_JNE_X",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 1234),
+                       BPF_ALU32_IMM(BPF_MOV, R1, 1234),
+                       BPF_JMP32_REG(BPF_JNE, R0, R1, 2),
+                       BPF_ALU32_IMM(BPF_MOV, R1, 4321),
+                       BPF_JMP32_REG(BPF_JNE, R0, R1, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 1234 } }
+       },
+       /* BPF_JMP32 | BPF_JSET | BPF_K */
+       {
+               "JMP32_JSET_K: Small immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 1),
+                       BPF_JMP32_IMM(BPF_JSET, R0, 2, 1),
+                       BPF_JMP32_IMM(BPF_JSET, R0, 3, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 1 } }
+       },
+       {
+               "JMP32_JSET_K: Large immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0x40000000),
+                       BPF_JMP32_IMM(BPF_JSET, R0, 0x3fffffff, 1),
+                       BPF_JMP32_IMM(BPF_JSET, R0, 0x60000000, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 0x40000000 } }
+       },
+       {
+               "JMP32_JSET_K: negative immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, -123),
+                       BPF_JMP32_IMM(BPF_JSET, R0, -1, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, -123 } }
+       },
+       /* BPF_JMP32 | BPF_JSET | BPF_X */
+       {
+               "JMP32_JSET_X",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 8),
+                       BPF_ALU32_IMM(BPF_MOV, R1, 7),
+                       BPF_JMP32_REG(BPF_JSET, R0, R1, 2),
+                       BPF_ALU32_IMM(BPF_MOV, R1, 8 | 2),
+                       BPF_JMP32_REG(BPF_JNE, R0, R1, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 8 } }
+       },
+       /* BPF_JMP32 | BPF_JGT | BPF_K */
+       {
+               "JMP32_JGT_K: Small immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 123),
+                       BPF_JMP32_IMM(BPF_JGT, R0, 123, 1),
+                       BPF_JMP32_IMM(BPF_JGT, R0, 122, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 123 } }
+       },
+       {
+               "JMP32_JGT_K: Large immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0xfffffffe),
+                       BPF_JMP32_IMM(BPF_JGT, R0, 0xffffffff, 1),
+                       BPF_JMP32_IMM(BPF_JGT, R0, 0xfffffffd, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 0xfffffffe } }
+       },
+       /* BPF_JMP32 | BPF_JGT | BPF_X */
+       {
+               "JMP32_JGT_X",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0xfffffffe),
+                       BPF_ALU32_IMM(BPF_MOV, R1, 0xffffffff),
+                       BPF_JMP32_REG(BPF_JGT, R0, R1, 2),
+                       BPF_ALU32_IMM(BPF_MOV, R1, 0xfffffffd),
+                       BPF_JMP32_REG(BPF_JGT, R0, R1, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 0xfffffffe } }
+       },
+       /* BPF_JMP32 | BPF_JGE | BPF_K */
+       {
+               "JMP32_JGE_K: Small immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 123),
+                       BPF_JMP32_IMM(BPF_JGE, R0, 124, 1),
+                       BPF_JMP32_IMM(BPF_JGE, R0, 123, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 123 } }
+       },
+       {
+               "JMP32_JGE_K: Large immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0xfffffffe),
+                       BPF_JMP32_IMM(BPF_JGE, R0, 0xffffffff, 1),
+                       BPF_JMP32_IMM(BPF_JGE, R0, 0xfffffffe, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 0xfffffffe } }
+       },
+       /* BPF_JMP32 | BPF_JGE | BPF_X */
+       {
+               "JMP32_JGE_X",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0xfffffffe),
+                       BPF_ALU32_IMM(BPF_MOV, R1, 0xffffffff),
+                       BPF_JMP32_REG(BPF_JGE, R0, R1, 2),
+                       BPF_ALU32_IMM(BPF_MOV, R1, 0xfffffffe),
+                       BPF_JMP32_REG(BPF_JGE, R0, R1, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 0xfffffffe } }
+       },
+       /* BPF_JMP32 | BPF_JLT | BPF_K */
+       {
+               "JMP32_JLT_K: Small immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 123),
+                       BPF_JMP32_IMM(BPF_JLT, R0, 123, 1),
+                       BPF_JMP32_IMM(BPF_JLT, R0, 124, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 123 } }
+       },
+       {
+               "JMP32_JLT_K: Large immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0xfffffffe),
+                       BPF_JMP32_IMM(BPF_JLT, R0, 0xfffffffd, 1),
+                       BPF_JMP32_IMM(BPF_JLT, R0, 0xffffffff, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 0xfffffffe } }
+       },
+       /* BPF_JMP32 | BPF_JLT | BPF_X */
+       {
+               "JMP32_JLT_X",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0xfffffffe),
+                       BPF_ALU32_IMM(BPF_MOV, R1, 0xfffffffd),
+                       BPF_JMP32_REG(BPF_JLT, R0, R1, 2),
+                       BPF_ALU32_IMM(BPF_MOV, R1, 0xffffffff),
+                       BPF_JMP32_REG(BPF_JLT, R0, R1, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 0xfffffffe } }
+       },
+       /* BPF_JMP32 | BPF_JLE | BPF_K */
+       {
+               "JMP32_JLE_K: Small immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 123),
+                       BPF_JMP32_IMM(BPF_JLE, R0, 122, 1),
+                       BPF_JMP32_IMM(BPF_JLE, R0, 123, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 123 } }
+       },
+       {
+               "JMP32_JLE_K: Large immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0xfffffffe),
+                       BPF_JMP32_IMM(BPF_JLE, R0, 0xfffffffd, 1),
+                       BPF_JMP32_IMM(BPF_JLE, R0, 0xfffffffe, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 0xfffffffe } }
+       },
+       /* BPF_JMP32 | BPF_JLE | BPF_X */
+       {
+               "JMP32_JLE_X",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0xfffffffe),
+                       BPF_ALU32_IMM(BPF_MOV, R1, 0xfffffffd),
+                       BPF_JMP32_REG(BPF_JLE, R0, R1, 2),
+                       BPF_ALU32_IMM(BPF_MOV, R1, 0xfffffffe),
+                       BPF_JMP32_REG(BPF_JLE, R0, R1, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 0xfffffffe } }
+       },
+       /* BPF_JMP32 | BPF_JSGT | BPF_K */
+       {
+               "JMP32_JSGT_K: Small immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, -123),
+                       BPF_JMP32_IMM(BPF_JSGT, R0, -123, 1),
+                       BPF_JMP32_IMM(BPF_JSGT, R0, -124, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, -123 } }
+       },
+       {
+               "JMP32_JSGT_K: Large immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, -12345678),
+                       BPF_JMP32_IMM(BPF_JSGT, R0, -12345678, 1),
+                       BPF_JMP32_IMM(BPF_JSGT, R0, -12345679, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, -12345678 } }
+       },
+       /* BPF_JMP32 | BPF_JSGT | BPF_X */
+       {
+               "JMP32_JSGT_X",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, -12345678),
+                       BPF_ALU32_IMM(BPF_MOV, R1, -12345678),
+                       BPF_JMP32_REG(BPF_JSGT, R0, R1, 2),
+                       BPF_ALU32_IMM(BPF_MOV, R1, -12345679),
+                       BPF_JMP32_REG(BPF_JSGT, R0, R1, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, -12345678 } }
+       },
+       /* BPF_JMP32 | BPF_JSGE | BPF_K */
+       {
+               "JMP32_JSGE_K: Small immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, -123),
+                       BPF_JMP32_IMM(BPF_JSGE, R0, -122, 1),
+                       BPF_JMP32_IMM(BPF_JSGE, R0, -123, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, -123 } }
+       },
+       {
+               "JMP32_JSGE_K: Large immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, -12345678),
+                       BPF_JMP32_IMM(BPF_JSGE, R0, -12345677, 1),
+                       BPF_JMP32_IMM(BPF_JSGE, R0, -12345678, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, -12345678 } }
+       },
+       /* BPF_JMP32 | BPF_JSGE | BPF_X */
+       {
+               "JMP32_JSGE_X",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, -12345678),
+                       BPF_ALU32_IMM(BPF_MOV, R1, -12345677),
+                       BPF_JMP32_REG(BPF_JSGE, R0, R1, 2),
+                       BPF_ALU32_IMM(BPF_MOV, R1, -12345678),
+                       BPF_JMP32_REG(BPF_JSGE, R0, R1, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, -12345678 } }
+       },
+       /* BPF_JMP32 | BPF_JSLT | BPF_K */
+       {
+               "JMP32_JSLT_K: Small immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, -123),
+                       BPF_JMP32_IMM(BPF_JSLT, R0, -123, 1),
+                       BPF_JMP32_IMM(BPF_JSLT, R0, -122, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, -123 } }
+       },
+       {
+               "JMP32_JSLT_K: Large immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, -12345678),
+                       BPF_JMP32_IMM(BPF_JSLT, R0, -12345678, 1),
+                       BPF_JMP32_IMM(BPF_JSLT, R0, -12345677, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, -12345678 } }
+       },
+       /* BPF_JMP32 | BPF_JSLT | BPF_X */
+       {
+               "JMP32_JSLT_X",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, -12345678),
+                       BPF_ALU32_IMM(BPF_MOV, R1, -12345678),
+                       BPF_JMP32_REG(BPF_JSLT, R0, R1, 2),
+                       BPF_ALU32_IMM(BPF_MOV, R1, -12345677),
+                       BPF_JMP32_REG(BPF_JSLT, R0, R1, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, -12345678 } }
+       },
+       /* BPF_JMP32 | BPF_JSLE | BPF_K */
+       {
+               "JMP32_JSLE_K: Small immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, -123),
+                       BPF_JMP32_IMM(BPF_JSLE, R0, -124, 1),
+                       BPF_JMP32_IMM(BPF_JSLE, R0, -123, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, -123 } }
+       },
+       {
+               "JMP32_JSLE_K: Large immediate",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, -12345678),
+                       BPF_JMP32_IMM(BPF_JSLE, R0, -12345679, 1),
+                       BPF_JMP32_IMM(BPF_JSLE, R0, -12345678, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, -12345678 } }
+       },
+       /* BPF_JMP32 | BPF_JSLE | BPF_K */
+       {
+               "JMP32_JSLE_X",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, -12345678),
+                       BPF_ALU32_IMM(BPF_MOV, R1, -12345679),
+                       BPF_JMP32_REG(BPF_JSLE, R0, R1, 2),
+                       BPF_ALU32_IMM(BPF_MOV, R1, -12345678),
+                       BPF_JMP32_REG(BPF_JSLE, R0, R1, 1),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, -12345678 } }
+       },
        /* BPF_JMP | BPF_EXIT */
        {
                "JMP_EXIT",