11590Srgrimes// SPDX-License-Identifier: GPL-2.0
21590Srgrimes/* Converted from tools/testing/selftests/bpf/verifier/raw_stack.c */
31590Srgrimes
41590Srgrimes#include <linux/bpf.h>
51590Srgrimes#include <bpf/bpf_helpers.h>
61590Srgrimes#include "bpf_misc.h"
71590Srgrimes
81590SrgrimesSEC("socket")
91590Srgrimes__description("raw_stack: no skb_load_bytes")
101590Srgrimes__success
111590Srgrimes__failure_unpriv __msg_unpriv("invalid read from stack R6 off=-8 size=8")
121590Srgrimes__naked void stack_no_skb_load_bytes(void)
131590Srgrimes{
141590Srgrimes	asm volatile ("					\
151590Srgrimes	r2 = 4;						\
161590Srgrimes	r6 = r10;					\
171590Srgrimes	r6 += -8;					\
181590Srgrimes	r3 = r6;					\
191590Srgrimes	r4 = 8;						\
201590Srgrimes	/* Call to skb_load_bytes() omitted. */		\
211590Srgrimes	r0 = *(u64*)(r6 + 0);				\
221590Srgrimes	exit;						\
231590Srgrimes"	::: __clobber_all);
241590Srgrimes}
251590Srgrimes
261590SrgrimesSEC("tc")
271590Srgrimes__description("raw_stack: skb_load_bytes, negative len")
281590Srgrimes__failure __msg("R4 min value is negative")
291590Srgrimes__naked void skb_load_bytes_negative_len(void)
3087687Smarkm{
3187687Smarkm	asm volatile ("					\
3287687Smarkm	r2 = 4;						\
3387687Smarkm	r6 = r10;					\
341590Srgrimes	r6 += -8;					\
3528855Scharnier	r3 = r6;					\
361590Srgrimes	r4 = -8;					\
371590Srgrimes	call %[bpf_skb_load_bytes];			\
3887687Smarkm	r0 = *(u64*)(r6 + 0);				\
391590Srgrimes	exit;						\
401590Srgrimes"	:
4187687Smarkm	: __imm(bpf_skb_load_bytes)
4228855Scharnier	: __clobber_all);
431590Srgrimes}
441590Srgrimes
4587687SmarkmSEC("tc")
4628855Scharnier__description("raw_stack: skb_load_bytes, negative len 2")
4728855Scharnier__failure __msg("R4 min value is negative")
4828855Scharnier__naked void load_bytes_negative_len_2(void)
4928855Scharnier{
501590Srgrimes	asm volatile ("					\
5128855Scharnier	r2 = 4;						\
521590Srgrimes	r6 = r10;					\
5387687Smarkm	r6 += -8;					\
541590Srgrimes	r3 = r6;					\
551590Srgrimes	r4 = %[__imm_0];				\
561590Srgrimes	call %[bpf_skb_load_bytes];			\
571590Srgrimes	r0 = *(u64*)(r6 + 0);				\
581590Srgrimes	exit;						\
591590Srgrimes"	:
601590Srgrimes	: __imm(bpf_skb_load_bytes),
611590Srgrimes	  __imm_const(__imm_0, ~0)
621590Srgrimes	: __clobber_all);
631590Srgrimes}
641590Srgrimes
65227247SedSEC("tc")
661590Srgrimes__description("raw_stack: skb_load_bytes, zero len")
67227247Sed__failure __msg("R4 invalid zero-sized read: u64=[0,0]")
68227247Sed__naked void skb_load_bytes_zero_len(void)
69227247Sed{
701590Srgrimes	asm volatile ("					\
71227247Sed	r2 = 4;						\
72227247Sed	r6 = r10;					\
73227247Sed	r6 += -8;					\
741590Srgrimes	r3 = r6;					\
75227247Sed	r4 = 0;						\
7687687Smarkm	call %[bpf_skb_load_bytes];			\
77227247Sed	r0 = *(u64*)(r6 + 0);				\
78227247Sed	exit;						\
79227247Sed"	:
80227247Sed	: __imm(bpf_skb_load_bytes)
8128855Scharnier	: __clobber_all);
82227247Sed}
83227247Sed
8487687SmarkmSEC("tc")
8592922Simp__description("raw_stack: skb_load_bytes, no init")
8687687Smarkm__success __retval(0)
87227247Sed__naked void skb_load_bytes_no_init(void)
88227247Sed{
89227247Sed	asm volatile ("					\
90227247Sed	r2 = 4;						\
91227247Sed	r6 = r10;					\
92227247Sed	r6 += -8;					\
93227247Sed	r3 = r6;					\
9487687Smarkm	r4 = 8;						\
9528855Scharnier	call %[bpf_skb_load_bytes];			\
96102944Sdwmalone	r0 = *(u64*)(r6 + 0);				\
971590Srgrimes	exit;						\
9828855Scharnier"	:
99178973Skevlo	: __imm(bpf_skb_load_bytes)
1001590Srgrimes	: __clobber_all);
10128855Scharnier}
10228855Scharnier
10328855ScharnierSEC("tc")
1041590Srgrimes__description("raw_stack: skb_load_bytes, init")
10528855Scharnier__success __retval(0)
1061590Srgrimes__naked void stack_skb_load_bytes_init(void)
1071590Srgrimes{
10828855Scharnier	asm volatile ("					\
1091590Srgrimes	r2 = 4;						\
1101590Srgrimes	r6 = r10;					\
11128855Scharnier	r6 += -8;					\
1121590Srgrimes	r3 = 0xcafe;					\
11328855Scharnier	*(u64*)(r6 + 0) = r3;				\
11428855Scharnier	r3 = r6;					\
11528855Scharnier	r4 = 8;						\
11628855Scharnier	call %[bpf_skb_load_bytes];			\
11728855Scharnier	r0 = *(u64*)(r6 + 0);				\
1181590Srgrimes	exit;						\
1191590Srgrimes"	:
12028855Scharnier	: __imm(bpf_skb_load_bytes)
1211590Srgrimes	: __clobber_all);
122178973Skevlo}
123178973Skevlo
124178973SkevloSEC("tc")
125178973Skevlo__description("raw_stack: skb_load_bytes, spilled regs around bounds")
126178973Skevlo__success __retval(0)
127178973Skevlo__naked void bytes_spilled_regs_around_bounds(void)
128178973Skevlo{
129178973Skevlo	asm volatile ("					\
130178973Skevlo	r2 = 4;						\
131178973Skevlo	r6 = r10;					\
1321590Srgrimes	r6 += -16;					\
1331590Srgrimes	*(u64*)(r6 - 8) = r1;				\
13428855Scharnier	*(u64*)(r6 + 8) = r1;				\
1351590Srgrimes	r3 = r6;					\
13628855Scharnier	r4 = 8;						\
1371590Srgrimes	call %[bpf_skb_load_bytes];			\
1381590Srgrimes	r0 = *(u64*)(r6 - 8);				\
1391590Srgrimes	r2 = *(u64*)(r6 + 8);				\
1401590Srgrimes	r0 = *(u32*)(r0 + %[__sk_buff_mark]);		\
1411590Srgrimes	r2 = *(u32*)(r2 + %[__sk_buff_priority]);	\
1421590Srgrimes	r0 += r2;					\
1431590Srgrimes	exit;						\
1441590Srgrimes"	:
1451590Srgrimes	: __imm(bpf_skb_load_bytes),
1461590Srgrimes	  __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark)),
1471590Srgrimes	  __imm_const(__sk_buff_priority, offsetof(struct __sk_buff, priority))
1481590Srgrimes	: __clobber_all);
1491590Srgrimes}
1501590Srgrimes
15128855ScharnierSEC("tc")
152102944Sdwmalone__description("raw_stack: skb_load_bytes, spilled regs corruption")
15328855Scharnier__failure __msg("R0 invalid mem access 'scalar'")
154146467Sru__flag(BPF_F_ANY_ALIGNMENT)
15528855Scharnier__naked void load_bytes_spilled_regs_corruption(void)
15628855Scharnier{
15728855Scharnier	asm volatile ("					\
158227247Sed	r2 = 4;						\
1591590Srgrimes	r6 = r10;					\
160227247Sed	r6 += -8;					\
161102944Sdwmalone	*(u64*)(r6 + 0) = r1;				\
1621590Srgrimes	r3 = r6;					\
1631590Srgrimes	r4 = 8;						\
16487687Smarkm	call %[bpf_skb_load_bytes];			\
16587687Smarkm	r0 = *(u64*)(r6 + 0);				\
1661590Srgrimes	r0 = *(u32*)(r0 + %[__sk_buff_mark]);		\
1671590Srgrimes	exit;						\
1681590Srgrimes"	:
1691590Srgrimes	: __imm(bpf_skb_load_bytes),
1701590Srgrimes	  __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark))
17128855Scharnier	: __clobber_all);
17228855Scharnier}
1731590Srgrimes
1741590SrgrimesSEC("tc")
1751590Srgrimes__description("raw_stack: skb_load_bytes, spilled regs corruption 2")
1761590Srgrimes__failure __msg("R3 invalid mem access 'scalar'")
1771590Srgrimes__flag(BPF_F_ANY_ALIGNMENT)
1781590Srgrimes__naked void bytes_spilled_regs_corruption_2(void)
1791590Srgrimes{
1801590Srgrimes	asm volatile ("					\
1811590Srgrimes	r2 = 4;						\
18228855Scharnier	r6 = r10;					\
1838874Srgrimes	r6 += -16;					\
1841590Srgrimes	*(u64*)(r6 - 8) = r1;				\
1851590Srgrimes	*(u64*)(r6 + 0) = r1;				\
1861590Srgrimes	*(u64*)(r6 + 8) = r1;				\
1871590Srgrimes	r3 = r6;					\
1881590Srgrimes	r4 = 8;						\
1891590Srgrimes	call %[bpf_skb_load_bytes];			\
1901590Srgrimes	r0 = *(u64*)(r6 - 8);				\
1911590Srgrimes	r2 = *(u64*)(r6 + 8);				\
1921590Srgrimes	r3 = *(u64*)(r6 + 0);				\
1931590Srgrimes	r0 = *(u32*)(r0 + %[__sk_buff_mark]);		\
1941590Srgrimes	r2 = *(u32*)(r2 + %[__sk_buff_priority]);	\
1951590Srgrimes	r0 += r2;					\
1961590Srgrimes	r3 = *(u32*)(r3 + %[__sk_buff_pkt_type]);	\
1971590Srgrimes	r0 += r3;					\
1981590Srgrimes	exit;						\
1991590Srgrimes"	:
2001590Srgrimes	: __imm(bpf_skb_load_bytes),
2011590Srgrimes	  __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark)),
2021590Srgrimes	  __imm_const(__sk_buff_pkt_type, offsetof(struct __sk_buff, pkt_type)),
2031590Srgrimes	  __imm_const(__sk_buff_priority, offsetof(struct __sk_buff, priority))
2041590Srgrimes	: __clobber_all);
2051590Srgrimes}
2061590Srgrimes
2071590SrgrimesSEC("tc")
2081590Srgrimes__description("raw_stack: skb_load_bytes, spilled regs + data")
2091590Srgrimes__success __retval(0)
2101590Srgrimes__naked void load_bytes_spilled_regs_data(void)
2111590Srgrimes{
2121590Srgrimes	asm volatile ("					\
2131590Srgrimes	r2 = 4;						\
2141590Srgrimes	r6 = r10;					\
2151590Srgrimes	r6 += -16;					\
2168874Srgrimes	*(u64*)(r6 - 8) = r1;				\
2171590Srgrimes	*(u64*)(r6 + 0) = r1;				\
2181590Srgrimes	*(u64*)(r6 + 8) = r1;				\
2191590Srgrimes	r3 = r6;					\
2201590Srgrimes	r4 = 8;						\
2211590Srgrimes	call %[bpf_skb_load_bytes];			\
2221590Srgrimes	r0 = *(u64*)(r6 - 8);				\
2231590Srgrimes	r2 = *(u64*)(r6 + 8);				\
2241590Srgrimes	r3 = *(u64*)(r6 + 0);				\
22587687Smarkm	r0 = *(u32*)(r0 + %[__sk_buff_mark]);		\
2261590Srgrimes	r2 = *(u32*)(r2 + %[__sk_buff_priority]);	\
2271590Srgrimes	r0 += r2;					\
228227247Sed	r0 += r3;					\
229102944Sdwmalone	exit;						\
2301590Srgrimes"	:
23187687Smarkm	: __imm(bpf_skb_load_bytes),
23287687Smarkm	  __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark)),
2331590Srgrimes	  __imm_const(__sk_buff_priority, offsetof(struct __sk_buff, priority))
23487687Smarkm	: __clobber_all);
23587687Smarkm}
23687687Smarkm
2371590SrgrimesSEC("tc")
23828855Scharnier__description("raw_stack: skb_load_bytes, invalid access 1")
239106296Stjr__failure __msg("invalid indirect access to stack R3 off=-513 size=8")
240106296Stjr__naked void load_bytes_invalid_access_1(void)
2411590Srgrimes{
2421590Srgrimes	asm volatile ("					\
2431590Srgrimes	r2 = 4;						\
2441590Srgrimes	r6 = r10;					\
2451590Srgrimes	r6 += -513;					\
2461590Srgrimes	r3 = r6;					\
2471590Srgrimes	r4 = 8;						\
2481590Srgrimes	call %[bpf_skb_load_bytes];			\
2491590Srgrimes	r0 = *(u64*)(r6 + 0);				\
2501590Srgrimes	exit;						\
2511590Srgrimes"	:
2528874Srgrimes	: __imm(bpf_skb_load_bytes)
2531590Srgrimes	: __clobber_all);
25428855Scharnier}
25528855Scharnier
2561590SrgrimesSEC("tc")
2571590Srgrimes__description("raw_stack: skb_load_bytes, invalid access 2")
2581590Srgrimes__failure __msg("invalid indirect access to stack R3 off=-1 size=8")
2591590Srgrimes__naked void load_bytes_invalid_access_2(void)
2601590Srgrimes{
26187687Smarkm	asm volatile ("					\
2621590Srgrimes	r2 = 4;						\
2631590Srgrimes	r6 = r10;					\
2641590Srgrimes	r6 += -1;					\
2651590Srgrimes	r3 = r6;					\
2661590Srgrimes	r4 = 8;						\
2671590Srgrimes	call %[bpf_skb_load_bytes];			\
2681590Srgrimes	r0 = *(u64*)(r6 + 0);				\
2691590Srgrimes	exit;						\
2701590Srgrimes"	:
2711590Srgrimes	: __imm(bpf_skb_load_bytes)
2721590Srgrimes	: __clobber_all);
2731590Srgrimes}
2741590Srgrimes
2751590SrgrimesSEC("tc")
2761590Srgrimes__description("raw_stack: skb_load_bytes, invalid access 3")
2771590Srgrimes__failure __msg("R4 min value is negative")
2781590Srgrimes__naked void load_bytes_invalid_access_3(void)
2791590Srgrimes{
2801590Srgrimes	asm volatile ("					\
2811590Srgrimes	r2 = 4;						\
2821590Srgrimes	r6 = r10;					\
2831590Srgrimes	r6 += 0xffffffff;				\
2841590Srgrimes	r3 = r6;					\
2851590Srgrimes	r4 = 0xffffffff;				\
2861590Srgrimes	call %[bpf_skb_load_bytes];			\
2871590Srgrimes	r0 = *(u64*)(r6 + 0);				\
288227247Sed	exit;						\
289102944Sdwmalone"	:
2901590Srgrimes	: __imm(bpf_skb_load_bytes)
2911590Srgrimes	: __clobber_all);
2921590Srgrimes}
2931590Srgrimes
294227247SedSEC("tc")
295102944Sdwmalone__description("raw_stack: skb_load_bytes, invalid access 4")
2961590Srgrimes__failure
2971590Srgrimes__msg("R4 unbounded memory access, use 'var &= const' or 'if (var < const)'")
29887687Smarkm__naked void load_bytes_invalid_access_4(void)
2991590Srgrimes{
3001590Srgrimes	asm volatile ("					\
3011590Srgrimes	r2 = 4;						\
3021590Srgrimes	r6 = r10;					\
3031590Srgrimes	r6 += -1;					\
30428855Scharnier	r3 = r6;					\
3051590Srgrimes	r4 = 0x7fffffff;				\
3061590Srgrimes	call %[bpf_skb_load_bytes];			\
3071590Srgrimes	r0 = *(u64*)(r6 + 0);				\
3081590Srgrimes	exit;						\
3091590Srgrimes"	:
3101590Srgrimes	: __imm(bpf_skb_load_bytes)
311227247Sed	: __clobber_all);
312102944Sdwmalone}
3131590Srgrimes
31487687SmarkmSEC("tc")
31587687Smarkm__description("raw_stack: skb_load_bytes, invalid access 5")
3161590Srgrimes__failure
3171590Srgrimes__msg("R4 unbounded memory access, use 'var &= const' or 'if (var < const)'")
3181590Srgrimes__naked void load_bytes_invalid_access_5(void)
3191590Srgrimes{
32028855Scharnier	asm volatile ("					\
3211590Srgrimes	r2 = 4;						\
3221590Srgrimes	r6 = r10;					\
323227247Sed	r6 += -512;					\
324102944Sdwmalone	r3 = r6;					\
3251590Srgrimes	r4 = 0x7fffffff;				\
3261590Srgrimes	call %[bpf_skb_load_bytes];			\
3271590Srgrimes	r0 = *(u64*)(r6 + 0);				\
3281590Srgrimes	exit;						\
3291590Srgrimes"	:
3301590Srgrimes	: __imm(bpf_skb_load_bytes)
3311590Srgrimes	: __clobber_all);
3321590Srgrimes}
333227247Sed
3341590SrgrimesSEC("tc")
3351590Srgrimes__description("raw_stack: skb_load_bytes, invalid access 6")
3361590Srgrimes__failure __msg("invalid zero-sized read")
3371590Srgrimes__naked void load_bytes_invalid_access_6(void)
3381590Srgrimes{
3391590Srgrimes	asm volatile ("					\
340227247Sed	r2 = 4;						\
341102944Sdwmalone	r6 = r10;					\
3421590Srgrimes	r6 += -512;					\
3431590Srgrimes	r3 = r6;					\
34487687Smarkm	r4 = 0;						\
3451590Srgrimes	call %[bpf_skb_load_bytes];			\
3461590Srgrimes	r0 = *(u64*)(r6 + 0);				\
3471590Srgrimes	exit;						\
3481590Srgrimes"	:
3491590Srgrimes	: __imm(bpf_skb_load_bytes)
3501590Srgrimes	: __clobber_all);
3511590Srgrimes}
3521590Srgrimes
35328855ScharnierSEC("tc")
35428855Scharnier__description("raw_stack: skb_load_bytes, large access")
3551590Srgrimes__success __retval(0)
35628855Scharnier__naked void skb_load_bytes_large_access(void)
35728855Scharnier{
3581590Srgrimes	asm volatile ("					\
3591590Srgrimes	r2 = 4;						\
3601590Srgrimes	r6 = r10;					\
3611590Srgrimes	r6 += -512;					\
3621590Srgrimes	r3 = r6;					\
3631590Srgrimes	r4 = 512;					\
3641590Srgrimes	call %[bpf_skb_load_bytes];			\
365227247Sed	r0 = *(u64*)(r6 + 0);				\
366102944Sdwmalone	exit;						\
3671590Srgrimes"	:
36887687Smarkm	: __imm(bpf_skb_load_bytes)
36987687Smarkm	: __clobber_all);
37087687Smarkm}
37187687Smarkm
3721590Srgrimeschar _license[] SEC("license") = "GPL";
3731590Srgrimes