diff options
Diffstat (limited to 'tools/testing/selftests/bpf/test_verifier.c')
| -rw-r--r-- | tools/testing/selftests/bpf/test_verifier.c | 510 | 
1 files changed, 508 insertions, 2 deletions
| diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c index 26f3250bdcd2..64ae21f64489 100644 --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c @@ -1130,15 +1130,27 @@ static struct bpf_test tests[] = {  		.errstr = "invalid bpf_context access",  	},  	{ -		"check skb->mark is writeable by SK_SKB", +		"invalid access of skb->mark for SK_SKB", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, +				    offsetof(struct __sk_buff, mark)), +			BPF_EXIT_INSN(), +		}, +		.result =  REJECT, +		.prog_type = BPF_PROG_TYPE_SK_SKB, +		.errstr = "invalid bpf_context access", +	}, +	{ +		"check skb->mark is not writeable by SK_SKB",  		.insns = {  			BPF_MOV64_IMM(BPF_REG_0, 0),  			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,  				    offsetof(struct __sk_buff, mark)),  			BPF_EXIT_INSN(),  		}, -		.result = ACCEPT, +		.result =  REJECT,  		.prog_type = BPF_PROG_TYPE_SK_SKB, +		.errstr = "invalid bpf_context access",  	},  	{  		"check skb->tc_index is writeable by SK_SKB", @@ -6645,6 +6657,500 @@ static struct bpf_test tests[] = {  		.errstr = "BPF_END uses reserved fields",  		.result = REJECT,  	}, +	{ +		"arithmetic ops make PTR_TO_CTX unusable", +		.insns = { +			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, +				      offsetof(struct __sk_buff, data) - +				      offsetof(struct __sk_buff, mark)), +			BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, +				    offsetof(struct __sk_buff, mark)), +			BPF_EXIT_INSN(), +		}, +		.errstr = "dereference of modified ctx ptr R1 off=68+8, ctx+const is allowed, ctx+const+const is not", +		.result = REJECT, +		.prog_type = BPF_PROG_TYPE_SCHED_CLS, +	}, +	{ +		"XDP pkt read, pkt_end mangling, bad access 1", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), +			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), +			BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 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(), +		}, +		.errstr = "R1 offset is outside of the packet", +		.result = REJECT, +		.prog_type = BPF_PROG_TYPE_XDP, +	}, +	{ +		"XDP pkt read, pkt_end mangling, bad access 2", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), +			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), +			BPF_ALU64_IMM(BPF_SUB, BPF_REG_3, 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(), +		}, +		.errstr = "R1 offset is outside of the packet", +		.result = REJECT, +		.prog_type = BPF_PROG_TYPE_XDP, +	}, +	{ +		"XDP pkt read, pkt_data' > pkt_end, good access", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_data' > pkt_end, bad access 1", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_data' > pkt_end, bad access 2", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_end > pkt_data', good access", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_end > pkt_data', bad access 1", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_end > pkt_data', bad access 2", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_data' < pkt_end, good access", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_data' < pkt_end, bad access 1", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_data' < pkt_end, bad access 2", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_end < pkt_data', good access", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_end < pkt_data', bad access 1", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_end < pkt_data', bad access 2", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_data' >= pkt_end, good access", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_data' >= pkt_end, bad access 1", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_data' >= pkt_end, bad access 2", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_end >= pkt_data', good access", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_end >= pkt_data', bad access 1", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_end >= pkt_data', bad access 2", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_data' <= pkt_end, good access", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_data' <= pkt_end, bad access 1", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_data' <= pkt_end, bad access 2", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_end <= pkt_data', good access", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_end <= pkt_data', bad access 1", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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_end <= pkt_data', bad access 2", +		.insns = { +			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, +				    offsetof(struct xdp_md, data)), +			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, +				    offsetof(struct xdp_md, data_end)), +			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, +	},  };  static int probe_filter_length(const struct bpf_insn *fp) |