This patch adds some unit testcases.

There are a couple of code paths inside verifier doing register read/write
marking, therefore are the places that could trigger zero extension
insertion logic. Create one test for each of them.

A couple of testcases for complex CFG also included. They cover register
read propagation during path pruning etc.

Signed-off-by: Jiong Wang <jiong.w...@netronome.com>
---
 tools/testing/selftests/bpf/verifier/zext.c | 651 ++++++++++++++++++++++++++++
 1 file changed, 651 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/verifier/zext.c

diff --git a/tools/testing/selftests/bpf/verifier/zext.c 
b/tools/testing/selftests/bpf/verifier/zext.c
new file mode 100644
index 0000000..b45a429
--- /dev/null
+++ b/tools/testing/selftests/bpf/verifier/zext.c
@@ -0,0 +1,651 @@
+/* There are a couple of code paths inside verifier doing register
+ * read/write marking. Create one test for each.
+ */
+{
+       "zext: basic 1",
+       .insns = {
+       BPF_LD_IMM64(BPF_REG_0, 0x100000000ULL),
+       BPF_MOV32_IMM(BPF_REG_0, 0),
+       BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
+       BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       BPF_LD_IMM64(BPF_REG_0, 0x100000000ULL),
+       BPF_MOV32_IMM(BPF_REG_0, 0),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_0, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
+       BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+       BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+       .retval = 0,
+},
+{
+       "zext: basic 2",
+       .insns = {
+       BPF_LD_IMM64(BPF_REG_0, 0x100000001ULL),
+       BPF_MOV32_IMM(BPF_REG_0, 1),
+       BPF_ALU64_IMM(BPF_NEG, BPF_REG_0, 0),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       BPF_LD_IMM64(BPF_REG_0, 0x100000001ULL),
+       BPF_MOV32_IMM(BPF_REG_0, 1),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_0, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_ALU64_IMM(BPF_NEG, BPF_REG_0, 0),
+       BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+       .retval = -1,
+},
+{
+       "zext: basic 3",
+       .insns = {
+       BPF_LD_IMM64(BPF_REG_0, 0x100000000ULL),
+       BPF_MOV32_IMM(BPF_REG_0, 0),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       BPF_LD_IMM64(BPF_REG_0, 0x100000000ULL),
+       BPF_MOV32_IMM(BPF_REG_0, 0),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_0, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+       .retval = 0,
+},
+{
+       "zext: basic 4",
+       .insns = {
+       BPF_LD_IMM64(BPF_REG_1, 0x300000001ULL),
+       BPF_MOV32_IMM(BPF_REG_1, 1),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 32),
+       BPF_MOV32_IMM(BPF_REG_2, 2),
+       BPF_JMP_REG(BPF_JSLE, BPF_REG_1, BPF_REG_2, 2),
+       BPF_MOV64_IMM(BPF_REG_0, 3),
+       BPF_EXIT_INSN(),
+       BPF_MOV32_IMM(BPF_REG_0, 4),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       BPF_LD_IMM64(BPF_REG_1, 0x300000001ULL),
+       BPF_MOV32_IMM(BPF_REG_1, 1),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 32),
+       BPF_MOV32_IMM(BPF_REG_2, 2),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
+       BPF_JMP_REG(BPF_JSLE, BPF_REG_1, BPF_REG_2, 2),
+       BPF_MOV64_IMM(BPF_REG_0, 3),
+       BPF_EXIT_INSN(),
+       BPF_MOV32_IMM(BPF_REG_0, 4),
+       BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+       .retval = 4,
+},
+{
+       "zext: basic 5",
+       .insns = {
+       BPF_LD_IMM64(BPF_REG_1, 0x100000001ULL),
+       BPF_MOV32_IMM(BPF_REG_1, 0),
+       BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
+       BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       BPF_LD_IMM64(BPF_REG_1, 0x100000001ULL),
+       BPF_MOV32_IMM(BPF_REG_1, 0),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 32),
+       BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
+       BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+       .retval = 0,
+},
+{
+       "zext: basic 6",
+       .insns = {
+       BPF_LD_IMM64(BPF_REG_0, 0x100000000ULL),
+       BPF_MOV32_IMM(BPF_REG_0, 0),
+       BPF_MOV32_IMM(BPF_REG_1, 1),
+       BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       BPF_LD_IMM64(BPF_REG_0, 0x100000000ULL),
+       BPF_MOV32_IMM(BPF_REG_0, 0),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_0, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_MOV32_IMM(BPF_REG_1, 1),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 32),
+       BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+       BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+       .retval = 1,
+},
+{
+       "zext: ret from main",
+       .insns = {
+       BPF_LD_IMM64(BPF_REG_0, 0x100000001ULL),
+       BPF_MOV32_IMM(BPF_REG_0, 1),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       BPF_LD_IMM64(BPF_REG_0, 0x100000001ULL),
+       BPF_MOV32_IMM(BPF_REG_0, 1),
+       BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+       .retval = 1,
+},
+{
+       "zext: ret from helper",
+       .insns = {
+       BPF_MOV32_IMM(BPF_REG_0, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
+       BPF_MOV64_IMM(BPF_REG_8, BPF_REG_0),
+       BPF_MOV32_IMM(BPF_REG_0, 0),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       /* Shouldn't do zext. */
+       BPF_MOV32_IMM(BPF_REG_0, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
+       BPF_MOV64_IMM(BPF_REG_8, BPF_REG_0),
+       BPF_MOV32_IMM(BPF_REG_0, 0),
+       BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+       .retval = 0,
+},
+{
+       "zext: xadd",
+       .insns = {
+       BPF_LD_IMM64(BPF_REG_0, 0x100000001ULL),
+       BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
+       BPF_MOV32_IMM(BPF_REG_0, 1),
+       BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
+       BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       BPF_LD_IMM64(BPF_REG_0, 0x100000001ULL),
+       BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
+       BPF_MOV32_IMM(BPF_REG_0, 1),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_0, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
+       BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+       .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+       .retval = 1,
+},
+{
+       "zext: ld_abs ind",
+       .insns = {
+       BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
+       BPF_LD_IMM64(BPF_REG_8, 0x100000000ULL),
+       BPF_MOV32_IMM(BPF_REG_8, 2),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_8, 32),
+       BPF_LD_IND(BPF_B, BPF_REG_8, 0),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
+       BPF_LD_IMM64(BPF_REG_8, 0x100000000ULL),
+       BPF_MOV32_IMM(BPF_REG_8, 2),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_8, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_8, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_8, 32),
+       },
+       .data = {
+               10, 20, 30, 40, 50,
+       },
+       .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+       .result = ACCEPT,
+       .retval = 10,
+},
+{
+       "zext: multi paths, all 32-bit use",
+       .insns = {
+       BPF_MOV32_IMM(BPF_REG_8, 2),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
+       BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 2),
+       BPF_MOV32_REG(BPF_REG_0, BPF_REG_8),
+       BPF_EXIT_INSN(),
+       BPF_MOV32_REG(BPF_REG_7, BPF_REG_8),
+       BPF_MOV32_REG(BPF_REG_0, BPF_REG_7),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       BPF_MOV32_IMM(BPF_REG_8, 2),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
+       BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 2),
+       BPF_MOV32_REG(BPF_REG_0, BPF_REG_8),
+       BPF_EXIT_INSN(),
+       BPF_MOV32_REG(BPF_REG_7, BPF_REG_8),
+       BPF_MOV32_REG(BPF_REG_0, BPF_REG_7),
+       BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+       .retval = 2,
+},
+{
+       "zext: multi paths, partial 64-bit use",
+       .insns = {
+       BPF_LD_IMM64(BPF_REG_8, 0x100000001ULL),
+       BPF_MOV32_IMM(BPF_REG_8, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
+       BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 2),
+       BPF_MOV32_REG(BPF_REG_0, BPF_REG_8),
+       BPF_EXIT_INSN(),
+       BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       BPF_LD_IMM64(BPF_REG_8, 0x100000001ULL),
+       BPF_MOV32_IMM(BPF_REG_8, 0),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_8, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_8, 32),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
+       BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 2),
+       BPF_MOV32_REG(BPF_REG_0, BPF_REG_8),
+       BPF_EXIT_INSN(),
+       BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+       .retval = 0,
+},
+{
+       "zext: multi paths, 32-bit def override",
+       .insns = {
+       BPF_MOV32_IMM(BPF_REG_8, 2),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
+       BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 3),
+       BPF_MOV32_IMM(BPF_REG_8, 2),
+       BPF_MOV32_REG(BPF_REG_0, BPF_REG_8),
+       BPF_EXIT_INSN(),
+       BPF_MOV32_IMM(BPF_REG_8, 2),
+       BPF_MOV64_REG(BPF_REG_7, BPF_REG_8),
+       BPF_MOV32_REG(BPF_REG_0, BPF_REG_7),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       BPF_MOV32_IMM(BPF_REG_8, 2),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
+       BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 3),
+       BPF_MOV32_IMM(BPF_REG_8, 2),
+       BPF_MOV32_REG(BPF_REG_0, BPF_REG_8),
+       BPF_EXIT_INSN(),
+       BPF_MOV32_IMM(BPF_REG_8, 2),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_8, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_8, 32),
+       BPF_MOV64_REG(BPF_REG_7, BPF_REG_8),
+       BPF_MOV32_REG(BPF_REG_0, BPF_REG_7),
+       BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+       .retval = 2,
+},
+{
+       /* Diamond CFG
+        *
+        *          -----
+        *         | BB0 |
+        *          -----
+        *           /\
+        *          /  \
+        *         /    \
+        *      -----     -----
+        *     | BB1 |   | BB2 | u32 def
+        *      -----     -----
+        *         \     /
+        *          \   / -> pruned, but u64 read should propagate backward
+        *           \ /
+        *          -----
+        *         | BB3 | u64 read
+        *          -----
+        */
+       "zext: complex cfg 1",
+       .insns = {
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
+       BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 2),
+       /* BB1 */
+       BPF_MOV64_IMM(BPF_REG_8, 2),
+       BPF_JMP_IMM(BPF_JA, 0, 0, 2),
+       /* BB2 */
+       BPF_MOV32_IMM(BPF_REG_8, 2),
+       BPF_JMP_IMM(BPF_JA, 0, 0, 0),
+       /* BB3, 64-bit R8 read should be prop backward. */
+       BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
+       BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 2),
+       /* BB1 */
+       BPF_MOV64_IMM(BPF_REG_8, 2),
+       BPF_JMP_IMM(BPF_JA, 0, 0, 3),
+       /* BB2 */
+       BPF_MOV32_IMM(BPF_REG_8, 2),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_8, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_8, 32),
+       /* BB3 */
+       BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+       .retval = 0,
+},
+{
+       /* Diamond CFG
+        *
+        *          -----
+        *         | BB0 | u32 def
+        *          -----
+        *           /\
+        *          /  \
+        *         /    \
+        *      -----     -----
+        *     | BB1 |   | BB2 | u32 def
+        *      -----     -----
+        *         \     /
+        *          \   / -> pruned, but u64 read should propagate backward
+        *           \ /
+        *          -----
+        *         | BB3 | u64 read
+        *          -----
+        */
+       "zext: complex cfg 2",
+       .insns = {
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
+       BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
+       BPF_MOV32_IMM(BPF_REG_6, 2),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 2),
+       /* BB1 */
+       BPF_MOV64_IMM(BPF_REG_8, 2),
+       BPF_JMP_IMM(BPF_JA, 0, 0, 2),
+       /* BB2 */
+       BPF_MOV32_IMM(BPF_REG_8, 2),
+       BPF_JMP_IMM(BPF_JA, 0, 0, 0),
+       /* BB3, 64-bit R8 read should be prop backward. */
+       BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
+       BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
+       BPF_MOV32_IMM(BPF_REG_6, 2),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_6, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_6, 32),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 2),
+       /* BB1 */
+       BPF_MOV64_IMM(BPF_REG_8, 2),
+       BPF_JMP_IMM(BPF_JA, 0, 0, 3),
+       /* BB2 */
+       BPF_MOV32_IMM(BPF_REG_8, 2),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_8, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_8, 32),
+       /* BB3 */
+       BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
+       BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+       .retval = 2,
+},
+{
+       /* Diamond CFG
+        *
+        *                 -----
+        *                | BB0 | u32 def A
+        *                 -----
+        *                  /\
+        *                 /  \
+        *                /    \
+        *             -----    -----
+        *  u64 def A | BB1 |  | BB2 | u32 def B
+        *             -----    -----
+        *                 \     /
+        *                  \   /
+        *                   \ /
+        *                  -----
+        *                 | BB3 | u64 read A and B
+        *                  -----
+        */
+       "zext: complex cfg 3",
+       .insns = {
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
+       BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
+       BPF_MOV32_IMM(BPF_REG_6, 2),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 3),
+       /* BB1 */
+       BPF_MOV64_IMM(BPF_REG_8, 2),
+       BPF_MOV64_IMM(BPF_REG_6, 2),
+       BPF_JMP_IMM(BPF_JA, 0, 0, 2),
+       /* BB2 */
+       BPF_MOV32_IMM(BPF_REG_8, 2),
+       BPF_JMP_IMM(BPF_JA, 0, 0, 0),
+       /* BB3, 64-bit R8 read should be prop backward. */
+       BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
+       BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
+       BPF_MOV32_IMM(BPF_REG_6, 2),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_6, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_6, 32),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 3),
+       /* BB1 */
+       BPF_MOV64_IMM(BPF_REG_8, 2),
+       BPF_MOV64_IMM(BPF_REG_6, 2),
+       BPF_JMP_IMM(BPF_JA, 0, 0, 3),
+       /* BB2 */
+       BPF_MOV32_IMM(BPF_REG_8, 2),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_8, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_8, 32),
+       /* BB3 */
+       BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
+       BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+       .retval = 2,
+},
+{
+       /* Diamond CFG
+        *
+        *                 -----
+        *                | BB0 | u32 def A
+        *                 -----
+        *                  /\
+        *                 /  \
+        *                /    \
+        *             -----    -----
+        *  u64 def A | BB1 |  | BB2 | u64 def A and u32 def B
+        *             -----    -----
+        *                 \     /
+        *                  \   /
+        *                   \ /
+        *                  -----
+        *                 | BB3 | u64 read A and B
+        *                  -----
+        */
+       "zext: complex cfg 4",
+       .insns = {
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
+       BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
+       BPF_MOV32_IMM(BPF_REG_6, 2),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 3),
+       /* BB1 */
+       BPF_MOV64_IMM(BPF_REG_8, 2),
+       BPF_MOV64_IMM(BPF_REG_6, 3),
+       BPF_JMP_IMM(BPF_JA, 0, 0, 3),
+       /* BB2 */
+       BPF_MOV32_IMM(BPF_REG_8, 2),
+       BPF_MOV64_IMM(BPF_REG_6, 3),
+       BPF_JMP_IMM(BPF_JA, 0, 0, 0),
+       /* BB3, 64-bit R8 read should be prop backward. */
+       BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
+       BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
+       BPF_MOV32_IMM(BPF_REG_6, 2),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 3),
+       /* BB1 */
+       BPF_MOV64_IMM(BPF_REG_8, 2),
+       BPF_MOV64_IMM(BPF_REG_6, 3),
+       BPF_JMP_IMM(BPF_JA, 0, 0, 4),
+       /* BB2 */
+       BPF_MOV32_IMM(BPF_REG_8, 2),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_8, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_8, 32),
+       BPF_MOV64_IMM(BPF_REG_6, 3),
+       /* BB3 */
+       BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
+       BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+       .retval = 3,
+},
+{
+       "zext: callee-saved",
+       .insns = {
+       BPF_MOV32_IMM(BPF_REG_6, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
+       BPF_MOV64_REG(BPF_REG_0, BPF_REG_6),
+       BPF_EXIT_INSN(),
+       /* callee */
+       BPF_MOV32_IMM(BPF_REG_6, 1),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       /* caller u32 def should be zero extended. */
+       BPF_MOV32_IMM(BPF_REG_6, 0),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_6, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_6, 32),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
+       /* u64 use. */
+       BPF_MOV64_REG(BPF_REG_0, BPF_REG_6),
+       BPF_EXIT_INSN(),
+       /* callee u32 def shouldn't be affected. */
+       BPF_MOV32_IMM(BPF_REG_6, 1),
+       BPF_EXIT_INSN(),
+       },
+       .errstr_unpriv = "function calls to other bpf functions are allowed for 
root only",
+       .result_unpriv = REJECT,
+       .result = ACCEPT,
+       .retval = 0,
+},
+{
+       "zext: arg regs",
+       .insns = {
+       BPF_MOV32_IMM(BPF_REG_1, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
+       BPF_MOV64_IMM(BPF_REG_0, 0),
+       BPF_EXIT_INSN(),
+       /* callee */
+       BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       /* caller u32 def should be zero extended. */
+       BPF_MOV32_IMM(BPF_REG_1, 0),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 32),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
+       /* u64 use. */
+       BPF_MOV64_IMM(BPF_REG_0, 0),
+       BPF_EXIT_INSN(),
+       /* callee u64 use on caller-saved reg. */
+       BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
+       BPF_EXIT_INSN(),
+       },
+       .errstr_unpriv = "function calls to other bpf functions are allowed for 
root only",
+       .result_unpriv = REJECT,
+       .result = ACCEPT,
+       .retval = 0,
+},
+{
+       "zext: return arg",
+       .insns = {
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
+       BPF_ALU32_IMM(BPF_ADD, BPF_REG_0, 1),
+       BPF_MOV32_REG(BPF_REG_6, BPF_REG_0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
+       BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
+       BPF_EXIT_INSN(),
+       /* callee 1 */
+       BPF_MOV32_IMM(BPF_REG_0, 1),
+       BPF_EXIT_INSN(),
+       /* callee 2 */
+       BPF_MOV32_IMM(BPF_REG_0, 1),
+       BPF_EXIT_INSN(),
+       },
+       .xlated_insns = {
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 7),
+       BPF_ALU32_IMM(BPF_ADD, BPF_REG_0, 1),
+       BPF_MOV32_REG(BPF_REG_6, BPF_REG_0),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_6, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_6, 32),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
+       BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
+       BPF_EXIT_INSN(),
+       /* callee 1 */
+       BPF_MOV32_IMM(BPF_REG_0, 1),
+       BPF_EXIT_INSN(),
+       /* callee 2 */
+       BPF_MOV32_IMM(BPF_REG_0, 1),
+       BPF_ALU64_IMM(BPF_LSH, BPF_REG_0, 32),
+       BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32),
+       BPF_EXIT_INSN(),
+       },
+       .errstr_unpriv = "function calls to other bpf functions are allowed for 
root only",
+       .result_unpriv = REJECT,
+       .result = ACCEPT,
+       .retval = 3,
+},
-- 
2.7.4

Reply via email to