|
@@ -49,6 +49,7 @@
|
|
|
#define MAX_NR_MAPS 4
|
|
|
|
|
|
#define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0)
|
|
|
+#define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1)
|
|
|
|
|
|
struct bpf_test {
|
|
|
const char *descr;
|
|
@@ -2614,6 +2615,30 @@ static struct bpf_test tests[] = {
|
|
|
.result = REJECT,
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
},
|
|
|
+ {
|
|
|
+ "direct packet access: test17 (pruning, alignment)",
|
|
|
+ .insns = {
|
|
|
+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
|
|
+ offsetof(struct __sk_buff, data)),
|
|
|
+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
|
|
+ offsetof(struct __sk_buff, data_end)),
|
|
|
+ BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
|
|
|
+ offsetof(struct __sk_buff, mark)),
|
|
|
+ BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
|
|
|
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 14),
|
|
|
+ BPF_JMP_IMM(BPF_JGT, BPF_REG_7, 1, 4),
|
|
|
+ BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
|
|
|
+ BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, -4),
|
|
|
+ BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
|
|
|
+ BPF_JMP_A(-6),
|
|
|
+ },
|
|
|
+ .errstr = "misaligned packet access off 2+15+-4 size 4",
|
|
|
+ .result = REJECT,
|
|
|
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
+ .flags = F_LOAD_WITH_STRICT_ALIGNMENT,
|
|
|
+ },
|
|
|
{
|
|
|
"helper access to packet: test1, valid packet_ptr range",
|
|
|
.insns = {
|
|
@@ -3340,6 +3365,70 @@ static struct bpf_test tests[] = {
|
|
|
.result = ACCEPT,
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS
|
|
|
},
|
|
|
+ {
|
|
|
+ "alu ops on ptr_to_map_value_or_null, 1",
|
|
|
+ .insns = {
|
|
|
+ BPF_MOV64_IMM(BPF_REG_1, 10),
|
|
|
+ BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
|
|
|
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
|
|
|
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
|
|
|
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
|
|
|
+ BPF_FUNC_map_lookup_elem),
|
|
|
+ BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
|
|
|
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -2),
|
|
|
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 2),
|
|
|
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
|
|
|
+ BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
+ },
|
|
|
+ .fixup_map1 = { 4 },
|
|
|
+ .errstr = "R4 invalid mem access",
|
|
|
+ .result = REJECT,
|
|
|
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "alu ops on ptr_to_map_value_or_null, 2",
|
|
|
+ .insns = {
|
|
|
+ BPF_MOV64_IMM(BPF_REG_1, 10),
|
|
|
+ BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
|
|
|
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
|
|
|
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
|
|
|
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
|
|
|
+ BPF_FUNC_map_lookup_elem),
|
|
|
+ BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
|
|
|
+ BPF_ALU64_IMM(BPF_AND, BPF_REG_4, -1),
|
|
|
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
|
|
|
+ BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
+ },
|
|
|
+ .fixup_map1 = { 4 },
|
|
|
+ .errstr = "R4 invalid mem access",
|
|
|
+ .result = REJECT,
|
|
|
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "alu ops on ptr_to_map_value_or_null, 3",
|
|
|
+ .insns = {
|
|
|
+ BPF_MOV64_IMM(BPF_REG_1, 10),
|
|
|
+ BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
|
|
|
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
|
|
|
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
|
|
|
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
|
|
|
+ BPF_FUNC_map_lookup_elem),
|
|
|
+ BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
|
|
|
+ BPF_ALU64_IMM(BPF_LSH, BPF_REG_4, 1),
|
|
|
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
|
|
|
+ BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
+ },
|
|
|
+ .fixup_map1 = { 4 },
|
|
|
+ .errstr = "R4 invalid mem access",
|
|
|
+ .result = REJECT,
|
|
|
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS
|
|
|
+ },
|
|
|
{
|
|
|
"invalid memory access with multiple map_lookup_elem calls",
|
|
|
.insns = {
|
|
@@ -4937,7 +5026,149 @@ static struct bpf_test tests[] = {
|
|
|
.fixup_map_in_map = { 3 },
|
|
|
.errstr = "R1 type=map_value_or_null expected=map_ptr",
|
|
|
.result = REJECT,
|
|
|
- }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "ld_abs: check calling conv, r1",
|
|
|
+ .insns = {
|
|
|
+ BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
|
|
|
+ BPF_MOV64_IMM(BPF_REG_1, 0),
|
|
|
+ BPF_LD_ABS(BPF_W, -0x200000),
|
|
|
+ BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
+ },
|
|
|
+ .errstr = "R1 !read_ok",
|
|
|
+ .result = REJECT,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "ld_abs: check calling conv, r2",
|
|
|
+ .insns = {
|
|
|
+ BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
|
|
|
+ BPF_MOV64_IMM(BPF_REG_2, 0),
|
|
|
+ BPF_LD_ABS(BPF_W, -0x200000),
|
|
|
+ BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
+ },
|
|
|
+ .errstr = "R2 !read_ok",
|
|
|
+ .result = REJECT,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "ld_abs: check calling conv, r3",
|
|
|
+ .insns = {
|
|
|
+ BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
|
|
|
+ BPF_MOV64_IMM(BPF_REG_3, 0),
|
|
|
+ BPF_LD_ABS(BPF_W, -0x200000),
|
|
|
+ BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
+ },
|
|
|
+ .errstr = "R3 !read_ok",
|
|
|
+ .result = REJECT,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "ld_abs: check calling conv, r4",
|
|
|
+ .insns = {
|
|
|
+ BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
|
|
|
+ BPF_MOV64_IMM(BPF_REG_4, 0),
|
|
|
+ BPF_LD_ABS(BPF_W, -0x200000),
|
|
|
+ BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
+ },
|
|
|
+ .errstr = "R4 !read_ok",
|
|
|
+ .result = REJECT,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "ld_abs: check calling conv, r5",
|
|
|
+ .insns = {
|
|
|
+ BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
|
|
|
+ BPF_MOV64_IMM(BPF_REG_5, 0),
|
|
|
+ BPF_LD_ABS(BPF_W, -0x200000),
|
|
|
+ BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
+ },
|
|
|
+ .errstr = "R5 !read_ok",
|
|
|
+ .result = REJECT,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "ld_abs: check calling conv, r7",
|
|
|
+ .insns = {
|
|
|
+ BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
|
|
|
+ BPF_MOV64_IMM(BPF_REG_7, 0),
|
|
|
+ BPF_LD_ABS(BPF_W, -0x200000),
|
|
|
+ BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
+ },
|
|
|
+ .result = ACCEPT,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "ld_ind: check calling conv, r1",
|
|
|
+ .insns = {
|
|
|
+ BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
|
|
|
+ BPF_MOV64_IMM(BPF_REG_1, 1),
|
|
|
+ BPF_LD_IND(BPF_W, BPF_REG_1, -0x200000),
|
|
|
+ BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
+ },
|
|
|
+ .errstr = "R1 !read_ok",
|
|
|
+ .result = REJECT,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "ld_ind: check calling conv, r2",
|
|
|
+ .insns = {
|
|
|
+ BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
|
|
|
+ BPF_MOV64_IMM(BPF_REG_2, 1),
|
|
|
+ BPF_LD_IND(BPF_W, BPF_REG_2, -0x200000),
|
|
|
+ BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
+ },
|
|
|
+ .errstr = "R2 !read_ok",
|
|
|
+ .result = REJECT,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "ld_ind: check calling conv, r3",
|
|
|
+ .insns = {
|
|
|
+ BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
|
|
|
+ BPF_MOV64_IMM(BPF_REG_3, 1),
|
|
|
+ BPF_LD_IND(BPF_W, BPF_REG_3, -0x200000),
|
|
|
+ BPF_MOV64_REG(BPF_REG_0, BPF_REG_3),
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
+ },
|
|
|
+ .errstr = "R3 !read_ok",
|
|
|
+ .result = REJECT,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "ld_ind: check calling conv, r4",
|
|
|
+ .insns = {
|
|
|
+ BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
|
|
|
+ BPF_MOV64_IMM(BPF_REG_4, 1),
|
|
|
+ BPF_LD_IND(BPF_W, BPF_REG_4, -0x200000),
|
|
|
+ BPF_MOV64_REG(BPF_REG_0, BPF_REG_4),
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
+ },
|
|
|
+ .errstr = "R4 !read_ok",
|
|
|
+ .result = REJECT,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "ld_ind: check calling conv, r5",
|
|
|
+ .insns = {
|
|
|
+ BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
|
|
|
+ BPF_MOV64_IMM(BPF_REG_5, 1),
|
|
|
+ BPF_LD_IND(BPF_W, BPF_REG_5, -0x200000),
|
|
|
+ BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
+ },
|
|
|
+ .errstr = "R5 !read_ok",
|
|
|
+ .result = REJECT,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "ld_ind: check calling conv, r7",
|
|
|
+ .insns = {
|
|
|
+ BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
|
|
|
+ BPF_MOV64_IMM(BPF_REG_7, 1),
|
|
|
+ BPF_LD_IND(BPF_W, BPF_REG_7, -0x200000),
|
|
|
+ BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
+ },
|
|
|
+ .result = ACCEPT,
|
|
|
+ },
|
|
|
};
|
|
|
|
|
|
static int probe_filter_length(const struct bpf_insn *fp)
|
|
@@ -5059,9 +5290,9 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
|
|
|
|
|
|
do_test_fixup(test, prog, map_fds);
|
|
|
|
|
|
- fd_prog = bpf_load_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
|
|
|
- prog, prog_len, "GPL", 0, bpf_vlog,
|
|
|
- sizeof(bpf_vlog));
|
|
|
+ fd_prog = bpf_verify_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
|
|
|
+ prog, prog_len, test->flags & F_LOAD_WITH_STRICT_ALIGNMENT,
|
|
|
+ "GPL", 0, bpf_vlog, sizeof(bpf_vlog));
|
|
|
|
|
|
expected_ret = unpriv && test->result_unpriv != UNDEF ?
|
|
|
test->result_unpriv : test->result;
|