Add the following verifier tests to cover the cgroup storage
functionality:
1) valid access to the cgroup storage
2) invalid access: use regular hashmap instead of cgroup storage map
3) invalid access: use invalid map fd
4) invalid access: try access memory after the cgroup storage
5) invalid access: try access memory before the cgroup storage
6) invalid access: call get_local_storage() with non-zero flags

For tests 2)-6) check returned error strings.

Expected output:
  $ ./test_verifier
  #0/u add+sub+mul OK
  #0/p add+sub+mul OK
  #1/u DIV32 by 0, zero check 1 OK
  ...
  #280/p valid cgroup storage access OK
  #281/p invalid cgroup storage access 1 OK
  #282/p invalid cgroup storage access 2 OK
  #283/p invalid per-cgroup storage access 3 OK
  #284/p invalid cgroup storage access 4 OK
  #285/p invalid cgroup storage access 5 OK
  ...
  #649/p pass modified ctx pointer to helper, 2 OK
  #650/p pass modified ctx pointer to helper, 3 OK
  Summary: 901 PASSED, 0 SKIPPED, 0 FAILED

Signed-off-by: Roman Gushchin <g...@fb.com>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Acked-by: Martin KaFai Lau <ka...@fb.com>
---
 tools/testing/selftests/bpf/bpf_helpers.h   |   2 +
 tools/testing/selftests/bpf/test_verifier.c | 123 +++++++++++++++++++++++++++-
 2 files changed, 124 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/bpf/bpf_helpers.h 
b/tools/testing/selftests/bpf/bpf_helpers.h
index f2f28b6c8915..ccd959fd940e 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -133,6 +133,8 @@ static int (*bpf_rc_keydown)(void *ctx, unsigned int 
protocol,
        (void *) BPF_FUNC_rc_keydown;
 static unsigned long long (*bpf_get_current_cgroup_id)(void) =
        (void *) BPF_FUNC_get_current_cgroup_id;
+static void *(*bpf_get_local_storage)(void *map, unsigned long long flags) =
+       (void *) BPF_FUNC_get_local_storage;
 
 /* llvm builtin functions that eBPF C program may use to
  * emit BPF_LD_ABS and BPF_LD_IND instructions
diff --git a/tools/testing/selftests/bpf/test_verifier.c 
b/tools/testing/selftests/bpf/test_verifier.c
index 2ecd27b670d7..7016fb2964a1 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_FIXUPS     8
-#define MAX_NR_MAPS    7
+#define MAX_NR_MAPS    8
 #define POINTER_VALUE  0xcafe4all
 #define TEST_DATA_LEN  64
 
@@ -70,6 +70,7 @@ struct bpf_test {
        int fixup_prog1[MAX_FIXUPS];
        int fixup_prog2[MAX_FIXUPS];
        int fixup_map_in_map[MAX_FIXUPS];
+       int fixup_cgroup_storage[MAX_FIXUPS];
        const char *errstr;
        const char *errstr_unpriv;
        uint32_t retval;
@@ -4630,6 +4631,104 @@ static struct bpf_test tests[] = {
                .result = REJECT,
                .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
        },
+       {
+               "valid cgroup storage access",
+               .insns = {
+                       BPF_MOV64_IMM(BPF_REG_2, 0),
+                       BPF_LD_MAP_FD(BPF_REG_1, 0),
+                       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+                                    BPF_FUNC_get_local_storage),
+                       BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
+                       BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
+                       BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
+                       BPF_EXIT_INSN(),
+               },
+               .fixup_cgroup_storage = { 1 },
+               .result = ACCEPT,
+               .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
+       },
+       {
+               "invalid cgroup storage access 1",
+               .insns = {
+                       BPF_MOV64_IMM(BPF_REG_2, 0),
+                       BPF_LD_MAP_FD(BPF_REG_1, 0),
+                       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+                                    BPF_FUNC_get_local_storage),
+                       BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
+                       BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
+                       BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
+                       BPF_EXIT_INSN(),
+               },
+               .fixup_map1 = { 1 },
+               .result = REJECT,
+               .errstr = "cannot pass map_type 1 into func 
bpf_get_local_storage",
+               .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
+       },
+       {
+               "invalid cgroup storage access 2",
+               .insns = {
+                       BPF_MOV64_IMM(BPF_REG_2, 0),
+                       BPF_LD_MAP_FD(BPF_REG_1, 1),
+                       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+                                    BPF_FUNC_get_local_storage),
+                       BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
+                       BPF_EXIT_INSN(),
+               },
+               .result = REJECT,
+               .errstr = "fd 1 is not pointing to valid bpf_map",
+               .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
+       },
+       {
+               "invalid per-cgroup storage access 3",
+               .insns = {
+                       BPF_MOV64_IMM(BPF_REG_2, 0),
+                       BPF_LD_MAP_FD(BPF_REG_1, 0),
+                       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+                                    BPF_FUNC_get_local_storage),
+                       BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 256),
+                       BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
+                       BPF_MOV64_IMM(BPF_REG_0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               .fixup_cgroup_storage = { 1 },
+               .result = REJECT,
+               .errstr = "invalid access to map value, value_size=64 off=256 
size=4",
+               .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
+       },
+       {
+               "invalid cgroup storage access 4",
+               .insns = {
+                       BPF_MOV64_IMM(BPF_REG_2, 0),
+                       BPF_LD_MAP_FD(BPF_REG_1, 0),
+                       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+                                    BPF_FUNC_get_local_storage),
+                       BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, -2),
+                       BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
+                       BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
+                       BPF_EXIT_INSN(),
+               },
+               .fixup_cgroup_storage = { 1 },
+               .result = REJECT,
+               .errstr = "invalid access to map value, value_size=64 off=-2 
size=4",
+               .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
+       },
+       {
+               "invalid cgroup storage access 5",
+               .insns = {
+                       BPF_MOV64_IMM(BPF_REG_2, 7),
+                       BPF_LD_MAP_FD(BPF_REG_1, 0),
+                       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+                                    BPF_FUNC_get_local_storage),
+                       BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
+                       BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
+                       BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
+                       BPF_EXIT_INSN(),
+               },
+               .fixup_cgroup_storage = { 1 },
+               .result = REJECT,
+               .errstr = "get_local_storage() doesn't support non-zero flags",
+               .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
+       },
        {
                "multiple registers share map_lookup_elem result",
                .insns = {
@@ -12418,6 +12517,19 @@ static int create_map_in_map(void)
        return outer_map_fd;
 }
 
+static int create_cgroup_storage(void)
+{
+       int fd;
+
+       fd = bpf_create_map(BPF_MAP_TYPE_CGROUP_STORAGE,
+                           sizeof(struct bpf_cgroup_storage_key),
+                           TEST_DATA_LEN, 0, 0);
+       if (fd < 0)
+               printf("Failed to create array '%s'!\n", strerror(errno));
+
+       return fd;
+}
+
 static char bpf_vlog[UINT_MAX >> 8];
 
 static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
@@ -12430,6 +12542,7 @@ static void do_test_fixup(struct bpf_test *test, struct 
bpf_insn *prog,
        int *fixup_prog1 = test->fixup_prog1;
        int *fixup_prog2 = test->fixup_prog2;
        int *fixup_map_in_map = test->fixup_map_in_map;
+       int *fixup_cgroup_storage = test->fixup_cgroup_storage;
 
        if (test->fill_helper)
                test->fill_helper(test);
@@ -12497,6 +12610,14 @@ static void do_test_fixup(struct bpf_test *test, 
struct bpf_insn *prog,
                        fixup_map_in_map++;
                } while (*fixup_map_in_map);
        }
+
+       if (*fixup_cgroup_storage) {
+               map_fds[7] = create_cgroup_storage();
+               do {
+                       prog[*fixup_cgroup_storage].imm = map_fds[7];
+                       fixup_cgroup_storage++;
+               } while (*fixup_cgroup_storage);
+       }
 }
 
 static void do_test_single(struct bpf_test *test, bool unpriv,
-- 
2.14.4

Reply via email to