BPF range marking improvements for meta data
Subsystems (6)
Daniel Borkmann
maintainercover BPF range marking improvements for meta data
The set contains improvements for direct packet access range markings related to data_meta pointer and test cases for all such access patterns that the verifier matches on.
Thanks!
Daniel Borkmann (3):
bpf: minor cleanups after merge
bpf: also improve pattern matches for meta access
bpf: add test cases to bpf selftests to cover all meta tests
kernel/bpf/verifier.c | 167 +++++---- tools/testing/selftests/bpf/test_verifier.c | 552 +++++++++++++++++++++++++--- 2 files changed, 594 insertions(+), 125 deletions(-)
Signature · 1 line
1.9.3
Daniel Borkmann
maintainerPATCH 1/3 bpf: minor cleanups after merge
Two minor cleanups after Dave's recent merge in f8ddadc4db6c ("Merge git://git.kernel.org...") of net into net-next in order to get the code in line with what was done originally in the net tree: i) use max() instead of max_t() since both ranges are u16, ii) don't split the direct access test cases in the middle with bpf_exit test cases from 390ee7e29fc ("bpf: enforce return code for cgroup-bpf programs").
--- kernel/bpf/verifier.c | 2 +- tools/testing/selftests/bpf/test_verifier.c | 144 ++++++++++++++-------------- 2 files changed, 73 insertions(+), 73 deletions(-)
kernel/bpf/verifier.c +1 -1
@@ -2532,7 +2532,7 @@ static void find_good_pkt_pointers(struct bpf_verifier_state *state,continue ; reg = &state->stack[i].spilled_ptr;if (reg->type == type && reg->id == dst_reg->id) - reg->range =max_t (u16, reg->range, new_range); + reg->range =max (reg->range, new_range); } }
tools/testing/selftests/bpf/test_verifier.c +72 -72
156 lines not on this page · raw message
Signature · 1 line
1.9.3
Daniel Borkmann
maintainerPATCH 2/3 bpf: also improve pattern matches for meta access
In reply to Daniel BorkmannFollow-up to 0fd4759c5515 ("bpf: fix pattern matches for direct packet access") to cover also the remaining data_meta/data matches in the verifier. The matches are also refactored a bit to simplify handling of all the cases.
--- kernel/bpf/verifier.c | 165 +++++++++++++++++++++++++++++--------------------- 1 file changed, 96 insertions(+), 69 deletions(-)
kernel/bpf/verifier.c +96 -69
@@ -2787,6 +2787,99 @@ static void mark_map_regs(struct bpf_verifier_state *state, u32 regno, } } +static bool try_match_pkt_pointers (const struct bpf_insn *insn, +struct bpf_reg_state *dst_reg, +struct bpf_reg_state *src_reg, +struct bpf_verifier_state *this_branch, +struct bpf_verifier_state *other_branch) +{ +if (BPF_SRC (insn->code) !=BPF_X ) +return false; + +switch (BPF_OP (insn->code)) { +case BPF_JGT : +if ((dst_reg->type ==PTR_TO_PACKET && + src_reg->type ==PTR_TO_PACKET_END ) || + (dst_reg->type ==PTR_TO_PACKET_META && +reg_is_init_pkt_pointer (src_reg,PTR_TO_PACKET ))) { +/* pkt_data' > pkt_end, pkt_meta' > pkt_data */ +find_good_pkt_pointers (this_branch, dst_reg, + dst_reg->type, false); + }else if ((dst_reg->type ==PTR_TO_PACKET_END && + src_reg->type ==PTR_TO_PACKET ) || + (reg_is_init_pkt_pointer (dst_reg,PTR_TO_PACKET ) && + src_reg->type ==PTR_TO_PACKET_META )) { +/* pkt_end > pkt_data', pkt_data > pkt_meta' */ +find_good_pkt_pointers (other_branch, src_reg, + src_reg->type, true); + }else { +return false; + } +break ; +case BPF_JLT : +if ((dst_reg->type ==PTR_TO_PACKET && + src_reg->type ==PTR_TO_PACKET_END ) || + (dst_reg->type ==PTR_TO_PACKET_META && +reg_is_init_pkt_pointer (src_reg,PTR_TO_PACKET ))) { +/* pkt_data' < pkt_end, pkt_meta' < pkt_data */ +find_good_pkt_pointers (other_branch, dst_reg, + dst_reg->type, true); + }else if ((dst_reg->type ==PTR_TO_PACKET_END && + src_reg->type ==PTR_TO_PACKET ) || + (reg_is_init_pkt_pointer (dst_reg,PTR_TO_PACKET ) && + src_reg->type ==PTR_TO_PACKET_META )) { +/* pkt_end < pkt_data', pkt_data > pkt_meta' */ +find_good_pkt_pointers (this_branch, src_reg, + src_reg->type, false); + }else { +return false; + } +break ; +case BPF_JGE : +if ((dst_reg->type ==PTR_TO_PACKET && + src_reg->type ==PTR_TO_PACKET_END ) || + (dst_reg->type ==PTR_TO_PACKET_META && +reg_is_init_pkt_pointer (src_reg,PTR_TO_PACKET ))) { +/* pkt_data' >= pkt_end, pkt_meta' >= pkt_data */ +find_good_pkt_pointers (this_branch, dst_reg, + dst_reg->type, true); + }else if ((dst_reg->type ==PTR_TO_PACKET_END && + src_reg->type ==PTR_TO_PACKET ) || + (reg_is_init_pkt_pointer (dst_reg,PTR_TO_PACKET ) && + src_reg->type ==PTR_TO_PACKET_META )) { +/* pkt_end >= pkt_data', pkt_data >= pkt_meta' */ +find_good_pkt_pointers (other_branch, src_reg, + src_reg->type, false); + }else { +return false; + } +break ; +case BPF_JLE : +if ((dst_reg->type ==PTR_TO_PACKET && + src_reg->type ==PTR_TO_PACKET_END ) || + (dst_reg->type ==PTR_TO_PACKET_META && +reg_is_init_pkt_pointer (src_reg,PTR_TO_PACKET ))) { +/* pkt_data' <= pkt_end, pkt_meta' <= pkt_data */ +find_good_pkt_pointers (other_branch, dst_reg, + dst_reg->type, false); + }else if ((dst_reg->type ==PTR_TO_PACKET_END && + src_reg->type ==PTR_TO_PACKET ) || + (reg_is_init_pkt_pointer (dst_reg,PTR_TO_PACKET ) && + src_reg->type ==PTR_TO_PACKET_META )) { +/* pkt_end <= pkt_data', pkt_data <= pkt_meta' */ +find_good_pkt_pointers (this_branch, src_reg, + src_reg->type, true); + }else { +return false; + } +break ; +default : +return false; + } + +return true; +} +static int check_cond_jmp_op (struct bpf_verifier_env *env,struct bpf_insn *insn,int *insn_idx) {
@@ -2893,75 +2986,9 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,*/ mark_map_regs (this_branch, insn->dst_reg, opcode ==BPF_JNE );mark_map_regs (other_branch, insn->dst_reg, opcode ==BPF_JEQ ); - }else if (BPF_SRC (insn->code) ==BPF_X && opcode ==BPF_JGT && - dst_reg->type ==PTR_TO_PACKET && - regs[insn->src_reg].type ==PTR_TO_PACKET_END ) { -/* pkt_data' > pkt_end */ -find_good_pkt_pointers (this_branch, dst_reg, -PTR_TO_PACKET , false); - }else if (BPF_SRC (insn->code) ==BPF_X && opcode ==BPF_JGT && - dst_reg->type ==PTR_TO_PACKET_END && - regs[insn->src_reg].type ==PTR_TO_PACKET ) { -/* pkt_end > pkt_data' */ -find_good_pkt_pointers (other_branch, ®s[insn->src_reg], -PTR_TO_PACKET , true); - }else if (BPF_SRC (insn->code) ==BPF_X && opcode ==BPF_JLT && - dst_reg->type ==PTR_TO_PACKET && - regs[insn->src_reg].type ==PTR_TO_PACKET_END ) { -/* pkt_data' < pkt_end */ -find_good_pkt_pointers (other_branch, dst_reg,PTR_TO_PACKET , - true); - }else if (BPF_SRC (insn->code) ==BPF_X && opcode ==BPF_JLT && - dst_reg->type ==PTR_TO_PACKET_END && - regs[insn->src_reg].type ==PTR_TO_PACKET ) { -/* pkt_end < pkt_data' */ -find_good_pkt_pointers (this_branch, ®s[insn->src_reg], -PTR_TO_PACKET , false); - }else if (BPF_SRC (insn->code) ==BPF_X && opcode ==BPF_JGE && - dst_reg->type ==PTR_TO_PACKET && - regs[insn->src_reg].type ==PTR_TO_PACKET_END ) { -/* pkt_data' >= pkt_end */ -find_good_pkt_pointers (this_branch, dst_reg, -PTR_TO_PACKET , true); - }else if (BPF_SRC (insn->code) ==BPF_X && opcode ==BPF_JGE && - dst_reg->type ==PTR_TO_PACKET_END && - regs[insn->src_reg].type ==PTR_TO_PACKET ) { -/* pkt_end >= pkt_data' */ -find_good_pkt_pointers (other_branch, ®s[insn->src_reg], -PTR_TO_PACKET , false); - }else if (BPF_SRC (insn->code) ==BPF_X && opcode ==BPF_JLE && - dst_reg->type ==PTR_TO_PACKET && - regs[insn->src_reg].type ==PTR_TO_PACKET_END ) { -/* pkt_data' <= pkt_end */ -find_good_pkt_pointers (other_branch, dst_reg, -PTR_TO_PACKET , false); - }else if (BPF_SRC (insn->code) ==BPF_X && opcode ==BPF_JLE && - dst_reg->type ==PTR_TO_PACKET_END && - regs[insn->src_reg].type ==PTR_TO_PACKET ) { -/* pkt_end <= pkt_data' */ -find_good_pkt_pointers (this_branch, ®s[insn->src_reg], -PTR_TO_PACKET , true); - }else if (BPF_SRC (insn->code) ==BPF_X && opcode ==BPF_JGT && - dst_reg->type ==PTR_TO_PACKET_META && -reg_is_init_pkt_pointer (®s[insn->src_reg],PTR_TO_PACKET )) { -find_good_pkt_pointers (this_branch, dst_reg, -PTR_TO_PACKET_META , false); - }else if (BPF_SRC (insn->code) ==BPF_X && opcode ==BPF_JLT && - dst_reg->type ==PTR_TO_PACKET_META && -reg_is_init_pkt_pointer (®s[insn->src_reg],PTR_TO_PACKET )) { -find_good_pkt_pointers (other_branch, dst_reg, -PTR_TO_PACKET_META , false); - }else if (BPF_SRC (insn->code) ==BPF_X && opcode ==BPF_JGE && -reg_is_init_pkt_pointer (dst_reg,PTR_TO_PACKET ) && - regs[insn->src_reg].type ==PTR_TO_PACKET_META ) { -find_good_pkt_pointers (other_branch, ®s[insn->src_reg], -PTR_TO_PACKET_META , false); - }else if (BPF_SRC (insn->code) ==BPF_X && opcode ==BPF_JLE && -reg_is_init_pkt_pointer (dst_reg,PTR_TO_PACKET ) && - regs[insn->src_reg].type ==PTR_TO_PACKET_META ) { -find_good_pkt_pointers (this_branch, ®s[insn->src_reg], -PTR_TO_PACKET_META , false); - }else if (is_pointer_value (env, insn->dst_reg)) { + }else if (!try_match_pkt_pointers (insn, dst_reg, ®s[insn->src_reg], + this_branch, other_branch) && +is_pointer_value (env, insn->dst_reg)) {verbose (env,"R%d pointer comparison prohibited\n" , insn->dst_reg);return -EACCES ;
Signature · 1 line
1.9.3
Daniel Borkmann
maintainerPATCH 3/3 bpf: add test cases to bpf selftests to cover all meta tests
In reply to Daniel BorkmannLets also add test cases to cover all possible data_meta access tests for good/bad access cases so we keep tracking them.
--- tools/testing/selftests/bpf/test_verifier.c | 442 ++++++++++++++++++++++++++++ 1 file changed, 442 insertions(+)
tools/testing/selftests/bpf/test_verifier.c +442 -0
@@ -7399,6 +7399,448 @@ struct test_val { .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { + "XDP pkt read, pkt_meta' > pkt_data, good access", + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JGT ,BPF_REG_1 ,BPF_REG_3 ,1 ), +BPF_LDX_MEM (BPF_DW ,BPF_REG_0 ,BPF_REG_1 ,-8 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .result =ACCEPT , + .prog_type = BPF_PROG_TYPE_XDP, + }, + { +"XDP pkt read, pkt_meta' > pkt_data, bad access 1" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JGT ,BPF_REG_1 ,BPF_REG_3 ,1 ), +BPF_LDX_MEM (BPF_DW ,BPF_REG_0 ,BPF_REG_1 ,-4 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .errstr ="R1 offset is outside of the packet" , + .result = REJECT, + .prog_type = BPF_PROG_TYPE_XDP, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, + }, + { +"XDP pkt read, pkt_meta' > pkt_data, bad access 2" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JGT ,BPF_REG_1 ,BPF_REG_3 ,0 ), +BPF_LDX_MEM (BPF_DW ,BPF_REG_0 ,BPF_REG_1 ,-8 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .errstr ="R1 offset is outside of the packet" , + .result = REJECT, + .prog_type = BPF_PROG_TYPE_XDP, + }, + { +"XDP pkt read, pkt_data > pkt_meta', good access" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JGT ,BPF_REG_3 ,BPF_REG_1 ,1 ), +BPF_JMP_IMM (BPF_JA ,0 ,0 ,1 ), +BPF_LDX_MEM (BPF_W ,BPF_REG_0 ,BPF_REG_1 ,-5 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .result =ACCEPT , + .prog_type = BPF_PROG_TYPE_XDP, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, + }, + { +"XDP pkt read, pkt_data > pkt_meta', bad access 1" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JGT ,BPF_REG_3 ,BPF_REG_1 ,1 ), +BPF_JMP_IMM (BPF_JA ,0 ,0 ,1 ), +BPF_LDX_MEM (BPF_DW ,BPF_REG_0 ,BPF_REG_1 ,-8 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .errstr ="R1 offset is outside of the packet" , + .result = REJECT, + .prog_type = BPF_PROG_TYPE_XDP, + }, + { +"XDP pkt read, pkt_data > pkt_meta', bad access 2" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JGT ,BPF_REG_3 ,BPF_REG_1 ,1 ), +BPF_LDX_MEM (BPF_DW ,BPF_REG_0 ,BPF_REG_1 ,-8 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .errstr ="R1 offset is outside of the packet" , + .result = REJECT, + .prog_type = BPF_PROG_TYPE_XDP, + }, + { +"XDP pkt read, pkt_meta' < pkt_data, good access" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JLT ,BPF_REG_1 ,BPF_REG_3 ,1 ), +BPF_JMP_IMM (BPF_JA ,0 ,0 ,1 ), +BPF_LDX_MEM (BPF_W ,BPF_REG_0 ,BPF_REG_1 ,-5 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .result =ACCEPT , + .prog_type = BPF_PROG_TYPE_XDP, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, + }, + { +"XDP pkt read, pkt_meta' < pkt_data, bad access 1" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JLT ,BPF_REG_1 ,BPF_REG_3 ,1 ), +BPF_JMP_IMM (BPF_JA ,0 ,0 ,1 ), +BPF_LDX_MEM (BPF_DW ,BPF_REG_0 ,BPF_REG_1 ,-8 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .errstr ="R1 offset is outside of the packet" , + .result = REJECT, + .prog_type = BPF_PROG_TYPE_XDP, + }, + { +"XDP pkt read, pkt_meta' < pkt_data, bad access 2" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JLT ,BPF_REG_1 ,BPF_REG_3 ,1 ), +BPF_LDX_MEM (BPF_DW ,BPF_REG_0 ,BPF_REG_1 ,-8 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .errstr ="R1 offset is outside of the packet" , + .result = REJECT, + .prog_type = BPF_PROG_TYPE_XDP, + }, + { +"XDP pkt read, pkt_data < pkt_meta', good access" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JLT ,BPF_REG_3 ,BPF_REG_1 ,1 ), +BPF_LDX_MEM (BPF_DW ,BPF_REG_0 ,BPF_REG_1 ,-8 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .result =ACCEPT , + .prog_type = BPF_PROG_TYPE_XDP, + }, + { +"XDP pkt read, pkt_data < pkt_meta', bad access 1" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JLT ,BPF_REG_3 ,BPF_REG_1 ,1 ), +BPF_LDX_MEM (BPF_DW ,BPF_REG_0 ,BPF_REG_1 ,-4 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .errstr ="R1 offset is outside of the packet" , + .result = REJECT, + .prog_type = BPF_PROG_TYPE_XDP, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, + }, + { +"XDP pkt read, pkt_data < pkt_meta', bad access 2" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JLT ,BPF_REG_3 ,BPF_REG_1 ,0 ), +BPF_LDX_MEM (BPF_DW ,BPF_REG_0 ,BPF_REG_1 ,-8 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .errstr ="R1 offset is outside of the packet" , + .result = REJECT, + .prog_type = BPF_PROG_TYPE_XDP, + }, + { +"XDP pkt read, pkt_meta' >= pkt_data, good access" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JGE ,BPF_REG_1 ,BPF_REG_3 ,1 ), +BPF_LDX_MEM (BPF_W ,BPF_REG_0 ,BPF_REG_1 ,-5 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .result =ACCEPT , + .prog_type = BPF_PROG_TYPE_XDP, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, + }, + { +"XDP pkt read, pkt_meta' >= pkt_data, bad access 1" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JGE ,BPF_REG_1 ,BPF_REG_3 ,1 ), +BPF_LDX_MEM (BPF_DW ,BPF_REG_0 ,BPF_REG_1 ,-8 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .errstr ="R1 offset is outside of the packet" , + .result = REJECT, + .prog_type = BPF_PROG_TYPE_XDP, + }, + { +"XDP pkt read, pkt_meta' >= pkt_data, bad access 2" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JGE ,BPF_REG_1 ,BPF_REG_3 ,0 ), +BPF_LDX_MEM (BPF_W ,BPF_REG_0 ,BPF_REG_1 ,-5 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .errstr ="R1 offset is outside of the packet" , + .result = REJECT, + .prog_type = BPF_PROG_TYPE_XDP, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, + }, + { +"XDP pkt read, pkt_data >= pkt_meta', good access" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JGE ,BPF_REG_3 ,BPF_REG_1 ,1 ), +BPF_JMP_IMM (BPF_JA ,0 ,0 ,1 ), +BPF_LDX_MEM (BPF_DW ,BPF_REG_0 ,BPF_REG_1 ,-8 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .result =ACCEPT , + .prog_type = BPF_PROG_TYPE_XDP, + }, + { +"XDP pkt read, pkt_data >= pkt_meta', bad access 1" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JGE ,BPF_REG_3 ,BPF_REG_1 ,1 ), +BPF_JMP_IMM (BPF_JA ,0 ,0 ,1 ), +BPF_LDX_MEM (BPF_DW ,BPF_REG_0 ,BPF_REG_1 ,-4 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .errstr ="R1 offset is outside of the packet" , + .result = REJECT, + .prog_type = BPF_PROG_TYPE_XDP, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, + }, + { +"XDP pkt read, pkt_data >= pkt_meta', bad access 2" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JGE ,BPF_REG_3 ,BPF_REG_1 ,1 ), +BPF_LDX_MEM (BPF_DW ,BPF_REG_0 ,BPF_REG_1 ,-8 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .errstr ="R1 offset is outside of the packet" , + .result = REJECT, + .prog_type = BPF_PROG_TYPE_XDP, + }, + { +"XDP pkt read, pkt_meta' <= pkt_data, good access" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JLE ,BPF_REG_1 ,BPF_REG_3 ,1 ), +BPF_JMP_IMM (BPF_JA ,0 ,0 ,1 ), +BPF_LDX_MEM (BPF_DW ,BPF_REG_0 ,BPF_REG_1 ,-8 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .result =ACCEPT , + .prog_type = BPF_PROG_TYPE_XDP, + }, + { +"XDP pkt read, pkt_meta' <= pkt_data, bad access 1" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JLE ,BPF_REG_1 ,BPF_REG_3 ,1 ), +BPF_JMP_IMM (BPF_JA ,0 ,0 ,1 ), +BPF_LDX_MEM (BPF_DW ,BPF_REG_0 ,BPF_REG_1 ,-4 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .errstr ="R1 offset is outside of the packet" , + .result = REJECT, + .prog_type = BPF_PROG_TYPE_XDP, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, + }, + { +"XDP pkt read, pkt_meta' <= pkt_data, bad access 2" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JLE ,BPF_REG_1 ,BPF_REG_3 ,1 ), +BPF_LDX_MEM (BPF_DW ,BPF_REG_0 ,BPF_REG_1 ,-8 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .errstr ="R1 offset is outside of the packet" , + .result = REJECT, + .prog_type = BPF_PROG_TYPE_XDP, + }, + { +"XDP pkt read, pkt_data <= pkt_meta', good access" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JLE ,BPF_REG_3 ,BPF_REG_1 ,1 ), +BPF_LDX_MEM (BPF_W ,BPF_REG_0 ,BPF_REG_1 ,-5 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .result =ACCEPT , + .prog_type = BPF_PROG_TYPE_XDP, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, + }, + { +"XDP pkt read, pkt_data <= pkt_meta', bad access 1" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JLE ,BPF_REG_3 ,BPF_REG_1 ,1 ), +BPF_LDX_MEM (BPF_DW ,BPF_REG_0 ,BPF_REG_1 ,-8 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .errstr ="R1 offset is outside of the packet" , + .result = REJECT, + .prog_type = BPF_PROG_TYPE_XDP, + }, + { +"XDP pkt read, pkt_data <= pkt_meta', bad access 2" , + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct xdp_md , data_meta)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct xdp_md , data)), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,8 ), +BPF_JMP_REG (BPF_JLE ,BPF_REG_3 ,BPF_REG_1 ,0 ), +BPF_LDX_MEM (BPF_W ,BPF_REG_0 ,BPF_REG_1 ,-5 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .errstr ="R1 offset is outside of the packet" , + .result = REJECT, + .prog_type = BPF_PROG_TYPE_XDP, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, + }, + {"bpf_exit with invalid return code. test1" , .insns = { BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
Signature · 1 line
1.9.3
David Miller
maintainerFrom: Daniel Borkmann <[email protected]>
Date: Wed, 1 Nov 2017 23:58:08 +0100
Quoted 3 lines
The set contains improvements for direct packet access range markings related to
data_metapointer and test cases for all such access patterns that the verifier matches on.
Series applied.
Thanks, in particular, for following up with the merge cleanups.