diff options
Diffstat (limited to 'tools/testing/selftests/bpf')
| -rw-r--r-- | tools/testing/selftests/bpf/Makefile | 1 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/bpf_endian.h | 1 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/bpf_helpers.h | 3 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/bpf_util.h | 18 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/include/uapi/linux/types.h | 1 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/sockmap_verdict_prog.c | 4 | ||||
| -rwxr-xr-x | tools/testing/selftests/bpf/test_kmod.sh | 1 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/test_lpm_map.c | 1 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/test_maps.c | 12 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/test_tag.c | 1 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/test_verifier.c | 510 | 
11 files changed, 539 insertions, 14 deletions
| diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index f4b23d697448..eab7644a07b4 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0  LIBDIR := ../../../lib  BPFDIR := $(LIBDIR)/bpf  APIDIR := ../../../include/uapi diff --git a/tools/testing/selftests/bpf/bpf_endian.h b/tools/testing/selftests/bpf/bpf_endian.h index 74af266aa512..b25595ea4a78 100644 --- a/tools/testing/selftests/bpf/bpf_endian.h +++ b/tools/testing/selftests/bpf/bpf_endian.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  #ifndef __BPF_ENDIAN__  #define __BPF_ENDIAN__ diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h index 36fb9161b34a..50353c10573c 100644 --- a/tools/testing/selftests/bpf/bpf_helpers.h +++ b/tools/testing/selftests/bpf/bpf_helpers.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  #ifndef __BPF_HELPERS_H  #define __BPF_HELPERS_H @@ -65,7 +66,7 @@ static int (*bpf_xdp_adjust_head)(void *ctx, int offset) =  static int (*bpf_setsockopt)(void *ctx, int level, int optname, void *optval,  			     int optlen) =  	(void *) BPF_FUNC_setsockopt; -static int (*bpf_sk_redirect_map)(void *map, int key, int flags) = +static int (*bpf_sk_redirect_map)(void *ctx, void *map, int key, int flags) =  	(void *) BPF_FUNC_sk_redirect_map;  static int (*bpf_sock_map_update)(void *map, void *key, void *value,  				  unsigned long long flags) = diff --git a/tools/testing/selftests/bpf/bpf_util.h b/tools/testing/selftests/bpf/bpf_util.h index 20ecbaa0d85d..d0811b3d6a6f 100644 --- a/tools/testing/selftests/bpf/bpf_util.h +++ b/tools/testing/selftests/bpf/bpf_util.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  #ifndef __BPF_UTIL__  #define __BPF_UTIL__ @@ -12,6 +13,7 @@ static inline unsigned int bpf_num_possible_cpus(void)  	unsigned int start, end, possible_cpus = 0;  	char buff[128];  	FILE *fp; +	int n;  	fp = fopen(fcpu, "r");  	if (!fp) { @@ -20,17 +22,17 @@ static inline unsigned int bpf_num_possible_cpus(void)  	}  	while (fgets(buff, sizeof(buff), fp)) { -		if (sscanf(buff, "%u-%u", &start, &end) == 2) { -			possible_cpus = start == 0 ? end + 1 : 0; -			break; +		n = sscanf(buff, "%u-%u", &start, &end); +		if (n == 0) { +			printf("Failed to retrieve # possible CPUs!\n"); +			exit(1); +		} else if (n == 1) { +			end = start;  		} +		possible_cpus = start == 0 ? end + 1 : 0; +		break;  	} -  	fclose(fp); -	if (!possible_cpus) { -		printf("Failed to retrieve # possible CPUs!\n"); -		exit(1); -	}  	return possible_cpus;  } diff --git a/tools/testing/selftests/bpf/include/uapi/linux/types.h b/tools/testing/selftests/bpf/include/uapi/linux/types.h index 51841848fbfe..91fa51a9c31d 100644 --- a/tools/testing/selftests/bpf/include/uapi/linux/types.h +++ b/tools/testing/selftests/bpf/include/uapi/linux/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  #ifndef _UAPI_LINUX_TYPES_H  #define _UAPI_LINUX_TYPES_H diff --git a/tools/testing/selftests/bpf/sockmap_verdict_prog.c b/tools/testing/selftests/bpf/sockmap_verdict_prog.c index 9b99bd10807d..2cd2d552938b 100644 --- a/tools/testing/selftests/bpf/sockmap_verdict_prog.c +++ b/tools/testing/selftests/bpf/sockmap_verdict_prog.c @@ -61,8 +61,8 @@ int bpf_prog2(struct __sk_buff *skb)  	bpf_printk("verdict: data[0] = redir(%u:%u)\n", map, sk);  	if (!map) -		return bpf_sk_redirect_map(&sock_map_rx, sk, 0); -	return bpf_sk_redirect_map(&sock_map_tx, sk, 0); +		return bpf_sk_redirect_map(skb, &sock_map_rx, sk, 0); +	return bpf_sk_redirect_map(skb, &sock_map_tx, sk, 0);  }  char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/test_kmod.sh b/tools/testing/selftests/bpf/test_kmod.sh index 6d58cca8e235..ed4774d8d6ed 100755 --- a/tools/testing/selftests/bpf/test_kmod.sh +++ b/tools/testing/selftests/bpf/test_kmod.sh @@ -1,4 +1,5 @@  #!/bin/sh +# SPDX-License-Identifier: GPL-2.0  SRC_TREE=../../../../ diff --git a/tools/testing/selftests/bpf/test_lpm_map.c b/tools/testing/selftests/bpf/test_lpm_map.c index e97565243d59..f93a333cbf2c 100644 --- a/tools/testing/selftests/bpf/test_lpm_map.c +++ b/tools/testing/selftests/bpf/test_lpm_map.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   * Randomized tests for eBPF longest-prefix-match maps   * diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c index fe3a443a1102..50ce52d2013d 100644 --- a/tools/testing/selftests/bpf/test_maps.c +++ b/tools/testing/selftests/bpf/test_maps.c @@ -466,7 +466,7 @@ static void test_sockmap(int tasks, void *data)  	int one = 1, map_fd_rx, map_fd_tx, map_fd_break, s, sc, rc;  	struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_break;  	int ports[] = {50200, 50201, 50202, 50204}; -	int err, i, fd, sfd[6] = {0xdeadbeef}; +	int err, i, fd, udp, sfd[6] = {0xdeadbeef};  	u8 buf[20] = {0x0, 0x5, 0x3, 0x2, 0x1, 0x0};  	int parse_prog, verdict_prog;  	struct sockaddr_in addr; @@ -548,6 +548,16 @@ static void test_sockmap(int tasks, void *data)  		goto out_sockmap;  	} +	/* Test update with unsupported UDP socket */ +	udp = socket(AF_INET, SOCK_DGRAM, 0); +	i = 0; +	err = bpf_map_update_elem(fd, &i, &udp, BPF_ANY); +	if (!err) { +		printf("Failed socket SOCK_DGRAM allowed '%i:%i'\n", +		       i, udp); +		goto out_sockmap; +	} +  	/* Test update without programs */  	for (i = 0; i < 6; i++) {  		err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY); diff --git a/tools/testing/selftests/bpf/test_tag.c b/tools/testing/selftests/bpf/test_tag.c index de409fc50c35..8b201895c569 100644 --- a/tools/testing/selftests/bpf/test_tag.c +++ b/tools/testing/selftests/bpf/test_tag.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  #include <stdint.h>  #include <stdio.h>  #include <stdlib.h> 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) |