|
@@ -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,121 @@ 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,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "invalid cgroup storage access 6",
|
|
|
+ .insns = {
|
|
|
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
|
|
|
+ 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 = {
|
|
@@ -6997,7 +7113,7 @@ static struct bpf_test tests[] = {
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
|
|
|
BPF_FUNC_map_lookup_elem),
|
|
|
- BPF_MOV64_REG(BPF_REG_0, 0),
|
|
|
+ BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
BPF_EXIT_INSN(),
|
|
|
},
|
|
|
.fixup_map_in_map = { 3 },
|
|
@@ -7020,7 +7136,7 @@ static struct bpf_test tests[] = {
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
|
|
|
BPF_FUNC_map_lookup_elem),
|
|
|
- BPF_MOV64_REG(BPF_REG_0, 0),
|
|
|
+ BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
BPF_EXIT_INSN(),
|
|
|
},
|
|
|
.fixup_map_in_map = { 3 },
|
|
@@ -7042,7 +7158,7 @@ static struct bpf_test tests[] = {
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
|
|
|
BPF_FUNC_map_lookup_elem),
|
|
|
- BPF_MOV64_REG(BPF_REG_0, 0),
|
|
|
+ BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
BPF_EXIT_INSN(),
|
|
|
},
|
|
|
.fixup_map_in_map = { 3 },
|
|
@@ -12372,6 +12488,32 @@ static struct bpf_test tests[] = {
|
|
|
.result = REJECT,
|
|
|
.errstr = "variable ctx access var_off=(0x0; 0x4)",
|
|
|
},
|
|
|
+ {
|
|
|
+ "mov64 src == dst",
|
|
|
+ .insns = {
|
|
|
+ BPF_MOV64_IMM(BPF_REG_2, 0),
|
|
|
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_2),
|
|
|
+ // Check bounds are OK
|
|
|
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
|
|
|
+ BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
+ },
|
|
|
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
+ .result = ACCEPT,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "mov64 src != dst",
|
|
|
+ .insns = {
|
|
|
+ BPF_MOV64_IMM(BPF_REG_3, 0),
|
|
|
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_3),
|
|
|
+ // Check bounds are OK
|
|
|
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
|
|
|
+ BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
+ },
|
|
|
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
+ .result = ACCEPT,
|
|
|
+ },
|
|
|
};
|
|
|
|
|
|
static int probe_filter_length(const struct bpf_insn *fp)
|
|
@@ -12476,6 +12618,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,
|
|
@@ -12488,6 +12643,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);
|
|
@@ -12555,6 +12711,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,
|