162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci#include <linux/bpf.h> 462306a36Sopenharmony_ci#include <bpf/bpf_helpers.h> 562306a36Sopenharmony_ci#include "bpf_misc.h" 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci/* Read an uninitialized value from stack at a fixed offset */ 862306a36Sopenharmony_ciSEC("socket") 962306a36Sopenharmony_ci__naked int read_uninit_stack_fixed_off(void *ctx) 1062306a36Sopenharmony_ci{ 1162306a36Sopenharmony_ci asm volatile (" \ 1262306a36Sopenharmony_ci r0 = 0; \ 1362306a36Sopenharmony_ci /* force stack depth to be 128 */ \ 1462306a36Sopenharmony_ci *(u64*)(r10 - 128) = r1; \ 1562306a36Sopenharmony_ci r1 = *(u8 *)(r10 - 8 ); \ 1662306a36Sopenharmony_ci r0 += r1; \ 1762306a36Sopenharmony_ci r1 = *(u8 *)(r10 - 11); \ 1862306a36Sopenharmony_ci r1 = *(u8 *)(r10 - 13); \ 1962306a36Sopenharmony_ci r1 = *(u8 *)(r10 - 15); \ 2062306a36Sopenharmony_ci r1 = *(u16*)(r10 - 16); \ 2162306a36Sopenharmony_ci r1 = *(u32*)(r10 - 32); \ 2262306a36Sopenharmony_ci r1 = *(u64*)(r10 - 64); \ 2362306a36Sopenharmony_ci /* read from a spill of a wrong size, it is a separate \ 2462306a36Sopenharmony_ci * branch in check_stack_read_fixed_off() \ 2562306a36Sopenharmony_ci */ \ 2662306a36Sopenharmony_ci *(u32*)(r10 - 72) = r1; \ 2762306a36Sopenharmony_ci r1 = *(u64*)(r10 - 72); \ 2862306a36Sopenharmony_ci r0 = 0; \ 2962306a36Sopenharmony_ci exit; \ 3062306a36Sopenharmony_ci" 3162306a36Sopenharmony_ci ::: __clobber_all); 3262306a36Sopenharmony_ci} 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci/* Read an uninitialized value from stack at a variable offset */ 3562306a36Sopenharmony_ciSEC("socket") 3662306a36Sopenharmony_ci__naked int read_uninit_stack_var_off(void *ctx) 3762306a36Sopenharmony_ci{ 3862306a36Sopenharmony_ci asm volatile (" \ 3962306a36Sopenharmony_ci call %[bpf_get_prandom_u32]; \ 4062306a36Sopenharmony_ci /* force stack depth to be 64 */ \ 4162306a36Sopenharmony_ci *(u64*)(r10 - 64) = r0; \ 4262306a36Sopenharmony_ci r0 = -r0; \ 4362306a36Sopenharmony_ci /* give r0 a range [-31, -1] */ \ 4462306a36Sopenharmony_ci if r0 s<= -32 goto exit_%=; \ 4562306a36Sopenharmony_ci if r0 s>= 0 goto exit_%=; \ 4662306a36Sopenharmony_ci /* access stack using r0 */ \ 4762306a36Sopenharmony_ci r1 = r10; \ 4862306a36Sopenharmony_ci r1 += r0; \ 4962306a36Sopenharmony_ci r2 = *(u8*)(r1 + 0); \ 5062306a36Sopenharmony_ciexit_%=: r0 = 0; \ 5162306a36Sopenharmony_ci exit; \ 5262306a36Sopenharmony_ci" 5362306a36Sopenharmony_ci : 5462306a36Sopenharmony_ci : __imm(bpf_get_prandom_u32) 5562306a36Sopenharmony_ci : __clobber_all); 5662306a36Sopenharmony_ci} 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_cistatic __noinline void dummy(void) {} 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci/* Pass a pointer to uninitialized stack memory to a helper. 6162306a36Sopenharmony_ci * Passed memory block should be marked as STACK_MISC after helper call. 6262306a36Sopenharmony_ci */ 6362306a36Sopenharmony_ciSEC("socket") 6462306a36Sopenharmony_ci__log_level(7) __msg("fp-104=mmmmmmmm") 6562306a36Sopenharmony_ci__naked int helper_uninit_to_misc(void *ctx) 6662306a36Sopenharmony_ci{ 6762306a36Sopenharmony_ci asm volatile (" \ 6862306a36Sopenharmony_ci /* force stack depth to be 128 */ \ 6962306a36Sopenharmony_ci *(u64*)(r10 - 128) = r1; \ 7062306a36Sopenharmony_ci r1 = r10; \ 7162306a36Sopenharmony_ci r1 += -128; \ 7262306a36Sopenharmony_ci r2 = 32; \ 7362306a36Sopenharmony_ci call %[bpf_trace_printk]; \ 7462306a36Sopenharmony_ci /* Call to dummy() forces print_verifier_state(..., true), \ 7562306a36Sopenharmony_ci * thus showing the stack state, matched by __msg(). \ 7662306a36Sopenharmony_ci */ \ 7762306a36Sopenharmony_ci call %[dummy]; \ 7862306a36Sopenharmony_ci r0 = 0; \ 7962306a36Sopenharmony_ci exit; \ 8062306a36Sopenharmony_ci" 8162306a36Sopenharmony_ci : 8262306a36Sopenharmony_ci : __imm(bpf_trace_printk), 8362306a36Sopenharmony_ci __imm(dummy) 8462306a36Sopenharmony_ci : __clobber_all); 8562306a36Sopenharmony_ci} 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_cichar _license[] SEC("license") = "GPL"; 88