1*6338a94dSEduard Zingerman // SPDX-License-Identifier: GPL-2.0 2*6338a94dSEduard Zingerman 3*6338a94dSEduard Zingerman #include <linux/bpf.h> 4*6338a94dSEduard Zingerman #include <bpf/bpf_helpers.h> 5*6338a94dSEduard Zingerman #include "bpf_misc.h" 6*6338a94dSEduard Zingerman 7*6338a94dSEduard Zingerman /* Read an uninitialized value from stack at a fixed offset */ 8*6338a94dSEduard Zingerman SEC("socket") read_uninit_stack_fixed_off(void * ctx)9*6338a94dSEduard Zingerman__naked int read_uninit_stack_fixed_off(void *ctx) 10*6338a94dSEduard Zingerman { 11*6338a94dSEduard Zingerman asm volatile (" \ 12*6338a94dSEduard Zingerman r0 = 0; \ 13*6338a94dSEduard Zingerman /* force stack depth to be 128 */ \ 14*6338a94dSEduard Zingerman *(u64*)(r10 - 128) = r1; \ 15*6338a94dSEduard Zingerman r1 = *(u8 *)(r10 - 8 ); \ 16*6338a94dSEduard Zingerman r0 += r1; \ 17*6338a94dSEduard Zingerman r1 = *(u8 *)(r10 - 11); \ 18*6338a94dSEduard Zingerman r1 = *(u8 *)(r10 - 13); \ 19*6338a94dSEduard Zingerman r1 = *(u8 *)(r10 - 15); \ 20*6338a94dSEduard Zingerman r1 = *(u16*)(r10 - 16); \ 21*6338a94dSEduard Zingerman r1 = *(u32*)(r10 - 32); \ 22*6338a94dSEduard Zingerman r1 = *(u64*)(r10 - 64); \ 23*6338a94dSEduard Zingerman /* read from a spill of a wrong size, it is a separate \ 24*6338a94dSEduard Zingerman * branch in check_stack_read_fixed_off() \ 25*6338a94dSEduard Zingerman */ \ 26*6338a94dSEduard Zingerman *(u32*)(r10 - 72) = r1; \ 27*6338a94dSEduard Zingerman r1 = *(u64*)(r10 - 72); \ 28*6338a94dSEduard Zingerman r0 = 0; \ 29*6338a94dSEduard Zingerman exit; \ 30*6338a94dSEduard Zingerman " 31*6338a94dSEduard Zingerman ::: __clobber_all); 32*6338a94dSEduard Zingerman } 33*6338a94dSEduard Zingerman 34*6338a94dSEduard Zingerman /* Read an uninitialized value from stack at a variable offset */ 35*6338a94dSEduard Zingerman SEC("socket") read_uninit_stack_var_off(void * ctx)36*6338a94dSEduard Zingerman__naked int read_uninit_stack_var_off(void *ctx) 37*6338a94dSEduard Zingerman { 38*6338a94dSEduard Zingerman asm volatile (" \ 39*6338a94dSEduard Zingerman call %[bpf_get_prandom_u32]; \ 40*6338a94dSEduard Zingerman /* force stack depth to be 64 */ \ 41*6338a94dSEduard Zingerman *(u64*)(r10 - 64) = r0; \ 42*6338a94dSEduard Zingerman r0 = -r0; \ 43*6338a94dSEduard Zingerman /* give r0 a range [-31, -1] */ \ 44*6338a94dSEduard Zingerman if r0 s<= -32 goto exit_%=; \ 45*6338a94dSEduard Zingerman if r0 s>= 0 goto exit_%=; \ 46*6338a94dSEduard Zingerman /* access stack using r0 */ \ 47*6338a94dSEduard Zingerman r1 = r10; \ 48*6338a94dSEduard Zingerman r1 += r0; \ 49*6338a94dSEduard Zingerman r2 = *(u8*)(r1 + 0); \ 50*6338a94dSEduard Zingerman exit_%=: r0 = 0; \ 51*6338a94dSEduard Zingerman exit; \ 52*6338a94dSEduard Zingerman " 53*6338a94dSEduard Zingerman : 54*6338a94dSEduard Zingerman : __imm(bpf_get_prandom_u32) 55*6338a94dSEduard Zingerman : __clobber_all); 56*6338a94dSEduard Zingerman } 57*6338a94dSEduard Zingerman dummy(void)58*6338a94dSEduard Zingermanstatic __noinline void dummy(void) {} 59*6338a94dSEduard Zingerman 60*6338a94dSEduard Zingerman /* Pass a pointer to uninitialized stack memory to a helper. 61*6338a94dSEduard Zingerman * Passed memory block should be marked as STACK_MISC after helper call. 62*6338a94dSEduard Zingerman */ 63*6338a94dSEduard Zingerman SEC("socket") 64*6338a94dSEduard Zingerman __log_level(7) __msg("fp-104=mmmmmmmm") helper_uninit_to_misc(void * ctx)65*6338a94dSEduard Zingerman__naked int helper_uninit_to_misc(void *ctx) 66*6338a94dSEduard Zingerman { 67*6338a94dSEduard Zingerman asm volatile (" \ 68*6338a94dSEduard Zingerman /* force stack depth to be 128 */ \ 69*6338a94dSEduard Zingerman *(u64*)(r10 - 128) = r1; \ 70*6338a94dSEduard Zingerman r1 = r10; \ 71*6338a94dSEduard Zingerman r1 += -128; \ 72*6338a94dSEduard Zingerman r2 = 32; \ 73*6338a94dSEduard Zingerman call %[bpf_trace_printk]; \ 74*6338a94dSEduard Zingerman /* Call to dummy() forces print_verifier_state(..., true), \ 75*6338a94dSEduard Zingerman * thus showing the stack state, matched by __msg(). \ 76*6338a94dSEduard Zingerman */ \ 77*6338a94dSEduard Zingerman call %[dummy]; \ 78*6338a94dSEduard Zingerman r0 = 0; \ 79*6338a94dSEduard Zingerman exit; \ 80*6338a94dSEduard Zingerman " 81*6338a94dSEduard Zingerman : 82*6338a94dSEduard Zingerman : __imm(bpf_trace_printk), 83*6338a94dSEduard Zingerman __imm(dummy) 84*6338a94dSEduard Zingerman : __clobber_all); 85*6338a94dSEduard Zingerman } 86*6338a94dSEduard Zingerman 87*6338a94dSEduard Zingerman char _license[] SEC("license") = "GPL"; 88