Skip to content

Commit bc3eeb4

Browse files
pchaignoMartin KaFai Lau
authored andcommitted
selftests/bpf: Test direct packet access on non-linear skbs
This patch adds new selftests in the direct packet access suite, to cover the non-linear case. The first six tests cover the behavior of the bounds check with a non-linear skb. The last test adds a call to bpf_skb_pull_data() to be able to access the packet. Note that the size of the linear area includes the L2 header, but for some program types like cgroup_skb, ctx->data points to the L3 header. Therefore, a linear area of 22 bytes will have only 8 bytes accessible to the BPF program (22 - ETH_HLEN). For that reason, the cgroup_skb test cases access the packet at an offset of 8 bytes. Signed-off-by: Paul Chaignon <[email protected]> Signed-off-by: Martin KaFai Lau <[email protected]> Link: https://patch.msgid.link/ceedbfd719e58f0d49dcceb8592f5e6bd38ce5fe.1760037899.git.paul.chaignon@gmail.com
1 parent 8d45d03 commit bc3eeb4

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

tools/testing/selftests/bpf/progs/verifier_direct_packet_access.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -801,4 +801,62 @@ l0_%=: /* exit(0) */ \
801801
: __clobber_all);
802802
}
803803

804+
#define access_test_non_linear(name, type, desc, retval, linear_sz, off) \
805+
SEC(type) \
806+
__description("direct packet access: " #name " (non-linear, " type ", " desc ")") \
807+
__success __retval(retval) \
808+
__linear_size(linear_sz) \
809+
__naked void access_non_linear_##name(void) \
810+
{ \
811+
asm volatile (" \
812+
r2 = *(u32*)(r1 + %[skb_data]); \
813+
r3 = *(u32*)(r1 + %[skb_data_end]); \
814+
r0 = r2; \
815+
r0 += %[offset]; \
816+
if r0 > r3 goto l0_%=; \
817+
r0 = *(u8*)(r0 - 1); \
818+
r0 = 0; \
819+
exit; \
820+
l0_%=: r0 = 1; \
821+
exit; \
822+
" : \
823+
: __imm_const(skb_data, offsetof(struct __sk_buff, data)), \
824+
__imm_const(skb_data_end, offsetof(struct __sk_buff, data_end)), \
825+
__imm_const(offset, off) \
826+
: __clobber_all); \
827+
}
828+
829+
access_test_non_linear(test31, "tc", "too short eth", 1, ETH_HLEN, 22);
830+
access_test_non_linear(test32, "tc", "too short 1", 1, 1, 22);
831+
access_test_non_linear(test33, "tc", "long enough", 0, 22, 22);
832+
access_test_non_linear(test34, "cgroup_skb/ingress", "too short eth", 1, ETH_HLEN, 8);
833+
access_test_non_linear(test35, "cgroup_skb/ingress", "too short 1", 1, 1, 8);
834+
access_test_non_linear(test36, "cgroup_skb/ingress", "long enough", 0, 22, 8);
835+
836+
SEC("tc")
837+
__description("direct packet access: test37 (non-linear, linearized)")
838+
__success __retval(0)
839+
__linear_size(ETH_HLEN)
840+
__naked void access_non_linear_linearized(void)
841+
{
842+
asm volatile (" \
843+
r6 = r1; \
844+
r2 = 22; \
845+
call %[bpf_skb_pull_data]; \
846+
r2 = *(u32*)(r6 + %[skb_data]); \
847+
r3 = *(u32*)(r6 + %[skb_data_end]); \
848+
r0 = r2; \
849+
r0 += 22; \
850+
if r0 > r3 goto l0_%=; \
851+
r0 = *(u8*)(r0 - 1); \
852+
exit; \
853+
l0_%=: r0 = 1; \
854+
exit; \
855+
" :
856+
: __imm(bpf_skb_pull_data),
857+
__imm_const(skb_data, offsetof(struct __sk_buff, data)),
858+
__imm_const(skb_data_end, offsetof(struct __sk_buff, data_end))
859+
: __clobber_all);
860+
}
861+
804862
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)