Use helper bpf_redirect_map() and bpf_redirect_map_multi() to test bpf
arg ARG_CONST_MAP_PTR and ARG_CONST_MAP_PTR_OR_NULL. Make sure the
map arg could be verified correctly when it is NULL or valid map
pointer.

Add devmap and devmap_hash in struct bpf_test due to bpf_redirect_{map,
map_multi} limit.

Test result:
 ]# ./test_verifier 702 705
 #702/p ARG_CONST_MAP_PTR: null pointer OK
 #703/p ARG_CONST_MAP_PTR: valid map pointer OK
 #704/p ARG_CONST_MAP_PTR_OR_NULL: null pointer for ex_map OK
 #705/p ARG_CONST_MAP_PTR_OR_NULL: valid map pointer for ex_map OK
 Summary: 4 PASSED, 0 SKIPPED, 0 FAILED

Signed-off-by: Hangbin Liu <liuhang...@gmail.com>
---

v2-v11: no update

---
 tools/testing/selftests/bpf/test_verifier.c   | 22 +++++-
 .../testing/selftests/bpf/verifier/map_ptr.c  | 70 +++++++++++++++++++
 2 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/bpf/test_verifier.c 
b/tools/testing/selftests/bpf/test_verifier.c
index 9be395d9dc64..f89a13e60692 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -50,7 +50,7 @@
 #define MAX_INSNS      BPF_MAXINSNS
 #define MAX_TEST_INSNS 1000000
 #define MAX_FIXUPS     8
-#define MAX_NR_MAPS    20
+#define MAX_NR_MAPS    22
 #define MAX_TEST_RUNS  8
 #define POINTER_VALUE  0xcafe4all
 #define TEST_DATA_LEN  64
@@ -87,6 +87,8 @@ struct bpf_test {
        int fixup_sk_storage_map[MAX_FIXUPS];
        int fixup_map_event_output[MAX_FIXUPS];
        int fixup_map_reuseport_array[MAX_FIXUPS];
+       int fixup_map_devmap[MAX_FIXUPS];
+       int fixup_map_devmap_hash[MAX_FIXUPS];
        const char *errstr;
        const char *errstr_unpriv;
        uint32_t insn_processed;
@@ -640,6 +642,8 @@ static void do_test_fixup(struct bpf_test *test, enum 
bpf_prog_type prog_type,
        int *fixup_sk_storage_map = test->fixup_sk_storage_map;
        int *fixup_map_event_output = test->fixup_map_event_output;
        int *fixup_map_reuseport_array = test->fixup_map_reuseport_array;
+       int *fixup_map_devmap = test->fixup_map_devmap;
+       int *fixup_map_devmap_hash = test->fixup_map_devmap_hash;
 
        if (test->fill_helper) {
                test->fill_insns = calloc(MAX_TEST_INSNS, sizeof(struct 
bpf_insn));
@@ -817,6 +821,22 @@ static void do_test_fixup(struct bpf_test *test, enum 
bpf_prog_type prog_type,
                        fixup_map_reuseport_array++;
                } while (*fixup_map_reuseport_array);
        }
+       if (*fixup_map_devmap) {
+               map_fds[20] = __create_map(BPF_MAP_TYPE_DEVMAP,
+                                          sizeof(u32), sizeof(u32), 1, 0);
+               do {
+                       prog[*fixup_map_devmap].imm = map_fds[20];
+                       fixup_map_devmap++;
+               } while (*fixup_map_devmap);
+       }
+       if (*fixup_map_devmap_hash) {
+               map_fds[21] = __create_map(BPF_MAP_TYPE_DEVMAP_HASH,
+                                          sizeof(u32), sizeof(u32), 1, 0);
+               do {
+                       prog[*fixup_map_devmap_hash].imm = map_fds[21];
+                       fixup_map_devmap_hash++;
+               } while (*fixup_map_devmap_hash);
+       }
 }
 
 struct libcap {
diff --git a/tools/testing/selftests/bpf/verifier/map_ptr.c 
b/tools/testing/selftests/bpf/verifier/map_ptr.c
index b52209db8250..51df7d8784dc 100644
--- a/tools/testing/selftests/bpf/verifier/map_ptr.c
+++ b/tools/testing/selftests/bpf/verifier/map_ptr.c
@@ -60,3 +60,73 @@
        .result = ACCEPT,
        .retval = 1,
 },
+{
+       "ARG_CONST_MAP_PTR: null pointer",
+       .insns = {
+               /* bpf_redirect_map arg1 (map) */
+               BPF_MOV64_IMM(BPF_REG_1, 0),
+               /* bpf_redirect_map arg2 (ifindex) */
+               BPF_MOV64_IMM(BPF_REG_2, 0),
+               /* bpf_redirect_map arg3 (flags) */
+               BPF_MOV64_IMM(BPF_REG_3, 0),
+               BPF_EMIT_CALL(BPF_FUNC_redirect_map),
+               BPF_EXIT_INSN(),
+       },
+       .result = REJECT,
+       .prog_type = BPF_PROG_TYPE_XDP,
+       .errstr = "R1 type=inv expected=map_ptr",
+},
+{
+       "ARG_CONST_MAP_PTR: valid map pointer",
+       .insns = {
+               BPF_MOV64_IMM(BPF_REG_1, 0),
+               /* bpf_redirect_map arg1 (map) */
+               BPF_LD_MAP_FD(BPF_REG_1, 0),
+               /* bpf_redirect_map arg2 (ifindex) */
+               BPF_MOV64_IMM(BPF_REG_2, 0),
+               /* bpf_redirect_map arg3 (flags) */
+               BPF_MOV64_IMM(BPF_REG_3, 0),
+               BPF_EMIT_CALL(BPF_FUNC_redirect_map),
+               BPF_EXIT_INSN(),
+       },
+       .fixup_map_devmap = { 1 },
+       .result = ACCEPT,
+       .prog_type = BPF_PROG_TYPE_XDP,
+},
+{
+       "ARG_CONST_MAP_PTR_OR_NULL: null pointer for ex_map",
+       .insns = {
+               BPF_MOV64_IMM(BPF_REG_1, 0),
+               /* bpf_redirect_map_multi arg1 (in_map) */
+               BPF_LD_MAP_FD(BPF_REG_1, 0),
+               /* bpf_redirect_map_multi arg2 (ex_map) */
+               BPF_MOV64_IMM(BPF_REG_2, 0),
+               /* bpf_redirect_map_multi arg3 (flags) */
+               BPF_MOV64_IMM(BPF_REG_3, 0),
+               BPF_EMIT_CALL(BPF_FUNC_redirect_map_multi),
+               BPF_EXIT_INSN(),
+       },
+       .fixup_map_devmap = { 1 },
+       .result = ACCEPT,
+       .prog_type = BPF_PROG_TYPE_XDP,
+       .retval = 4,
+},
+{
+       "ARG_CONST_MAP_PTR_OR_NULL: valid map pointer for ex_map",
+       .insns = {
+               BPF_MOV64_IMM(BPF_REG_1, 0),
+               /* bpf_redirect_map_multi arg1 (in_map) */
+               BPF_LD_MAP_FD(BPF_REG_1, 0),
+               /* bpf_redirect_map_multi arg2 (ex_map) */
+               BPF_LD_MAP_FD(BPF_REG_2, 1),
+               /* bpf_redirect_map_multi arg3 (flags) */
+               BPF_MOV64_IMM(BPF_REG_3, 0),
+               BPF_EMIT_CALL(BPF_FUNC_redirect_map_multi),
+               BPF_EXIT_INSN(),
+       },
+       .fixup_map_devmap = { 1 },
+       .fixup_map_devmap_hash = { 3 },
+       .result = ACCEPT,
+       .prog_type = BPF_PROG_TYPE_XDP,
+       .retval = 4,
+},
-- 
2.25.4

Reply via email to