aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/include/uapi/linux/bpf.h3
-rw-r--r--tools/objtool/check.c9
-rw-r--r--tools/perf/Documentation/perf-record.txt4
-rwxr-xr-xtools/perf/tests/shell/trace+probe_libc_inet_pton.sh9
-rw-r--r--tools/perf/ui/hist.c9
-rw-r--r--tools/perf/util/parse-events.l17
-rw-r--r--tools/perf/util/session.c2
-rw-r--r--tools/perf/util/xyarray.h4
-rw-r--r--tools/power/x86/turbostat/turbostat.c10
-rw-r--r--tools/testing/selftests/bpf/bpf_helpers.h2
-rw-r--r--tools/testing/selftests/bpf/sockmap_verdict_prog.c4
-rw-r--r--tools/testing/selftests/bpf/test_maps.c12
-rw-r--r--tools/testing/selftests/bpf/test_verifier.c510
13 files changed, 567 insertions, 28 deletions
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index f90860d1f897..24b35a1fd4d6 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -569,9 +569,10 @@ union bpf_attr {
569 * @flags: reserved for future use 569 * @flags: reserved for future use
570 * Return: 0 on success or negative error code 570 * Return: 0 on success or negative error code
571 * 571 *
572 * int bpf_sk_redirect_map(map, key, flags) 572 * int bpf_sk_redirect_map(skb, map, key, flags)
573 * Redirect skb to a sock in map using key as a lookup key for the 573 * Redirect skb to a sock in map using key as a lookup key for the
574 * sock in map. 574 * sock in map.
575 * @skb: pointer to skb
575 * @map: pointer to sockmap 576 * @map: pointer to sockmap
576 * @key: key to lookup sock in map 577 * @key: key to lookup sock in map
577 * @flags: reserved for future use 578 * @flags: reserved for future use
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index a0c518ecf085..c0e26ad1fa7e 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -267,12 +267,13 @@ static int decode_instructions(struct objtool_file *file)
267 &insn->immediate, 267 &insn->immediate,
268 &insn->stack_op); 268 &insn->stack_op);
269 if (ret) 269 if (ret)
270 return ret; 270 goto err;
271 271
272 if (!insn->type || insn->type > INSN_LAST) { 272 if (!insn->type || insn->type > INSN_LAST) {
273 WARN_FUNC("invalid instruction type %d", 273 WARN_FUNC("invalid instruction type %d",
274 insn->sec, insn->offset, insn->type); 274 insn->sec, insn->offset, insn->type);
275 return -1; 275 ret = -1;
276 goto err;
276 } 277 }
277 278
278 hash_add(file->insn_hash, &insn->hash, insn->offset); 279 hash_add(file->insn_hash, &insn->hash, insn->offset);
@@ -296,6 +297,10 @@ static int decode_instructions(struct objtool_file *file)
296 } 297 }
297 298
298 return 0; 299 return 0;
300
301err:
302 free(insn);
303 return ret;
299} 304}
300 305
301/* 306/*
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index e397453e5a46..63526f4416ea 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -8,8 +8,8 @@ perf-record - Run a command and record its profile into perf.data
8SYNOPSIS 8SYNOPSIS
9-------- 9--------
10[verse] 10[verse]
11'perf record' [-e <EVENT> | --event=EVENT] [-l] [-a] <command> 11'perf record' [-e <EVENT> | --event=EVENT] [-a] <command>
12'perf record' [-e <EVENT> | --event=EVENT] [-l] [-a] -- <command> [<options>] 12'perf record' [-e <EVENT> | --event=EVENT] [-a] -- <command> [<options>]
13 13
14DESCRIPTION 14DESCRIPTION
15----------- 15-----------
diff --git a/tools/perf/tests/shell/trace+probe_libc_inet_pton.sh b/tools/perf/tests/shell/trace+probe_libc_inet_pton.sh
index 462fc755092e..7a84d73324e3 100755
--- a/tools/perf/tests/shell/trace+probe_libc_inet_pton.sh
+++ b/tools/perf/tests/shell/trace+probe_libc_inet_pton.sh
@@ -10,6 +10,9 @@
10 10
11. $(dirname $0)/lib/probe.sh 11. $(dirname $0)/lib/probe.sh
12 12
13ld=$(realpath /lib64/ld*.so.* | uniq)
14libc=$(echo $ld | sed 's/ld/libc/g')
15
13trace_libc_inet_pton_backtrace() { 16trace_libc_inet_pton_backtrace() {
14 idx=0 17 idx=0
15 expected[0]="PING.*bytes" 18 expected[0]="PING.*bytes"
@@ -18,8 +21,8 @@ trace_libc_inet_pton_backtrace() {
18 expected[3]=".*packets transmitted.*" 21 expected[3]=".*packets transmitted.*"
19 expected[4]="rtt min.*" 22 expected[4]="rtt min.*"
20 expected[5]="[0-9]+\.[0-9]+[[:space:]]+probe_libc:inet_pton:\([[:xdigit:]]+\)" 23 expected[5]="[0-9]+\.[0-9]+[[:space:]]+probe_libc:inet_pton:\([[:xdigit:]]+\)"
21 expected[6]=".*inet_pton[[:space:]]\(/usr/lib.*/libc-[0-9]+\.[0-9]+\.so\)$" 24 expected[6]=".*inet_pton[[:space:]]\($libc\)$"
22 expected[7]="getaddrinfo[[:space:]]\(/usr/lib.*/libc-[0-9]+\.[0-9]+\.so\)$" 25 expected[7]="getaddrinfo[[:space:]]\($libc\)$"
23 expected[8]=".*\(.*/bin/ping.*\)$" 26 expected[8]=".*\(.*/bin/ping.*\)$"
24 27
25 perf trace --no-syscalls -e probe_libc:inet_pton/max-stack=3/ ping -6 -c 1 ::1 2>&1 | grep -v ^$ | while read line ; do 28 perf trace --no-syscalls -e probe_libc:inet_pton/max-stack=3/ ping -6 -c 1 ::1 2>&1 | grep -v ^$ | while read line ; do
@@ -35,7 +38,7 @@ trace_libc_inet_pton_backtrace() {
35} 38}
36 39
37skip_if_no_perf_probe && \ 40skip_if_no_perf_probe && \
38perf probe -q /lib64/libc-*.so inet_pton && \ 41perf probe -q $libc inet_pton && \
39trace_libc_inet_pton_backtrace 42trace_libc_inet_pton_backtrace
40err=$? 43err=$?
41rm -f ${file} 44rm -f ${file}
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index ddb2c6fbdf91..db79017a6e56 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -532,7 +532,7 @@ void perf_hpp_list__prepend_sort_field(struct perf_hpp_list *list,
532 532
533void perf_hpp__column_unregister(struct perf_hpp_fmt *format) 533void perf_hpp__column_unregister(struct perf_hpp_fmt *format)
534{ 534{
535 list_del(&format->list); 535 list_del_init(&format->list);
536} 536}
537 537
538void perf_hpp__cancel_cumulate(void) 538void perf_hpp__cancel_cumulate(void)
@@ -606,6 +606,13 @@ next:
606 606
607static void fmt_free(struct perf_hpp_fmt *fmt) 607static void fmt_free(struct perf_hpp_fmt *fmt)
608{ 608{
609 /*
610 * At this point fmt should be completely
611 * unhooked, if not it's a bug.
612 */
613 BUG_ON(!list_empty(&fmt->list));
614 BUG_ON(!list_empty(&fmt->sort_list));
615
609 if (fmt->free) 616 if (fmt->free)
610 fmt->free(fmt); 617 fmt->free(fmt);
611} 618}
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index c42edeac451f..dcfdafdc2f1c 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -8,6 +8,9 @@
8 8
9%{ 9%{
10#include <errno.h> 10#include <errno.h>
11#include <sys/types.h>
12#include <sys/stat.h>
13#include <unistd.h>
11#include "../perf.h" 14#include "../perf.h"
12#include "parse-events.h" 15#include "parse-events.h"
13#include "parse-events-bison.h" 16#include "parse-events-bison.h"
@@ -53,9 +56,8 @@ static int str(yyscan_t scanner, int token)
53 return token; 56 return token;
54} 57}
55 58
56static bool isbpf(yyscan_t scanner) 59static bool isbpf_suffix(char *text)
57{ 60{
58 char *text = parse_events_get_text(scanner);
59 int len = strlen(text); 61 int len = strlen(text);
60 62
61 if (len < 2) 63 if (len < 2)
@@ -68,6 +70,17 @@ static bool isbpf(yyscan_t scanner)
68 return false; 70 return false;
69} 71}
70 72
73static bool isbpf(yyscan_t scanner)
74{
75 char *text = parse_events_get_text(scanner);
76 struct stat st;
77
78 if (!isbpf_suffix(text))
79 return false;
80
81 return stat(text, &st) == 0;
82}
83
71/* 84/*
72 * This function is called when the parser gets two kind of input: 85 * This function is called when the parser gets two kind of input:
73 * 86 *
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index a7ebd9fe8e40..76ab0709a20c 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -374,6 +374,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
374 tool->mmap2 = process_event_stub; 374 tool->mmap2 = process_event_stub;
375 if (tool->comm == NULL) 375 if (tool->comm == NULL)
376 tool->comm = process_event_stub; 376 tool->comm = process_event_stub;
377 if (tool->namespaces == NULL)
378 tool->namespaces = process_event_stub;
377 if (tool->fork == NULL) 379 if (tool->fork == NULL)
378 tool->fork = process_event_stub; 380 tool->fork = process_event_stub;
379 if (tool->exit == NULL) 381 if (tool->exit == NULL)
diff --git a/tools/perf/util/xyarray.h b/tools/perf/util/xyarray.h
index 4ba726c90870..54af60462130 100644
--- a/tools/perf/util/xyarray.h
+++ b/tools/perf/util/xyarray.h
@@ -23,12 +23,12 @@ static inline void *xyarray__entry(struct xyarray *xy, int x, int y)
23 23
24static inline int xyarray__max_y(struct xyarray *xy) 24static inline int xyarray__max_y(struct xyarray *xy)
25{ 25{
26 return xy->max_x; 26 return xy->max_y;
27} 27}
28 28
29static inline int xyarray__max_x(struct xyarray *xy) 29static inline int xyarray__max_x(struct xyarray *xy)
30{ 30{
31 return xy->max_y; 31 return xy->max_x;
32} 32}
33 33
34#endif /* _PERF_XYARRAY_H_ */ 34#endif /* _PERF_XYARRAY_H_ */
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 0dafba2c1e7d..bd9c6b31a504 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -92,7 +92,6 @@ unsigned int do_ring_perf_limit_reasons;
92unsigned int crystal_hz; 92unsigned int crystal_hz;
93unsigned long long tsc_hz; 93unsigned long long tsc_hz;
94int base_cpu; 94int base_cpu;
95int do_migrate;
96double discover_bclk(unsigned int family, unsigned int model); 95double discover_bclk(unsigned int family, unsigned int model);
97unsigned int has_hwp; /* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */ 96unsigned int has_hwp; /* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */
98 /* IA32_HWP_REQUEST, IA32_HWP_STATUS */ 97 /* IA32_HWP_REQUEST, IA32_HWP_STATUS */
@@ -303,9 +302,6 @@ int for_all_cpus(int (func)(struct thread_data *, struct core_data *, struct pkg
303 302
304int cpu_migrate(int cpu) 303int cpu_migrate(int cpu)
305{ 304{
306 if (!do_migrate)
307 return 0;
308
309 CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set); 305 CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
310 CPU_SET_S(cpu, cpu_affinity_setsize, cpu_affinity_set); 306 CPU_SET_S(cpu, cpu_affinity_setsize, cpu_affinity_set);
311 if (sched_setaffinity(0, cpu_affinity_setsize, cpu_affinity_set) == -1) 307 if (sched_setaffinity(0, cpu_affinity_setsize, cpu_affinity_set) == -1)
@@ -5007,7 +5003,6 @@ void cmdline(int argc, char **argv)
5007 {"hide", required_argument, 0, 'H'}, // meh, -h taken by --help 5003 {"hide", required_argument, 0, 'H'}, // meh, -h taken by --help
5008 {"Joules", no_argument, 0, 'J'}, 5004 {"Joules", no_argument, 0, 'J'},
5009 {"list", no_argument, 0, 'l'}, 5005 {"list", no_argument, 0, 'l'},
5010 {"migrate", no_argument, 0, 'm'},
5011 {"out", required_argument, 0, 'o'}, 5006 {"out", required_argument, 0, 'o'},
5012 {"quiet", no_argument, 0, 'q'}, 5007 {"quiet", no_argument, 0, 'q'},
5013 {"show", required_argument, 0, 's'}, 5008 {"show", required_argument, 0, 's'},
@@ -5019,7 +5014,7 @@ void cmdline(int argc, char **argv)
5019 5014
5020 progname = argv[0]; 5015 progname = argv[0];
5021 5016
5022 while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:Jmo:qST:v", 5017 while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:JM:m:o:qST:v",
5023 long_options, &option_index)) != -1) { 5018 long_options, &option_index)) != -1) {
5024 switch (opt) { 5019 switch (opt) {
5025 case 'a': 5020 case 'a':
@@ -5062,9 +5057,6 @@ void cmdline(int argc, char **argv)
5062 list_header_only++; 5057 list_header_only++;
5063 quiet++; 5058 quiet++;
5064 break; 5059 break;
5065 case 'm':
5066 do_migrate = 1;
5067 break;
5068 case 'o': 5060 case 'o':
5069 outf = fopen_or_die(optarg, "w"); 5061 outf = fopen_or_die(optarg, "w");
5070 break; 5062 break;
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
index 36fb9161b34a..b2e02bdcd098 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -65,7 +65,7 @@ static int (*bpf_xdp_adjust_head)(void *ctx, int offset) =
65static int (*bpf_setsockopt)(void *ctx, int level, int optname, void *optval, 65static int (*bpf_setsockopt)(void *ctx, int level, int optname, void *optval,
66 int optlen) = 66 int optlen) =
67 (void *) BPF_FUNC_setsockopt; 67 (void *) BPF_FUNC_setsockopt;
68static int (*bpf_sk_redirect_map)(void *map, int key, int flags) = 68static int (*bpf_sk_redirect_map)(void *ctx, void *map, int key, int flags) =
69 (void *) BPF_FUNC_sk_redirect_map; 69 (void *) BPF_FUNC_sk_redirect_map;
70static int (*bpf_sock_map_update)(void *map, void *key, void *value, 70static int (*bpf_sock_map_update)(void *map, void *key, void *value,
71 unsigned long long flags) = 71 unsigned long long flags) =
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)
61 bpf_printk("verdict: data[0] = redir(%u:%u)\n", map, sk); 61 bpf_printk("verdict: data[0] = redir(%u:%u)\n", map, sk);
62 62
63 if (!map) 63 if (!map)
64 return bpf_sk_redirect_map(&sock_map_rx, sk, 0); 64 return bpf_sk_redirect_map(skb, &sock_map_rx, sk, 0);
65 return bpf_sk_redirect_map(&sock_map_tx, sk, 0); 65 return bpf_sk_redirect_map(skb, &sock_map_tx, sk, 0);
66} 66}
67 67
68char _license[] SEC("license") = "GPL"; 68char _license[] SEC("license") = "GPL";
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)
466 int one = 1, map_fd_rx, map_fd_tx, map_fd_break, s, sc, rc; 466 int one = 1, map_fd_rx, map_fd_tx, map_fd_break, s, sc, rc;
467 struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_break; 467 struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_break;
468 int ports[] = {50200, 50201, 50202, 50204}; 468 int ports[] = {50200, 50201, 50202, 50204};
469 int err, i, fd, sfd[6] = {0xdeadbeef}; 469 int err, i, fd, udp, sfd[6] = {0xdeadbeef};
470 u8 buf[20] = {0x0, 0x5, 0x3, 0x2, 0x1, 0x0}; 470 u8 buf[20] = {0x0, 0x5, 0x3, 0x2, 0x1, 0x0};
471 int parse_prog, verdict_prog; 471 int parse_prog, verdict_prog;
472 struct sockaddr_in addr; 472 struct sockaddr_in addr;
@@ -548,6 +548,16 @@ static void test_sockmap(int tasks, void *data)
548 goto out_sockmap; 548 goto out_sockmap;
549 } 549 }
550 550
551 /* Test update with unsupported UDP socket */
552 udp = socket(AF_INET, SOCK_DGRAM, 0);
553 i = 0;
554 err = bpf_map_update_elem(fd, &i, &udp, BPF_ANY);
555 if (!err) {
556 printf("Failed socket SOCK_DGRAM allowed '%i:%i'\n",
557 i, udp);
558 goto out_sockmap;
559 }
560
551 /* Test update without programs */ 561 /* Test update without programs */
552 for (i = 0; i < 6; i++) { 562 for (i = 0; i < 6; i++) {
553 err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY); 563 err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);
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[] = {
1130 .errstr = "invalid bpf_context access", 1130 .errstr = "invalid bpf_context access",
1131 }, 1131 },
1132 { 1132 {
1133 "check skb->mark is writeable by SK_SKB", 1133 "invalid access of skb->mark for SK_SKB",
1134 .insns = {
1135 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1136 offsetof(struct __sk_buff, mark)),
1137 BPF_EXIT_INSN(),
1138 },
1139 .result = REJECT,
1140 .prog_type = BPF_PROG_TYPE_SK_SKB,
1141 .errstr = "invalid bpf_context access",
1142 },
1143 {
1144 "check skb->mark is not writeable by SK_SKB",
1134 .insns = { 1145 .insns = {
1135 BPF_MOV64_IMM(BPF_REG_0, 0), 1146 BPF_MOV64_IMM(BPF_REG_0, 0),
1136 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 1147 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1137 offsetof(struct __sk_buff, mark)), 1148 offsetof(struct __sk_buff, mark)),
1138 BPF_EXIT_INSN(), 1149 BPF_EXIT_INSN(),
1139 }, 1150 },
1140 .result = ACCEPT, 1151 .result = REJECT,
1141 .prog_type = BPF_PROG_TYPE_SK_SKB, 1152 .prog_type = BPF_PROG_TYPE_SK_SKB,
1153 .errstr = "invalid bpf_context access",
1142 }, 1154 },
1143 { 1155 {
1144 "check skb->tc_index is writeable by SK_SKB", 1156 "check skb->tc_index is writeable by SK_SKB",
@@ -6645,6 +6657,500 @@ static struct bpf_test tests[] = {
6645 .errstr = "BPF_END uses reserved fields", 6657 .errstr = "BPF_END uses reserved fields",
6646 .result = REJECT, 6658 .result = REJECT,
6647 }, 6659 },
6660 {
6661 "arithmetic ops make PTR_TO_CTX unusable",
6662 .insns = {
6663 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
6664 offsetof(struct __sk_buff, data) -
6665 offsetof(struct __sk_buff, mark)),
6666 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
6667 offsetof(struct __sk_buff, mark)),
6668 BPF_EXIT_INSN(),
6669 },
6670 .errstr = "dereference of modified ctx ptr R1 off=68+8, ctx+const is allowed, ctx+const+const is not",
6671 .result = REJECT,
6672 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6673 },
6674 {
6675 "XDP pkt read, pkt_end mangling, bad access 1",
6676 .insns = {
6677 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
6678 offsetof(struct xdp_md, data)),
6679 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6680 offsetof(struct xdp_md, data_end)),
6681 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6682 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6683 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 8),
6684 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
6685 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
6686 BPF_MOV64_IMM(BPF_REG_0, 0),
6687 BPF_EXIT_INSN(),
6688 },
6689 .errstr = "R1 offset is outside of the packet",
6690 .result = REJECT,
6691 .prog_type = BPF_PROG_TYPE_XDP,
6692 },
6693 {
6694 "XDP pkt read, pkt_end mangling, bad access 2",
6695 .insns = {
6696 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
6697 offsetof(struct xdp_md, data)),
6698 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6699 offsetof(struct xdp_md, data_end)),
6700 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6701 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6702 BPF_ALU64_IMM(BPF_SUB, BPF_REG_3, 8),
6703 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
6704 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
6705 BPF_MOV64_IMM(BPF_REG_0, 0),
6706 BPF_EXIT_INSN(),
6707 },
6708 .errstr = "R1 offset is outside of the packet",
6709 .result = REJECT,
6710 .prog_type = BPF_PROG_TYPE_XDP,
6711 },
6712 {
6713 "XDP pkt read, pkt_data' > pkt_end, good access",
6714 .insns = {
6715 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
6716 offsetof(struct xdp_md, data)),
6717 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6718 offsetof(struct xdp_md, data_end)),
6719 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6720 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6721 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
6722 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
6723 BPF_MOV64_IMM(BPF_REG_0, 0),
6724 BPF_EXIT_INSN(),
6725 },
6726 .result = ACCEPT,
6727 .prog_type = BPF_PROG_TYPE_XDP,
6728 },
6729 {
6730 "XDP pkt read, pkt_data' > pkt_end, bad access 1",
6731 .insns = {
6732 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
6733 offsetof(struct xdp_md, data)),
6734 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6735 offsetof(struct xdp_md, data_end)),
6736 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6737 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6738 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
6739 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
6740 BPF_MOV64_IMM(BPF_REG_0, 0),
6741 BPF_EXIT_INSN(),
6742 },
6743 .errstr = "R1 offset is outside of the packet",
6744 .result = REJECT,
6745 .prog_type = BPF_PROG_TYPE_XDP,
6746 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
6747 },
6748 {
6749 "XDP pkt read, pkt_data' > pkt_end, bad access 2",
6750 .insns = {
6751 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
6752 offsetof(struct xdp_md, data)),
6753 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6754 offsetof(struct xdp_md, data_end)),
6755 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6756 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6757 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 0),
6758 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
6759 BPF_MOV64_IMM(BPF_REG_0, 0),
6760 BPF_EXIT_INSN(),
6761 },
6762 .errstr = "R1 offset is outside of the packet",
6763 .result = REJECT,
6764 .prog_type = BPF_PROG_TYPE_XDP,
6765 },
6766 {
6767 "XDP pkt read, pkt_end > pkt_data', good access",
6768 .insns = {
6769 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
6770 offsetof(struct xdp_md, data)),
6771 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6772 offsetof(struct xdp_md, data_end)),
6773 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6774 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6775 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
6776 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
6777 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
6778 BPF_MOV64_IMM(BPF_REG_0, 0),
6779 BPF_EXIT_INSN(),
6780 },
6781 .result = ACCEPT,
6782 .prog_type = BPF_PROG_TYPE_XDP,
6783 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
6784 },
6785 {
6786 "XDP pkt read, pkt_end > pkt_data', bad access 1",
6787 .insns = {
6788 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
6789 offsetof(struct xdp_md, data)),
6790 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6791 offsetof(struct xdp_md, data_end)),
6792 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6793 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6794 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
6795 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
6796 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
6797 BPF_MOV64_IMM(BPF_REG_0, 0),
6798 BPF_EXIT_INSN(),
6799 },
6800 .errstr = "R1 offset is outside of the packet",
6801 .result = REJECT,
6802 .prog_type = BPF_PROG_TYPE_XDP,
6803 },
6804 {
6805 "XDP pkt read, pkt_end > pkt_data', bad access 2",
6806 .insns = {
6807 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
6808 offsetof(struct xdp_md, data)),
6809 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6810 offsetof(struct xdp_md, data_end)),
6811 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6812 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6813 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
6814 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
6815 BPF_MOV64_IMM(BPF_REG_0, 0),
6816 BPF_EXIT_INSN(),
6817 },
6818 .errstr = "R1 offset is outside of the packet",
6819 .result = REJECT,
6820 .prog_type = BPF_PROG_TYPE_XDP,
6821 },
6822 {
6823 "XDP pkt read, pkt_data' < pkt_end, good access",
6824 .insns = {
6825 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
6826 offsetof(struct xdp_md, data)),
6827 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6828 offsetof(struct xdp_md, data_end)),
6829 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6830 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6831 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
6832 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
6833 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
6834 BPF_MOV64_IMM(BPF_REG_0, 0),
6835 BPF_EXIT_INSN(),
6836 },
6837 .result = ACCEPT,
6838 .prog_type = BPF_PROG_TYPE_XDP,
6839 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
6840 },
6841 {
6842 "XDP pkt read, pkt_data' < pkt_end, bad access 1",
6843 .insns = {
6844 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
6845 offsetof(struct xdp_md, data)),
6846 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6847 offsetof(struct xdp_md, data_end)),
6848 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6849 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6850 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
6851 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
6852 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
6853 BPF_MOV64_IMM(BPF_REG_0, 0),
6854 BPF_EXIT_INSN(),
6855 },
6856 .errstr = "R1 offset is outside of the packet",
6857 .result = REJECT,
6858 .prog_type = BPF_PROG_TYPE_XDP,
6859 },
6860 {
6861 "XDP pkt read, pkt_data' < pkt_end, bad access 2",
6862 .insns = {
6863 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
6864 offsetof(struct xdp_md, data)),
6865 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6866 offsetof(struct xdp_md, data_end)),
6867 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6868 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6869 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
6870 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
6871 BPF_MOV64_IMM(BPF_REG_0, 0),
6872 BPF_EXIT_INSN(),
6873 },
6874 .errstr = "R1 offset is outside of the packet",
6875 .result = REJECT,
6876 .prog_type = BPF_PROG_TYPE_XDP,
6877 },
6878 {
6879 "XDP pkt read, pkt_end < pkt_data', good access",
6880 .insns = {
6881 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
6882 offsetof(struct xdp_md, data)),
6883 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6884 offsetof(struct xdp_md, data_end)),
6885 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6886 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6887 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
6888 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
6889 BPF_MOV64_IMM(BPF_REG_0, 0),
6890 BPF_EXIT_INSN(),
6891 },
6892 .result = ACCEPT,
6893 .prog_type = BPF_PROG_TYPE_XDP,
6894 },
6895 {
6896 "XDP pkt read, pkt_end < pkt_data', bad access 1",
6897 .insns = {
6898 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
6899 offsetof(struct xdp_md, data)),
6900 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6901 offsetof(struct xdp_md, data_end)),
6902 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6903 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6904 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
6905 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
6906 BPF_MOV64_IMM(BPF_REG_0, 0),
6907 BPF_EXIT_INSN(),
6908 },
6909 .errstr = "R1 offset is outside of the packet",
6910 .result = REJECT,
6911 .prog_type = BPF_PROG_TYPE_XDP,
6912 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
6913 },
6914 {
6915 "XDP pkt read, pkt_end < pkt_data', bad access 2",
6916 .insns = {
6917 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
6918 offsetof(struct xdp_md, data)),
6919 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6920 offsetof(struct xdp_md, data_end)),
6921 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6922 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6923 BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 0),
6924 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
6925 BPF_MOV64_IMM(BPF_REG_0, 0),
6926 BPF_EXIT_INSN(),
6927 },
6928 .errstr = "R1 offset is outside of the packet",
6929 .result = REJECT,
6930 .prog_type = BPF_PROG_TYPE_XDP,
6931 },
6932 {
6933 "XDP pkt read, pkt_data' >= pkt_end, good access",
6934 .insns = {
6935 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
6936 offsetof(struct xdp_md, data)),
6937 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6938 offsetof(struct xdp_md, data_end)),
6939 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6940 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6941 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
6942 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
6943 BPF_MOV64_IMM(BPF_REG_0, 0),
6944 BPF_EXIT_INSN(),
6945 },
6946 .result = ACCEPT,
6947 .prog_type = BPF_PROG_TYPE_XDP,
6948 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
6949 },
6950 {
6951 "XDP pkt read, pkt_data' >= pkt_end, bad access 1",
6952 .insns = {
6953 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
6954 offsetof(struct xdp_md, data)),
6955 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6956 offsetof(struct xdp_md, data_end)),
6957 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6958 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6959 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
6960 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
6961 BPF_MOV64_IMM(BPF_REG_0, 0),
6962 BPF_EXIT_INSN(),
6963 },
6964 .errstr = "R1 offset is outside of the packet",
6965 .result = REJECT,
6966 .prog_type = BPF_PROG_TYPE_XDP,
6967 },
6968 {
6969 "XDP pkt read, pkt_data' >= pkt_end, bad access 2",
6970 .insns = {
6971 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
6972 offsetof(struct xdp_md, data)),
6973 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6974 offsetof(struct xdp_md, data_end)),
6975 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6976 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6977 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 0),
6978 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
6979 BPF_MOV64_IMM(BPF_REG_0, 0),
6980 BPF_EXIT_INSN(),
6981 },
6982 .errstr = "R1 offset is outside of the packet",
6983 .result = REJECT,
6984 .prog_type = BPF_PROG_TYPE_XDP,
6985 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
6986 },
6987 {
6988 "XDP pkt read, pkt_end >= pkt_data', good access",
6989 .insns = {
6990 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
6991 offsetof(struct xdp_md, data)),
6992 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
6993 offsetof(struct xdp_md, data_end)),
6994 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6995 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
6996 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
6997 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
6998 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
6999 BPF_MOV64_IMM(BPF_REG_0, 0),
7000 BPF_EXIT_INSN(),
7001 },
7002 .result = ACCEPT,
7003 .prog_type = BPF_PROG_TYPE_XDP,
7004 },
7005 {
7006 "XDP pkt read, pkt_end >= pkt_data', bad access 1",
7007 .insns = {
7008 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7009 offsetof(struct xdp_md, data)),
7010 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7011 offsetof(struct xdp_md, data_end)),
7012 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7013 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7014 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
7015 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
7016 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
7017 BPF_MOV64_IMM(BPF_REG_0, 0),
7018 BPF_EXIT_INSN(),
7019 },
7020 .errstr = "R1 offset is outside of the packet",
7021 .result = REJECT,
7022 .prog_type = BPF_PROG_TYPE_XDP,
7023 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7024 },
7025 {
7026 "XDP pkt read, pkt_end >= pkt_data', bad access 2",
7027 .insns = {
7028 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7029 offsetof(struct xdp_md, data)),
7030 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7031 offsetof(struct xdp_md, data_end)),
7032 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7033 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7034 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
7035 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7036 BPF_MOV64_IMM(BPF_REG_0, 0),
7037 BPF_EXIT_INSN(),
7038 },
7039 .errstr = "R1 offset is outside of the packet",
7040 .result = REJECT,
7041 .prog_type = BPF_PROG_TYPE_XDP,
7042 },
7043 {
7044 "XDP pkt read, pkt_data' <= pkt_end, good access",
7045 .insns = {
7046 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7047 offsetof(struct xdp_md, data)),
7048 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7049 offsetof(struct xdp_md, data_end)),
7050 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7051 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7052 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
7053 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
7054 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7055 BPF_MOV64_IMM(BPF_REG_0, 0),
7056 BPF_EXIT_INSN(),
7057 },
7058 .result = ACCEPT,
7059 .prog_type = BPF_PROG_TYPE_XDP,
7060 },
7061 {
7062 "XDP pkt read, pkt_data' <= pkt_end, bad access 1",
7063 .insns = {
7064 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7065 offsetof(struct xdp_md, data)),
7066 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7067 offsetof(struct xdp_md, data_end)),
7068 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7069 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7070 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
7071 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
7072 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4),
7073 BPF_MOV64_IMM(BPF_REG_0, 0),
7074 BPF_EXIT_INSN(),
7075 },
7076 .errstr = "R1 offset is outside of the packet",
7077 .result = REJECT,
7078 .prog_type = BPF_PROG_TYPE_XDP,
7079 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7080 },
7081 {
7082 "XDP pkt read, pkt_data' <= pkt_end, bad access 2",
7083 .insns = {
7084 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7085 offsetof(struct xdp_md, data)),
7086 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7087 offsetof(struct xdp_md, data_end)),
7088 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7089 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7090 BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
7091 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7092 BPF_MOV64_IMM(BPF_REG_0, 0),
7093 BPF_EXIT_INSN(),
7094 },
7095 .errstr = "R1 offset is outside of the packet",
7096 .result = REJECT,
7097 .prog_type = BPF_PROG_TYPE_XDP,
7098 },
7099 {
7100 "XDP pkt read, pkt_end <= pkt_data', good access",
7101 .insns = {
7102 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7103 offsetof(struct xdp_md, data)),
7104 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7105 offsetof(struct xdp_md, data_end)),
7106 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7107 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7108 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
7109 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
7110 BPF_MOV64_IMM(BPF_REG_0, 0),
7111 BPF_EXIT_INSN(),
7112 },
7113 .result = ACCEPT,
7114 .prog_type = BPF_PROG_TYPE_XDP,
7115 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7116 },
7117 {
7118 "XDP pkt read, pkt_end <= pkt_data', bad access 1",
7119 .insns = {
7120 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7121 offsetof(struct xdp_md, data)),
7122 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7123 offsetof(struct xdp_md, data_end)),
7124 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7125 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7126 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
7127 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
7128 BPF_MOV64_IMM(BPF_REG_0, 0),
7129 BPF_EXIT_INSN(),
7130 },
7131 .errstr = "R1 offset is outside of the packet",
7132 .result = REJECT,
7133 .prog_type = BPF_PROG_TYPE_XDP,
7134 },
7135 {
7136 "XDP pkt read, pkt_end <= pkt_data', bad access 2",
7137 .insns = {
7138 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7139 offsetof(struct xdp_md, data)),
7140 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
7141 offsetof(struct xdp_md, data_end)),
7142 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
7143 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7144 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 0),
7145 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5),
7146 BPF_MOV64_IMM(BPF_REG_0, 0),
7147 BPF_EXIT_INSN(),
7148 },
7149 .errstr = "R1 offset is outside of the packet",
7150 .result = REJECT,
7151 .prog_type = BPF_PROG_TYPE_XDP,
7152 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7153 },
6648}; 7154};
6649 7155
6650static int probe_filter_length(const struct bpf_insn *fp) 7156static int probe_filter_length(const struct bpf_insn *fp)