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