1 // SPDX-License-Identifier: GPL-2.0 2 /* Bounds checks for PTR_TO_FLOW_KEYS pointer arithmetic. */ 3 4 #include "vmlinux.h" 5 #include <bpf/bpf_helpers.h> 6 #include "bpf_misc.h" 7 8 /* sizeof(struct bpf_flow_keys) is well under 4096, so +0x1000 is OOB. */ 9 10 SEC("flow_dissector") 11 __description("flow_keys: in-bounds constant pointer arithmetic accepted") 12 __success 13 __naked void flow_keys_const_inbounds(void) 14 { 15 asm volatile (" \ 16 r1 = *(u64 *)(r1 + %[flow_keys]); \ 17 r1 += 8; \ 18 r0 = *(u64 *)(r1 + 0); \ 19 r0 = 0; \ 20 exit; \ 21 " : 22 : __imm_const(flow_keys, offsetof(struct __sk_buff, flow_keys)) 23 : __clobber_all); 24 } 25 26 SEC("flow_dissector") 27 __description("flow_keys: OOB via constant pointer arithmetic rejected") 28 __failure __msg("invalid access to flow keys off=4096 size=8") 29 __naked void flow_keys_const_oob_read(void) 30 { 31 asm volatile (" \ 32 r1 = *(u64 *)(r1 + %[flow_keys]); \ 33 r1 += 4096; \ 34 r0 = *(u64 *)(r1 + 0); \ 35 r0 = 0; \ 36 exit; \ 37 " : 38 : __imm_const(flow_keys, offsetof(struct __sk_buff, flow_keys)) 39 : __clobber_all); 40 } 41 42 SEC("flow_dissector") 43 __description("flow_keys: OOB write via constant pointer arithmetic rejected") 44 __failure __msg("invalid access to flow keys off=4096 size=8") 45 __naked void flow_keys_const_oob_write(void) 46 { 47 asm volatile (" \ 48 r1 = *(u64 *)(r1 + %[flow_keys]); \ 49 r1 += 4096; \ 50 r2 = 0; \ 51 *(u64 *)(r1 + 0) = r2; \ 52 r0 = 0; \ 53 exit; \ 54 " : 55 : __imm_const(flow_keys, offsetof(struct __sk_buff, flow_keys)) 56 : __clobber_all); 57 } 58 59 /* Equivalent OOB expressed directly in insn->off; this form was always 60 * rejected and is kept to show both forms now share one diagnostic. 61 */ 62 SEC("flow_dissector") 63 __description("flow_keys: OOB via insn->off rejected") 64 __failure __msg("invalid access to flow keys off=4096 size=8") 65 __naked void flow_keys_insn_off_oob(void) 66 { 67 asm volatile (" \ 68 r1 = *(u64 *)(r1 + %[flow_keys]); \ 69 r0 = *(u64 *)(r1 + 4096); \ 70 r0 = 0; \ 71 exit; \ 72 " : 73 : __imm_const(flow_keys, offsetof(struct __sk_buff, flow_keys)) 74 : __clobber_all); 75 } 76 77 SEC("flow_dissector") 78 __description("flow_keys: variable pointer arithmetic rejected") 79 __failure __msg("R1 pointer arithmetic on flow_keys prohibited") 80 __naked void flow_keys_var_read(void) 81 { 82 asm volatile (" \ 83 r6 = r1; \ 84 call %[bpf_get_prandom_u32]; \ 85 r0 &= 0xFFFF; \ 86 r1 = *(u64 *)(r6 + %[flow_keys]); \ 87 r1 += r0; \ 88 r0 = *(u64 *)(r1 + 0); \ 89 r0 = 0; \ 90 exit; \ 91 " : 92 : __imm_const(flow_keys, offsetof(struct __sk_buff, flow_keys)), 93 __imm(bpf_get_prandom_u32) 94 : __clobber_all); 95 } 96 97 char _license[] SEC("license") = "GPL"; 98