diff options
| author | Kumar Kartikeya Dwivedi <memxor@gmail.com> | 2026-09-18 01:32:11 +0200 |
|---|---|---|
| committer | Eduard Zingerman <eddyz87@gmail.com> | 2026-09-17 18:01:42 -0700 |
| commit | 2059d9af54f0d66deb237aa75d2ed28648df05a1 (patch) | |
| tree | 830cfc25197575c31a487b5759b4fcf4795f00eb /tools/testing/selftests/bpf/progs | |
| parent | fd16449a9b3b31a8f18944c2f0e29e4e218ca2cf (diff) | |
selftests/bpf: Test packet pointer class displacement pruning
Add two paths whose packet pointer ranges are individually compatible at
a join but whose members have different relative displacements. The first
path proves an eight-byte access through one member. On the second path,
the same guard only proves that the access starts before data_end.
An affected verifier prunes the second path and accepts the program. With
packet pointer class displacement preserved, it explores that path and
rejects the out-of-bounds access.
Read the unknown offset and branch selector directly from XDP context
fields, and force state checkpoints so the pruning attempt does not
depend on the verifier checkpoint heuristics.
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://patch.msgid.link/20260917233222.2542500-4-memxor@gmail.com
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Diffstat (limited to 'tools/testing/selftests/bpf/progs')
| -rw-r--r-- | tools/testing/selftests/bpf/progs/verifier_xdp_direct_packet_access.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/tools/testing/selftests/bpf/progs/verifier_xdp_direct_packet_access.c b/tools/testing/selftests/bpf/progs/verifier_xdp_direct_packet_access.c index 0b86d95a4133..9866bc154194 100644 --- a/tools/testing/selftests/bpf/progs/verifier_xdp_direct_packet_access.c +++ b/tools/testing/selftests/bpf/progs/verifier_xdp_direct_packet_access.c @@ -1719,4 +1719,39 @@ l0_%=: r0 = 0; \ : __clobber_all); } +SEC("xdp") +__description("XDP pkt regsafe preserves packet pointer class displacement") +__failure __msg("R2 min value is outside of the allowed memory range") +__flag(BPF_F_ANY_ALIGNMENT) __flag(BPF_F_TEST_STATE_FREQ) +__naked void pkt_regsafe_class_displacement(void) +{ + asm volatile (" \ + r8 = *(u32 *)(r1 + %[xdp_md_data_end]); \ + r9 = *(u32 *)(r1 + %[xdp_md_data]); \ + r4 = *(u32 *)(r1 + %[xdp_md_rx_queue_index]); \ + r4 &= 15; \ + r0 = *(u32 *)(r1 + %[xdp_md_ingress_ifindex]); \ + if r0 != 0 goto l0_%=; \ + r2 = r9; \ + r2 += r4; \ + r3 = r2; \ + r3 += 8; \ + goto l1_%=; \ +l0_%=: r4 &= 3; \ + r4 += 8; \ + r2 = r9; \ + r2 += r4; \ + r3 = r2; \ +l1_%=: if r3 > r8 goto l2_%=; \ + r0 = *(u64 *)(r2 + 0); \ +l2_%=: r0 = 0; \ + exit; \ +" : + : __imm_const(xdp_md_data, offsetof(struct xdp_md, data)), + __imm_const(xdp_md_data_end, offsetof(struct xdp_md, data_end)), + __imm_const(xdp_md_rx_queue_index, offsetof(struct xdp_md, rx_queue_index)), + __imm_const(xdp_md_ingress_ifindex, offsetof(struct xdp_md, ingress_ifindex)) + : __clobber_all); +} + char _license[] SEC("license") = "GPL"; |
