lkml.org 
[lkml]   [2018]   [Jun]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH bpf-next 12/14] selftests/bpf: add verifier cgroup storage tests
    Date
    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 <guro@fb.com>
    Cc: Alexei Starovoitov <ast@kernel.org>
    Cc: Daniel Borkmann <daniel@iogearbox.net>
    Acked-by: Martin KaFai Lau <kafai@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
    \
     
     \ /
      Last update: 2018-06-28 18:49    [W:5.007 / U:0.196 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site