History

Merge https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf

Daniel Borkmann says: ==================== bpf 2021-12-08 We've added 12 non-merge commits during the last 22 day(s) which contain a total of 29 files changed, 659 insertions(+), 80 deletions(-). The main changes are: 1) Fix an off-by-two error in packet range markings and also add a batch of new tests for coverage of these corner cases, from Maxim Mikityanskiy. 2) Fix a compilation issue on MIPS JIT for R10000 CPUs, from Johan Almbladh. 3) Fix two functional regressions and a build warning related to BTF kfunc for modules, from Kumar Kartikeya Dwivedi. 4) Fix outdated code and docs regarding BPF's migrate_disable() use on non- PREEMPT_RT kernels, from Sebastian Andrzej Siewior. 5) Add missing includes in order to be able to detangle cgroup vs bpf header dependencies, from Jakub Kicinski. 6) Fix regression in BPF sockmap tests caused by missing detachment of progs from sockets when they are removed from the map, from John Fastabend. 7) Fix a missing "no previous prototype" warning in x86 JIT caused by BPF dispatcher, from Björn Töpel. * https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf: bpf: Add selftests to cover packet access corner cases bpf: Fix the off-by-two error in range markings treewide: Add missing includes masked by cgroup -> bpf dependency tools/resolve_btfids: Skip unresolved symbol warning for empty BTF sets bpf: Fix bpf_check_mod_kfunc_call for built-in modules bpf: Make CONFIG_DEBUG_INFO_BTF depend upon CONFIG_BPF_SYSCALL mips, bpf: Fix reference to non-existing Kconfig symbol bpf: Make sure bpf_disable_instrumentation() is safe vs preemption. Documentation/locking/locktypes: Update migrate_disable() bits. bpf, sockmap: Re-evaluate proto ops when psock is removed from sockmap bpf, sockmap: Attach map progs to psock early for feature probes bpf, x86: Fix "no previous prototype" warning ====================

Jakub Kicinski committed 4 years ago

Commit 6efcdad2 parents 2b29cb9 b560b2129 files · +659 −80Browse files

Unified · Split

29 files
  1. Documentation/locking/locktypes.rst +3 −6
  2. arch/mips/net/bpf_jit_comp.h +1 −1
  3. block/fops.c +1 −0
  4. drivers/gpu/drm/drm_gem_shmem_helper.c +1 −0
  5. drivers/gpu/drm/i915/gt/intel_gtt.c +1 −0
  6. drivers/gpu/drm/i915/i915_request.c +1 −0
  7. drivers/gpu/drm/lima/lima_device.c +1 −0
  8. drivers/gpu/drm/msm/msm_gem_shrinker.c +1 −0
  9. drivers/gpu/drm/ttm/ttm_tt.c +1 −0
  10. drivers/net/ethernet/huawei/hinic/hinic_sriov.c +1 −0
  11. drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c +2 −0
  12. drivers/pci/controller/dwc/pci-exynos.c +1 −0
  13. drivers/pci/controller/dwc/pcie-qcom-ep.c +1 −0
  14. drivers/usb/cdns3/host.c +1 −0
  15. include/linux/bpf.h +3 −14
  16. include/linux/btf.h +10 −4
  17. include/linux/cacheinfo.h +0 −1
  18. include/linux/device/driver.h +1 −0
  19. include/linux/filter.h +1 −4
  20. kernel/bpf/btf.c +2 −9
  21. kernel/bpf/verifier.c +1 −1
  22. lib/Kconfig.debug +1 −0
  23. mm/damon/vaddr.c +1 −0
  24. mm/memory_hotplug.c +1 −0
  25. mm/swap_slots.c +1 −0
  26. net/core/skmsg.c +5 −0
  27. net/core/sock_map.c +10 −5
  28. tools/bpf/resolve_btfids/main.c +5 −3
  29. tools/testing/selftests/bpf/verifier/xdp_direct_packet_access.c +600 −32
Documentation/locking/locktypes.rst+3−6
@@ -439,11 +439,9 @@ preemption. The following substitution works on both kernels:: · 438 unmodified lines
439439 spin_lock(&p->lock);
440440 p->count += this_cpu_read(var2);
441441
442−On a non-PREEMPT_RT kernel migrate_disable() maps to preempt_disable()
443−which makes the above code fully equivalent. On a PREEMPT_RT kernel
444442 migrate_disable() ensures that the task is pinned on the current CPU which
445443 in turn guarantees that the per-CPU access to var1 and var2 are staying on
446−the same CPU.
444+the same CPU while the task remains preemptible.
447445
448446 The migrate_disable() substitution is not valid for the following
449447 scenario::
@@ -456,9 +454,8 @@ scenario:: · 6 unmodified lines
456454 p = this_cpu_ptr(&var1);
457455 p->val = func2();
458456
459−While correct on a non-PREEMPT_RT kernel, this breaks on PREEMPT_RT because
460−here migrate_disable() does not protect against reentrancy from a
461−preempting task. A correct substitution for this case is::
457+This breaks because migrate_disable() does not protect against reentrancy from
458+a preempting task. A correct substitution for this case is::
462459
463460 func()
464461 {
arch/mips/net/bpf_jit_comp.h+1−1
@@ -98,7 +98,7 @@ do { \ · 97 unmodified lines
9898 #define emit(...) __emit(__VA_ARGS__)
9999
100100 /* Workaround for R10000 ll/sc errata */
101−#ifdef CONFIG_WAR_R10000
101+#ifdef CONFIG_WAR_R10000_LLSC
102102 #define LLSC_beqz beqzl
103103 #else
104104 #define LLSC_beqz beqz
block/fops.c+1−0
@@ -15,6 +15,7 @@ · 14 unmodified lines
1515 #include <linux/falloc.h>
1616 #include <linux/suspend.h>
1717 #include <linux/fs.h>
18+#include <linux/module.h>
1819 #include "blk.h"
1920
2021 static inline struct inode *bdev_file_inode(struct file *file)
drivers/gpu/drm/drm_gem_shmem_helper.c+1−0
@@ -9,6 +9,7 @@ · 8 unmodified lines
99 #include <linux/shmem_fs.h>
1010 #include <linux/slab.h>
1111 #include <linux/vmalloc.h>
12+#include <linux/module.h>
1213
1314 #ifdef CONFIG_X86
1415 #include <asm/set_memory.h>
drivers/gpu/drm/i915/gt/intel_gtt.c+1−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
66 #include <linux/slab.h> /* fault-inject.h is not standalone! */
77
88 #include <linux/fault-inject.h>
9+#include <linux/sched/mm.h>
910
1011 #include "gem/i915_gem_lmem.h"
1112 #include "i915_trace.h"
drivers/gpu/drm/i915/i915_request.c+1−0
@@ -29,6 +29,7 @@ · 28 unmodified lines
2929 #include <linux/sched.h>
3030 #include <linux/sched/clock.h>
3131 #include <linux/sched/signal.h>
32+#include <linux/sched/mm.h>
3233
3334 #include "gem/i915_gem_context.h"
3435 #include "gt/intel_breadcrumbs.h"
drivers/gpu/drm/lima/lima_device.c+1−0
@@ -4,6 +4,7 @@ · 3 unmodified lines
44 #include <linux/regulator/consumer.h>
55 #include <linux/reset.h>
66 #include <linux/clk.h>
7+#include <linux/slab.h>
78 #include <linux/dma-mapping.h>
89 #include <linux/platform_device.h>
910
drivers/gpu/drm/msm/msm_gem_shrinker.c+1−0
@@ -5,6 +5,7 @@ · 4 unmodified lines
55 */
66
77 #include <linux/vmalloc.h>
8+#include <linux/sched/mm.h>
89
910 #include "msm_drv.h"
1011 #include "msm_gem.h"
drivers/gpu/drm/ttm/ttm_tt.c+1−0
@@ -34,6 +34,7 @@ · 33 unmodified lines
3434 #include <linux/sched.h>
3535 #include <linux/shmem_fs.h>
3636 #include <linux/file.h>
37+#include <linux/module.h>
3738 #include <drm/drm_cache.h>
3839 #include <drm/ttm/ttm_bo_driver.h>
3940
drivers/net/ethernet/huawei/hinic/hinic_sriov.c+1−0
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 #include <linux/interrupt.h>
99 #include <linux/etherdevice.h>
1010 #include <linux/netdevice.h>
11+#include <linux/module.h>
1112
1213 #include "hinic_hw_dev.h"
1314 #include "hinic_dev.h"
drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c+2−0
@@ -5,6 +5,8 @@ · 4 unmodified lines
55 *
66 */
77
8+#include <linux/module.h>
9+
810 #include "otx2_common.h"
911 #include "otx2_ptp.h"
1012
drivers/pci/controller/dwc/pci-exynos.c+1−0
@@ -19,6 +19,7 @@ · 18 unmodified lines
1919 #include <linux/platform_device.h>
2020 #include <linux/phy/phy.h>
2121 #include <linux/regulator/consumer.h>
22+#include <linux/module.h>
2223
2324 #include "pcie-designware.h"
2425
drivers/pci/controller/dwc/pcie-qcom-ep.c+1−0
@@ -18,6 +18,7 @@ · 17 unmodified lines
1818 #include <linux/pm_domain.h>
1919 #include <linux/regmap.h>
2020 #include <linux/reset.h>
21+#include <linux/module.h>
2122
2223 #include "pcie-designware.h"
2324
drivers/usb/cdns3/host.c+1−0
@@ -10,6 +10,7 @@ · 9 unmodified lines
1010 */
1111
1212 #include <linux/platform_device.h>
13+#include <linux/slab.h>
1314 #include "core.h"
1415 #include "drd.h"
1516 #include "host-export.h"
include/linux/bpf.h+3−14
@@ -732,6 +732,7 @@ int bpf_trampoline_unlink_prog(struct bpf_prog *prog, struct bpf_trampoline *tr) · 731 unmodified lines
732732 struct bpf_trampoline *bpf_trampoline_get(u64 key,
733733 struct bpf_attach_target_info *tgt_info);
734734 void bpf_trampoline_put(struct bpf_trampoline *tr);
735+int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs);
735736 #define BPF_DISPATCHER_INIT(_name) { \
736737 .mutex = __MUTEX_INITIALIZER(_name.mutex), \
737738 .func = &_name##_func, \
@@ -1352,28 +1353,16 @@ extern struct mutex bpf_stats_enabled_mutex; · 614 unmodified lines
13521353 * kprobes, tracepoints) to prevent deadlocks on map operations as any of
13531354 * these events can happen inside a region which holds a map bucket lock
13541355 * and can deadlock on it.
1355− *
1356− * Use the preemption safe inc/dec variants on RT because migrate disable
1357− * is preemptible on RT and preemption in the middle of the RMW operation
1358− * might lead to inconsistent state. Use the raw variants for non RT
1359− * kernels as migrate_disable() maps to preempt_disable() so the slightly
1360− * more expensive save operation can be avoided.
13611356 */
13621357 static inline void bpf_disable_instrumentation(void)
13631358 {
13641359 migrate_disable();
1365− if (IS_ENABLED(CONFIG_PREEMPT_RT))
1366− this_cpu_inc(bpf_prog_active);
1367− else
1368− __this_cpu_inc(bpf_prog_active);
1360+ this_cpu_inc(bpf_prog_active);
13691361 }
13701362
13711363 static inline void bpf_enable_instrumentation(void)
13721364 {
1373− if (IS_ENABLED(CONFIG_PREEMPT_RT))
1374− this_cpu_dec(bpf_prog_active);
1375− else
1376− __this_cpu_dec(bpf_prog_active);
1365+ this_cpu_dec(bpf_prog_active);
13771366 migrate_enable();
13781367 }
13791368
include/linux/btf.h+10−4
@@ -245,7 +245,10 @@ struct kfunc_btf_id_set { · 244 unmodified lines
245245 struct module *owner;
246246 };
247247
248−struct kfunc_btf_id_list;
248+struct kfunc_btf_id_list {
249+ struct list_head list;
250+ struct mutex mutex;
251+};
249252
250253 #ifdef CONFIG_DEBUG_INFO_BTF_MODULES
251254 void register_kfunc_btf_id_set(struct kfunc_btf_id_list *l,
@@ -254,6 +257,9 @@ void unregister_kfunc_btf_id_set(struct kfunc_btf_id_list *l, · 2 unmodified lines
254257 struct kfunc_btf_id_set *s);
255258 bool bpf_check_mod_kfunc_call(struct kfunc_btf_id_list *klist, u32 kfunc_id,
256259 struct module *owner);
260+
261+extern struct kfunc_btf_id_list bpf_tcp_ca_kfunc_list;
262+extern struct kfunc_btf_id_list prog_test_kfunc_list;
257263 #else
258264 static inline void register_kfunc_btf_id_set(struct kfunc_btf_id_list *l,
259265 struct kfunc_btf_id_set *s)
@@ -268,13 +274,13 @@ static inline bool bpf_check_mod_kfunc_call(struct kfunc_btf_id_list *klist, · 8 unmodified lines
268274 {
269275 return false;
270276 }
277+
278+static struct kfunc_btf_id_list bpf_tcp_ca_kfunc_list __maybe_unused;
279+static struct kfunc_btf_id_list prog_test_kfunc_list __maybe_unused;
271280 #endif
272281
273282 #define DEFINE_KFUNC_BTF_ID_SET(set, name) \
274283 struct kfunc_btf_id_set name = { LIST_HEAD_INIT(name.list), (set), \
275284 THIS_MODULE }
276285
277−extern struct kfunc_btf_id_list bpf_tcp_ca_kfunc_list;
278−extern struct kfunc_btf_id_list prog_test_kfunc_list;
279−
280286 #endif
include/linux/cacheinfo.h+0−1
@@ -3,7 +3,6 @@ · 2 unmodified lines
33 #define _LINUX_CACHEINFO_H
44
55 #include <linux/bitops.h>
6−#include <linux/cpu.h>
76 #include <linux/cpumask.h>
87 #include <linux/smp.h>
98
include/linux/device/driver.h+1−0
@@ -18,6 +18,7 @@ · 17 unmodified lines
1818 #include <linux/klist.h>
1919 #include <linux/pm.h>
2020 #include <linux/device/bus.h>
21+#include <linux/module.h>
2122
2223 /**
2324 * enum probe_type - device driver probe type to try
include/linux/filter.h+1−4
@@ -6,6 +6,7 @@ · 5 unmodified lines
66 #define __LINUX_FILTER_H__
77
88 #include <linux/atomic.h>
9+#include <linux/bpf.h>
910 #include <linux/refcount.h>
1011 #include <linux/compat.h>
1112 #include <linux/skbuff.h>
@@ -26,7 +27,6 @@ · 14 unmodified lines
2627
2728 #include <asm/byteorder.h>
2829 #include <uapi/linux/filter.h>
29−#include <uapi/linux/bpf.h>
3030
3131 struct sk_buff;
3232 struct sock;
@@ -640,9 +640,6 @@ static __always_inline u32 bpf_prog_run(const struct bpf_prog *prog, const void · 607 unmodified lines
640640 * This uses migrate_disable/enable() explicitly to document that the
641641 * invocation of a BPF program does not require reentrancy protection
642642 * against a BPF program which is invoked from a preempting task.
643− *
644− * For non RT enabled kernels migrate_disable/enable() maps to
645− * preempt_disable/enable(), i.e. it disables also preemption.
646643 */
647644 static inline u32 bpf_prog_run_pin_on_cpu(const struct bpf_prog *prog,
648645 const void *ctx)
kernel/bpf/btf.c+2−9
@@ -6346,11 +6346,6 @@ BTF_ID_LIST_GLOBAL_SINGLE(btf_task_struct_ids, struct, task_struct) · 6345 unmodified lines
63466346
63476347 /* BTF ID set registration API for modules */
63486348
6349−struct kfunc_btf_id_list {
6350− struct list_head list;
6351− struct mutex mutex;
6352−};
6353−
63546349 #ifdef CONFIG_DEBUG_INFO_BTF_MODULES
63556350
63566351 void register_kfunc_btf_id_set(struct kfunc_btf_id_list *l,
@@ -6376,8 +6371,6 @@ bool bpf_check_mod_kfunc_call(struct kfunc_btf_id_list *klist, u32 kfunc_id, · 19 unmodified lines
63766371 {
63776372 struct kfunc_btf_id_set *s;
63786373
6379− if (!owner)
6380− return false;
63816374 mutex_lock(&klist->mutex);
63826375 list_for_each_entry(s, &klist->list, list) {
63836376 if (s->owner == owner && btf_id_set_contains(s->set, kfunc_id)) {
@@ -6389,8 +6382,6 @@ bool bpf_check_mod_kfunc_call(struct kfunc_btf_id_list *klist, u32 kfunc_id, · 5 unmodified lines
63896382 return false;
63906383 }
63916384
6392−#endif
6393−
63946385 #define DEFINE_KFUNC_BTF_ID_LIST(name) \
63956386 struct kfunc_btf_id_list name = { LIST_HEAD_INIT(name.list), \
63966387 __MUTEX_INITIALIZER(name.mutex) }; \
@@ -6398,3 +6389,5 @@ bool bpf_check_mod_kfunc_call(struct kfunc_btf_id_list *klist, u32 kfunc_id, · 1 unmodified line
63986389
63996390 DEFINE_KFUNC_BTF_ID_LIST(bpf_tcp_ca_kfunc_list);
64006391 DEFINE_KFUNC_BTF_ID_LIST(prog_test_kfunc_list);
6392+
6393+#endif
kernel/bpf/verifier.c+1−1
@@ -8422,7 +8422,7 @@ static void find_good_pkt_pointers(struct bpf_verifier_state *vstate, · 8421 unmodified lines
84228422
84238423 new_range = dst_reg->off;
84248424 if (range_right_open)
8425− new_range--;
8425+ new_range++;
84268426
84278427 /* Examples for register markings:
84288428 *
lib/Kconfig.debug+1−0
@@ -316,6 +316,7 @@ config DEBUG_INFO_BTF · 315 unmodified lines
316316 bool "Generate BTF typeinfo"
317317 depends on !DEBUG_INFO_SPLIT && !DEBUG_INFO_REDUCED
318318 depends on !GCC_PLUGIN_RANDSTRUCT || COMPILE_TEST
319+ depends on BPF_SYSCALL
319320 help
320321 Generate deduplicated BTF type information from DWARF debug info.
321322 Turning this on expects presence of pahole tool, which will convert
mm/damon/vaddr.c+1−0
@@ -13,6 +13,7 @@ · 12 unmodified lines
1313 #include <linux/mmu_notifier.h>
1414 #include <linux/page_idle.h>
1515 #include <linux/pagewalk.h>
16+#include <linux/sched/mm.h>
1617
1718 #include "prmtv-common.h"
1819
mm/memory_hotplug.c+1−0
@@ -35,6 +35,7 @@ · 34 unmodified lines
3535 #include <linux/memblock.h>
3636 #include <linux/compaction.h>
3737 #include <linux/rmap.h>
38+#include <linux/module.h>
3839
3940 #include <asm/tlbflush.h>
4041
mm/swap_slots.c+1−0
@@ -30,6 +30,7 @@ · 29 unmodified lines
3030 #include <linux/swap_slots.h>
3131 #include <linux/cpu.h>
3232 #include <linux/cpumask.h>
33+#include <linux/slab.h>
3334 #include <linux/vmalloc.h>
3435 #include <linux/mutex.h>
3536 #include <linux/mm.h>
net/core/skmsg.c+5−0
@@ -1124,6 +1124,8 @@ void sk_psock_start_strp(struct sock *sk, struct sk_psock *psock) · 1123 unmodified lines
11241124
11251125 void sk_psock_stop_strp(struct sock *sk, struct sk_psock *psock)
11261126 {
1127+ psock_set_prog(&psock->progs.stream_parser, NULL);
1128+
11271129 if (!psock->saved_data_ready)
11281130 return;
11291131
@@ -1212,6 +1214,9 @@ void sk_psock_start_verdict(struct sock *sk, struct sk_psock *psock) · 82 unmodified lines
12121214
12131215 void sk_psock_stop_verdict(struct sock *sk, struct sk_psock *psock)
12141216 {
1217+ psock_set_prog(&psock->progs.stream_verdict, NULL);
1218+ psock_set_prog(&psock->progs.skb_verdict, NULL);
1219+
12151220 if (!psock->saved_data_ready)
12161221 return;
12171222
net/core/sock_map.c+10−5
@@ -167,8 +167,11 @@ static void sock_map_del_link(struct sock *sk, · 166 unmodified lines
167167 write_lock_bh(&sk->sk_callback_lock);
168168 if (strp_stop)
169169 sk_psock_stop_strp(sk, psock);
170− else
170+ if (verdict_stop)
171171 sk_psock_stop_verdict(sk, psock);
172+
173+ if (psock->psock_update_sk_prot)
174+ psock->psock_update_sk_prot(sk, psock, false);
172175 write_unlock_bh(&sk->sk_callback_lock);
173176 }
174177 }
@@ -282,6 +285,12 @@ static int sock_map_link(struct bpf_map *map, struct sock *sk) · 107 unmodified lines
282285
283286 if (msg_parser)
284287 psock_set_prog(&psock->progs.msg_parser, msg_parser);
288+ if (stream_parser)
289+ psock_set_prog(&psock->progs.stream_parser, stream_parser);
290+ if (stream_verdict)
291+ psock_set_prog(&psock->progs.stream_verdict, stream_verdict);
292+ if (skb_verdict)
293+ psock_set_prog(&psock->progs.skb_verdict, skb_verdict);
285294
286295 ret = sock_map_init_proto(sk, psock);
287296 if (ret < 0)
@@ -292,14 +301,10 @@ static int sock_map_link(struct bpf_map *map, struct sock *sk) · 4 unmodified lines
292301 ret = sk_psock_init_strp(sk, psock);
293302 if (ret)
294303 goto out_unlock_drop;
295− psock_set_prog(&psock->progs.stream_verdict, stream_verdict);
296− psock_set_prog(&psock->progs.stream_parser, stream_parser);
297304 sk_psock_start_strp(sk, psock);
298305 } else if (!stream_parser && stream_verdict && !psock->saved_data_ready) {
299− psock_set_prog(&psock->progs.stream_verdict, stream_verdict);
300306 sk_psock_start_verdict(sk,psock);
301307 } else if (!stream_verdict && skb_verdict && !psock->saved_data_ready) {
302− psock_set_prog(&psock->progs.skb_verdict, skb_verdict);
303308 sk_psock_start_verdict(sk, psock);
304309 }
305310 write_unlock_bh(&sk->sk_callback_lock);
tools/bpf/resolve_btfids/main.c+5−3
@@ -83,6 +83,7 @@ struct btf_id { · 82 unmodified lines
8383 int cnt;
8484 };
8585 int addr_cnt;
86+ bool is_set;
8687 Elf64_Addr addr[ADDR_CNT];
8788 };
8889
@@ -451,8 +452,10 @@ static int symbols_collect(struct object *obj) · 362 unmodified lines
451452 * in symbol's size, together with 'cnt' field hence
452453 * that - 1.
453454 */
454− if (id)
455+ if (id) {
455456 id->cnt = sym.st_size / sizeof(int) - 1;
457+ id->is_set = true;
458+ }
456459 } else {
457460 pr_err("FAILED unsupported prefix %s\n", prefix);
458461 return -1;
@@ -568,9 +571,8 @@ static int id_patch(struct object *obj, struct btf_id *id) · 109 unmodified lines
568571 int *ptr = data->d_buf;
569572 int i;
570573
571− if (!id->id) {
574+ if (!id->id && !id->is_set)
572575 pr_err("WARN: resolve_btfids: unresolved symbol %s\n", id->name);
573− }
574576
575577 for (i = 0; i < id->addr_cnt; i++) {
576578 unsigned long addr = id->addr[i];
tools/testing/selftests/bpf/verifier/xdp_direct_packet_access.c+600−32
@@ -35,7 +35,7 @@ · 34 unmodified lines
3535 .prog_type = BPF_PROG_TYPE_XDP,
3636 },
3737 {
38− "XDP pkt read, pkt_data' > pkt_end, good access",
38+ "XDP pkt read, pkt_data' > pkt_end, corner case, good access",
3939 .insns = {
4040 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
4141 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
@@ -87,6 +87,41 @@ · 45 unmodified lines
8787 .prog_type = BPF_PROG_TYPE_XDP,
8888 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8989 },
90+{
91+ "XDP pkt read, pkt_data' > pkt_end, corner case +1, good access",
92+ .insns = {
93+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
94+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
95+ offsetof(struct xdp_md, data_end)),
96+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
97+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9),
98+ BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
99+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9),
100+ BPF_MOV64_IMM(BPF_REG_0, 0),
101+ BPF_EXIT_INSN(),
102+ },
103+ .result = ACCEPT,
104+ .prog_type = BPF_PROG_TYPE_XDP,
105+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
106+},
107+{
108+ "XDP pkt read, pkt_data' > pkt_end, corner case -1, bad access",
109+ .insns = {
110+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
111+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
112+ offsetof(struct xdp_md, data_end)),
113+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
114+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
115+ BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
116+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
117+ BPF_MOV64_IMM(BPF_REG_0, 0),
118+ BPF_EXIT_INSN(),
119+ },
120+ .errstr = "R1 offset is outside of the packet",
121+ .result = REJECT,
122+ .prog_type = BPF_PROG_TYPE_XDP,
123+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
124+},
90125 {
91126 "XDP pkt read, pkt_end > pkt_data', good access",
92127 .insns = {
@@ -106,16 +141,16 @@ · 13 unmodified lines
106141 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
107142 },
108143 {
109− "XDP pkt read, pkt_end > pkt_data', bad access 1",
144+ "XDP pkt read, pkt_end > pkt_data', corner case -1, bad access",
110145 .insns = {
111146 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
112147 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
113148 offsetof(struct xdp_md, data_end)),
114149 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
115− BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
150+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
116151 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
117152 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
118− BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
153+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
119154 BPF_MOV64_IMM(BPF_REG_0, 0),
120155 BPF_EXIT_INSN(),
121156 },
@@ -142,6 +177,42 @@ · 20 unmodified lines
142177 .prog_type = BPF_PROG_TYPE_XDP,
143178 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
144179 },
180+{
181+ "XDP pkt read, pkt_end > pkt_data', corner case, good access",
182+ .insns = {
183+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
184+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
185+ offsetof(struct xdp_md, data_end)),
186+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
187+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
188+ BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
189+ BPF_JMP_IMM(BPF_JA, 0, 0, 1),
190+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
191+ BPF_MOV64_IMM(BPF_REG_0, 0),
192+ BPF_EXIT_INSN(),
193+ },
194+ .result = ACCEPT,
195+ .prog_type = BPF_PROG_TYPE_XDP,
196+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
197+},
198+{
199+ "XDP pkt read, pkt_end > pkt_data', corner case +1, good access",
200+ .insns = {
201+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
202+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
203+ offsetof(struct xdp_md, data_end)),
204+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
205+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
206+ BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
207+ BPF_JMP_IMM(BPF_JA, 0, 0, 1),
208+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
209+ BPF_MOV64_IMM(BPF_REG_0, 0),
210+ BPF_EXIT_INSN(),
211+ },
212+ .result = ACCEPT,
213+ .prog_type = BPF_PROG_TYPE_XDP,
214+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
215+},
145216 {
146217 "XDP pkt read, pkt_data' < pkt_end, good access",
147218 .insns = {
@@ -161,16 +232,16 @@ · 13 unmodified lines
161232 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
162233 },
163234 {
164− "XDP pkt read, pkt_data' < pkt_end, bad access 1",
235+ "XDP pkt read, pkt_data' < pkt_end, corner case -1, bad access",
165236 .insns = {
166237 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
167238 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
168239 offsetof(struct xdp_md, data_end)),
169240 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
170− BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
241+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
171242 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
172243 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
173− BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
244+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
174245 BPF_MOV64_IMM(BPF_REG_0, 0),
175246 BPF_EXIT_INSN(),
176247 },
@@ -198,7 +269,43 @@ · 21 unmodified lines
198269 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
199270 },
200271 {
201− "XDP pkt read, pkt_end < pkt_data', good access",
272+ "XDP pkt read, pkt_data' < pkt_end, corner case, good access",
273+ .insns = {
274+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
275+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
276+ offsetof(struct xdp_md, data_end)),
277+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
278+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
279+ BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
280+ BPF_JMP_IMM(BPF_JA, 0, 0, 1),
281+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
282+ BPF_MOV64_IMM(BPF_REG_0, 0),
283+ BPF_EXIT_INSN(),
284+ },
285+ .result = ACCEPT,
286+ .prog_type = BPF_PROG_TYPE_XDP,
287+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
288+},
289+{
290+ "XDP pkt read, pkt_data' < pkt_end, corner case +1, good access",
291+ .insns = {
292+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
293+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
294+ offsetof(struct xdp_md, data_end)),
295+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
296+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
297+ BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
298+ BPF_JMP_IMM(BPF_JA, 0, 0, 1),
299+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
300+ BPF_MOV64_IMM(BPF_REG_0, 0),
301+ BPF_EXIT_INSN(),
302+ },
303+ .result = ACCEPT,
304+ .prog_type = BPF_PROG_TYPE_XDP,
305+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
306+},
307+{
308+ "XDP pkt read, pkt_end < pkt_data', corner case, good access",
202309 .insns = {
203310 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
204311 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
@@ -250,6 +357,41 @@ · 45 unmodified lines
250357 .prog_type = BPF_PROG_TYPE_XDP,
251358 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
252359 },
360+{
361+ "XDP pkt read, pkt_end < pkt_data', corner case +1, good access",
362+ .insns = {
363+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
364+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
365+ offsetof(struct xdp_md, data_end)),
366+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
367+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9),
368+ BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
369+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9),
370+ BPF_MOV64_IMM(BPF_REG_0, 0),
371+ BPF_EXIT_INSN(),
372+ },
373+ .result = ACCEPT,
374+ .prog_type = BPF_PROG_TYPE_XDP,
375+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
376+},
377+{
378+ "XDP pkt read, pkt_end < pkt_data', corner case -1, bad access",
379+ .insns = {
380+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
381+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
382+ offsetof(struct xdp_md, data_end)),
383+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
384+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
385+ BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
386+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
387+ BPF_MOV64_IMM(BPF_REG_0, 0),
388+ BPF_EXIT_INSN(),
389+ },
390+ .errstr = "R1 offset is outside of the packet",
391+ .result = REJECT,
392+ .prog_type = BPF_PROG_TYPE_XDP,
393+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
394+},
253395 {
254396 "XDP pkt read, pkt_data' >= pkt_end, good access",
255397 .insns = {
@@ -268,15 +410,15 @@ · 12 unmodified lines
268410 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
269411 },
270412 {
271− "XDP pkt read, pkt_data' >= pkt_end, bad access 1",
413+ "XDP pkt read, pkt_data' >= pkt_end, corner case -1, bad access",
272414 .insns = {
273415 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
274416 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
275417 offsetof(struct xdp_md, data_end)),
276418 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
277− BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
419+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
278420 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
279− BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
421+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
280422 BPF_MOV64_IMM(BPF_REG_0, 0),
281423 BPF_EXIT_INSN(),
282424 },
@@ -304,7 +446,41 @@ · 21 unmodified lines
304446 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
305447 },
306448 {
307− "XDP pkt read, pkt_end >= pkt_data', good access",
449+ "XDP pkt read, pkt_data' >= pkt_end, corner case, good access",
450+ .insns = {
451+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
452+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
453+ offsetof(struct xdp_md, data_end)),
454+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
455+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
456+ BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
457+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
458+ BPF_MOV64_IMM(BPF_REG_0, 0),
459+ BPF_EXIT_INSN(),
460+ },
461+ .result = ACCEPT,
462+ .prog_type = BPF_PROG_TYPE_XDP,
463+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
464+},
465+{
466+ "XDP pkt read, pkt_data' >= pkt_end, corner case +1, good access",
467+ .insns = {
468+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
469+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
470+ offsetof(struct xdp_md, data_end)),
471+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
472+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
473+ BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
474+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
475+ BPF_MOV64_IMM(BPF_REG_0, 0),
476+ BPF_EXIT_INSN(),
477+ },
478+ .result = ACCEPT,
479+ .prog_type = BPF_PROG_TYPE_XDP,
480+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
481+},
482+{
483+ "XDP pkt read, pkt_end >= pkt_data', corner case, good access",
308484 .insns = {
309485 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
310486 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
@@ -359,7 +535,44 @@ · 48 unmodified lines
359535 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
360536 },
361537 {
362− "XDP pkt read, pkt_data' <= pkt_end, good access",
538+ "XDP pkt read, pkt_end >= pkt_data', corner case +1, good access",
539+ .insns = {
540+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
541+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
542+ offsetof(struct xdp_md, data_end)),
543+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
544+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9),
545+ BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
546+ BPF_JMP_IMM(BPF_JA, 0, 0, 1),
547+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9),
548+ BPF_MOV64_IMM(BPF_REG_0, 0),
549+ BPF_EXIT_INSN(),
550+ },
551+ .result = ACCEPT,
552+ .prog_type = BPF_PROG_TYPE_XDP,
553+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
554+},
555+{
556+ "XDP pkt read, pkt_end >= pkt_data', corner case -1, bad access",
557+ .insns = {
558+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
559+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
560+ offsetof(struct xdp_md, data_end)),
561+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
562+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
563+ BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
564+ BPF_JMP_IMM(BPF_JA, 0, 0, 1),
565+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
566+ BPF_MOV64_IMM(BPF_REG_0, 0),
567+ BPF_EXIT_INSN(),
568+ },
569+ .errstr = "R1 offset is outside of the packet",
570+ .result = REJECT,
571+ .prog_type = BPF_PROG_TYPE_XDP,
572+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
573+},
574+{
575+ "XDP pkt read, pkt_data' <= pkt_end, corner case, good access",
363576 .insns = {
364577 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
365578 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
@@ -413,6 +626,43 @@ · 47 unmodified lines
413626 .prog_type = BPF_PROG_TYPE_XDP,
414627 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
415628 },
629+{
630+ "XDP pkt read, pkt_data' <= pkt_end, corner case +1, good access",
631+ .insns = {
632+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
633+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
634+ offsetof(struct xdp_md, data_end)),
635+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
636+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9),
637+ BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
638+ BPF_JMP_IMM(BPF_JA, 0, 0, 1),
639+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9),
640+ BPF_MOV64_IMM(BPF_REG_0, 0),
641+ BPF_EXIT_INSN(),
642+ },
643+ .result = ACCEPT,
644+ .prog_type = BPF_PROG_TYPE_XDP,
645+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
646+},
647+{
648+ "XDP pkt read, pkt_data' <= pkt_end, corner case -1, bad access",
649+ .insns = {
650+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
651+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
652+ offsetof(struct xdp_md, data_end)),
653+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
654+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
655+ BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
656+ BPF_JMP_IMM(BPF_JA, 0, 0, 1),
657+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
658+ BPF_MOV64_IMM(BPF_REG_0, 0),
659+ BPF_EXIT_INSN(),
660+ },
661+ .errstr = "R1 offset is outside of the packet",
662+ .result = REJECT,
663+ .prog_type = BPF_PROG_TYPE_XDP,
664+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
665+},
416666 {
417667 "XDP pkt read, pkt_end <= pkt_data', good access",
418668 .insns = {
@@ -431,15 +681,15 @@ · 12 unmodified lines
431681 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
432682 },
433683 {
434− "XDP pkt read, pkt_end <= pkt_data', bad access 1",
684+ "XDP pkt read, pkt_end <= pkt_data', corner case -1, bad access",
435685 .insns = {
436686 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
437687 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
438688 offsetof(struct xdp_md, data_end)),
439689 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
440− BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
690+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
441691 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
442− BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
692+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
443693 BPF_MOV64_IMM(BPF_REG_0, 0),
444694 BPF_EXIT_INSN(),
445695 },
@@ -467,7 +717,41 @@ · 21 unmodified lines
467717 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
468718 },
469719 {
470− "XDP pkt read, pkt_meta' > pkt_data, good access",
720+ "XDP pkt read, pkt_end <= pkt_data', corner case, good access",
721+ .insns = {
722+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
723+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
724+ offsetof(struct xdp_md, data_end)),
725+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
726+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
727+ BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
728+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
729+ BPF_MOV64_IMM(BPF_REG_0, 0),
730+ BPF_EXIT_INSN(),
731+ },
732+ .result = ACCEPT,
733+ .prog_type = BPF_PROG_TYPE_XDP,
734+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
735+},
736+{
737+ "XDP pkt read, pkt_end <= pkt_data', corner case +1, good access",
738+ .insns = {
739+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
740+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
741+ offsetof(struct xdp_md, data_end)),
742+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
743+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
744+ BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
745+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
746+ BPF_MOV64_IMM(BPF_REG_0, 0),
747+ BPF_EXIT_INSN(),
748+ },
749+ .result = ACCEPT,
750+ .prog_type = BPF_PROG_TYPE_XDP,
751+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
752+},
753+{
754+ "XDP pkt read, pkt_meta' > pkt_data, corner case, good access",
471755 .insns = {
472756 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
473757 offsetof(struct xdp_md, data_meta)),
@@ -519,6 +803,41 @@ · 45 unmodified lines
519803 .prog_type = BPF_PROG_TYPE_XDP,
520804 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
521805 },
806+{
807+ "XDP pkt read, pkt_meta' > pkt_data, corner case +1, good access",
808+ .insns = {
809+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
810+ offsetof(struct xdp_md, data_meta)),
811+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
812+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
813+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9),
814+ BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
815+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9),
816+ BPF_MOV64_IMM(BPF_REG_0, 0),
817+ BPF_EXIT_INSN(),
818+ },
819+ .result = ACCEPT,
820+ .prog_type = BPF_PROG_TYPE_XDP,
821+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
822+},
823+{
824+ "XDP pkt read, pkt_meta' > pkt_data, corner case -1, bad access",
825+ .insns = {
826+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
827+ offsetof(struct xdp_md, data_meta)),
828+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
829+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
830+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
831+ BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
832+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
833+ BPF_MOV64_IMM(BPF_REG_0, 0),
834+ BPF_EXIT_INSN(),
835+ },
836+ .errstr = "R1 offset is outside of the packet",
837+ .result = REJECT,
838+ .prog_type = BPF_PROG_TYPE_XDP,
839+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
840+},
522841 {
523842 "XDP pkt read, pkt_data > pkt_meta', good access",
524843 .insns = {
@@ -538,16 +857,16 @@ · 13 unmodified lines
538857 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
539858 },
540859 {
541− "XDP pkt read, pkt_data > pkt_meta', bad access 1",
860+ "XDP pkt read, pkt_data > pkt_meta', corner case -1, bad access",
542861 .insns = {
543862 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
544863 offsetof(struct xdp_md, data_meta)),
545864 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
546865 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
547− BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
866+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
548867 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
549868 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
550− BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
869+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
551870 BPF_MOV64_IMM(BPF_REG_0, 0),
552871 BPF_EXIT_INSN(),
553872 },
@@ -574,6 +893,42 @@ · 20 unmodified lines
574893 .prog_type = BPF_PROG_TYPE_XDP,
575894 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
576895 },
896+{
897+ "XDP pkt read, pkt_data > pkt_meta', corner case, good access",
898+ .insns = {
899+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
900+ offsetof(struct xdp_md, data_meta)),
901+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
902+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
903+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
904+ BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
905+ BPF_JMP_IMM(BPF_JA, 0, 0, 1),
906+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
907+ BPF_MOV64_IMM(BPF_REG_0, 0),
908+ BPF_EXIT_INSN(),
909+ },
910+ .result = ACCEPT,
911+ .prog_type = BPF_PROG_TYPE_XDP,
912+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
913+},
914+{
915+ "XDP pkt read, pkt_data > pkt_meta', corner case +1, good access",
916+ .insns = {
917+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
918+ offsetof(struct xdp_md, data_meta)),
919+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
920+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
921+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
922+ BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
923+ BPF_JMP_IMM(BPF_JA, 0, 0, 1),
924+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
925+ BPF_MOV64_IMM(BPF_REG_0, 0),
926+ BPF_EXIT_INSN(),
927+ },
928+ .result = ACCEPT,
929+ .prog_type = BPF_PROG_TYPE_XDP,
930+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
931+},
577932 {
578933 "XDP pkt read, pkt_meta' < pkt_data, good access",
579934 .insns = {
@@ -593,16 +948,16 @@ · 13 unmodified lines
593948 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
594949 },
595950 {
596− "XDP pkt read, pkt_meta' < pkt_data, bad access 1",
951+ "XDP pkt read, pkt_meta' < pkt_data, corner case -1, bad access",
597952 .insns = {
598953 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
599954 offsetof(struct xdp_md, data_meta)),
600955 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
601956 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
602− BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
957+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
603958 BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
604959 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
605− BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
960+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
606961 BPF_MOV64_IMM(BPF_REG_0, 0),
607962 BPF_EXIT_INSN(),
608963 },
@@ -630,7 +985,43 @@ · 21 unmodified lines
630985 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
631986 },
632987 {
633− "XDP pkt read, pkt_data < pkt_meta', good access",
988+ "XDP pkt read, pkt_meta' < pkt_data, corner case, good access",
989+ .insns = {
990+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
991+ offsetof(struct xdp_md, data_meta)),
992+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
993+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
994+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
995+ BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
996+ BPF_JMP_IMM(BPF_JA, 0, 0, 1),
997+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
998+ BPF_MOV64_IMM(BPF_REG_0, 0),
999+ BPF_EXIT_INSN(),
1000+ },
1001+ .result = ACCEPT,
1002+ .prog_type = BPF_PROG_TYPE_XDP,
1003+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
1004+},
1005+{
1006+ "XDP pkt read, pkt_meta' < pkt_data, corner case +1, good access",
1007+ .insns = {
1008+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1009+ offsetof(struct xdp_md, data_meta)),
1010+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
1011+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1012+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
1013+ BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
1014+ BPF_JMP_IMM(BPF_JA, 0, 0, 1),
1015+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
1016+ BPF_MOV64_IMM(BPF_REG_0, 0),
1017+ BPF_EXIT_INSN(),
1018+ },
1019+ .result = ACCEPT,
1020+ .prog_type = BPF_PROG_TYPE_XDP,
1021+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
1022+},
1023+{
1024+ "XDP pkt read, pkt_data < pkt_meta', corner case, good access",
6341025 .insns = {
6351026 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
6361027 offsetof(struct xdp_md, data_meta)),
@@ -682,6 +1073,41 @@ · 45 unmodified lines
6821073 .prog_type = BPF_PROG_TYPE_XDP,
6831074 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
6841075 },
1076+{
1077+ "XDP pkt read, pkt_data < pkt_meta', corner case +1, good access",
1078+ .insns = {
1079+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1080+ offsetof(struct xdp_md, data_meta)),
1081+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
1082+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1083+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9),
1084+ BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
1085+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9),
1086+ BPF_MOV64_IMM(BPF_REG_0, 0),
1087+ BPF_EXIT_INSN(),
1088+ },
1089+ .result = ACCEPT,
1090+ .prog_type = BPF_PROG_TYPE_XDP,
1091+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
1092+},
1093+{
1094+ "XDP pkt read, pkt_data < pkt_meta', corner case -1, bad access",
1095+ .insns = {
1096+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1097+ offsetof(struct xdp_md, data_meta)),
1098+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
1099+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1100+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
1101+ BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
1102+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
1103+ BPF_MOV64_IMM(BPF_REG_0, 0),
1104+ BPF_EXIT_INSN(),
1105+ },
1106+ .errstr = "R1 offset is outside of the packet",
1107+ .result = REJECT,
1108+ .prog_type = BPF_PROG_TYPE_XDP,
1109+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
1110+},
6851111 {
6861112 "XDP pkt read, pkt_meta' >= pkt_data, good access",
6871113 .insns = {
@@ -700,15 +1126,15 @@ · 12 unmodified lines
7001126 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7011127 },
7021128 {
703− "XDP pkt read, pkt_meta' >= pkt_data, bad access 1",
1129+ "XDP pkt read, pkt_meta' >= pkt_data, corner case -1, bad access",
7041130 .insns = {
7051131 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7061132 offsetof(struct xdp_md, data_meta)),
7071133 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
7081134 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
709− BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
1135+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
7101136 BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
711− BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
1137+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
7121138 BPF_MOV64_IMM(BPF_REG_0, 0),
7131139 BPF_EXIT_INSN(),
7141140 },
@@ -736,7 +1162,41 @@ · 21 unmodified lines
7361162 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7371163 },
7381164 {
739− "XDP pkt read, pkt_data >= pkt_meta', good access",
1165+ "XDP pkt read, pkt_meta' >= pkt_data, corner case, good access",
1166+ .insns = {
1167+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1168+ offsetof(struct xdp_md, data_meta)),
1169+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
1170+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1171+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
1172+ BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
1173+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
1174+ BPF_MOV64_IMM(BPF_REG_0, 0),
1175+ BPF_EXIT_INSN(),
1176+ },
1177+ .result = ACCEPT,
1178+ .prog_type = BPF_PROG_TYPE_XDP,
1179+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
1180+},
1181+{
1182+ "XDP pkt read, pkt_meta' >= pkt_data, corner case +1, good access",
1183+ .insns = {
1184+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1185+ offsetof(struct xdp_md, data_meta)),
1186+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
1187+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1188+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
1189+ BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
1190+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
1191+ BPF_MOV64_IMM(BPF_REG_0, 0),
1192+ BPF_EXIT_INSN(),
1193+ },
1194+ .result = ACCEPT,
1195+ .prog_type = BPF_PROG_TYPE_XDP,
1196+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
1197+},
1198+{
1199+ "XDP pkt read, pkt_data >= pkt_meta', corner case, good access",
7401200 .insns = {
7411201 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7421202 offsetof(struct xdp_md, data_meta)),
@@ -791,7 +1251,44 @@ · 48 unmodified lines
7911251 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
7921252 },
7931253 {
794− "XDP pkt read, pkt_meta' <= pkt_data, good access",
1254+ "XDP pkt read, pkt_data >= pkt_meta', corner case +1, good access",
1255+ .insns = {
1256+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1257+ offsetof(struct xdp_md, data_meta)),
1258+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
1259+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1260+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9),
1261+ BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
1262+ BPF_JMP_IMM(BPF_JA, 0, 0, 1),
1263+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9),
1264+ BPF_MOV64_IMM(BPF_REG_0, 0),
1265+ BPF_EXIT_INSN(),
1266+ },
1267+ .result = ACCEPT,
1268+ .prog_type = BPF_PROG_TYPE_XDP,
1269+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
1270+},
1271+{
1272+ "XDP pkt read, pkt_data >= pkt_meta', corner case -1, bad access",
1273+ .insns = {
1274+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1275+ offsetof(struct xdp_md, data_meta)),
1276+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
1277+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1278+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
1279+ BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
1280+ BPF_JMP_IMM(BPF_JA, 0, 0, 1),
1281+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
1282+ BPF_MOV64_IMM(BPF_REG_0, 0),
1283+ BPF_EXIT_INSN(),
1284+ },
1285+ .errstr = "R1 offset is outside of the packet",
1286+ .result = REJECT,
1287+ .prog_type = BPF_PROG_TYPE_XDP,
1288+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
1289+},
1290+{
1291+ "XDP pkt read, pkt_meta' <= pkt_data, corner case, good access",
7951292 .insns = {
7961293 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
7971294 offsetof(struct xdp_md, data_meta)),
@@ -845,6 +1342,43 @@ · 47 unmodified lines
8451342 .prog_type = BPF_PROG_TYPE_XDP,
8461343 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8471344 },
1345+{
1346+ "XDP pkt read, pkt_meta' <= pkt_data, corner case +1, good access",
1347+ .insns = {
1348+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1349+ offsetof(struct xdp_md, data_meta)),
1350+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
1351+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1352+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9),
1353+ BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
1354+ BPF_JMP_IMM(BPF_JA, 0, 0, 1),
1355+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9),
1356+ BPF_MOV64_IMM(BPF_REG_0, 0),
1357+ BPF_EXIT_INSN(),
1358+ },
1359+ .result = ACCEPT,
1360+ .prog_type = BPF_PROG_TYPE_XDP,
1361+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
1362+},
1363+{
1364+ "XDP pkt read, pkt_meta' <= pkt_data, corner case -1, bad access",
1365+ .insns = {
1366+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1367+ offsetof(struct xdp_md, data_meta)),
1368+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
1369+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1370+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
1371+ BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
1372+ BPF_JMP_IMM(BPF_JA, 0, 0, 1),
1373+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
1374+ BPF_MOV64_IMM(BPF_REG_0, 0),
1375+ BPF_EXIT_INSN(),
1376+ },
1377+ .errstr = "R1 offset is outside of the packet",
1378+ .result = REJECT,
1379+ .prog_type = BPF_PROG_TYPE_XDP,
1380+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
1381+},
8481382 {
8491383 "XDP pkt read, pkt_data <= pkt_meta', good access",
8501384 .insns = {
@@ -863,15 +1397,15 @@ · 12 unmodified lines
8631397 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
8641398 },
8651399 {
866− "XDP pkt read, pkt_data <= pkt_meta', bad access 1",
1400+ "XDP pkt read, pkt_data <= pkt_meta', corner case -1, bad access",
8671401 .insns = {
8681402 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
8691403 offsetof(struct xdp_md, data_meta)),
8701404 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
8711405 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
872− BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
1406+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
8731407 BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
874− BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
1408+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
8751409 BPF_MOV64_IMM(BPF_REG_0, 0),
8761410 BPF_EXIT_INSN(),
8771411 },
@@ -898,3 +1432,37 @@ · 20 unmodified lines
8981432 .prog_type = BPF_PROG_TYPE_XDP,
8991433 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
9001434 },
1435+{
1436+ "XDP pkt read, pkt_data <= pkt_meta', corner case, good access",
1437+ .insns = {
1438+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1439+ offsetof(struct xdp_md, data_meta)),
1440+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
1441+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1442+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
1443+ BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
1444+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
1445+ BPF_MOV64_IMM(BPF_REG_0, 0),
1446+ BPF_EXIT_INSN(),
1447+ },
1448+ .result = ACCEPT,
1449+ .prog_type = BPF_PROG_TYPE_XDP,
1450+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
1451+},
1452+{
1453+ "XDP pkt read, pkt_data <= pkt_meta', corner case +1, good access",
1454+ .insns = {
1455+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1456+ offsetof(struct xdp_md, data_meta)),
1457+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
1458+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1459+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
1460+ BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
1461+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
1462+ BPF_MOV64_IMM(BPF_REG_0, 0),
1463+ BPF_EXIT_INSN(),
1464+ },
1465+ .result = ACCEPT,
1466+ .prog_type = BPF_PROG_TYPE_XDP,
1467+ .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
1468+},