brintos

brintos / linux-shallow public Read only

0
0
Text · 20.4 KiB · 50c6b22 Raw
826 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Converted from tools/testing/selftests/bpf/verifier/helper_access_var_len.c */3 4#include <linux/bpf.h>5#include <bpf/bpf_helpers.h>6#include "bpf_misc.h"7 8#define MAX_ENTRIES 119 10struct test_val {11	unsigned int index;12	int foo[MAX_ENTRIES];13};14 15struct {16	__uint(type, BPF_MAP_TYPE_HASH);17	__uint(max_entries, 1);18	__type(key, long long);19	__type(value, struct test_val);20} map_hash_48b SEC(".maps");21 22struct {23	__uint(type, BPF_MAP_TYPE_HASH);24	__uint(max_entries, 1);25	__type(key, long long);26	__type(value, long long);27} map_hash_8b SEC(".maps");28 29struct {30	__uint(type, BPF_MAP_TYPE_RINGBUF);31	__uint(max_entries, 4096);32} map_ringbuf SEC(".maps");33 34SEC("tracepoint")35__description("helper access to variable memory: stack, bitwise AND + JMP, correct bounds")36__success37__naked void bitwise_and_jmp_correct_bounds(void)38{39	asm volatile ("					\40	r1 = r10;					\41	r1 += -64;					\42	r0 = 0;						\43	*(u64*)(r10 - 64) = r0;				\44	*(u64*)(r10 - 56) = r0;				\45	*(u64*)(r10 - 48) = r0;				\46	*(u64*)(r10 - 40) = r0;				\47	*(u64*)(r10 - 32) = r0;				\48	*(u64*)(r10 - 24) = r0;				\49	*(u64*)(r10 - 16) = r0;				\50	*(u64*)(r10 - 8) = r0;				\51	r2 = 16;					\52	*(u64*)(r1 - 128) = r2;				\53	r2 = *(u64*)(r1 - 128);				\54	r2 &= 64;					\55	r4 = 0;						\56	if r4 >= r2 goto l0_%=;				\57	r3 = 0;						\58	call %[bpf_probe_read_kernel];			\59l0_%=:	r0 = 0;						\60	exit;						\61"	:62	: __imm(bpf_probe_read_kernel)63	: __clobber_all);64}65 66SEC("socket")67__description("helper access to variable memory: stack, bitwise AND, zero included")68/* in privileged mode reads from uninitialized stack locations are permitted */69__success __failure_unpriv70__msg_unpriv("invalid indirect read from stack R2 off -64+0 size 64")71__retval(0)72__naked void stack_bitwise_and_zero_included(void)73{74	asm volatile ("					\75	/* set max stack size */			\76	r6 = 0;						\77	*(u64*)(r10 - 128) = r6;			\78	/* set r3 to a random value */			\79	call %[bpf_get_prandom_u32];			\80	r3 = r0;					\81	/* use bitwise AND to limit r3 range to [0, 64] */\82	r3 &= 64;					\83	r1 = %[map_ringbuf] ll;				\84	r2 = r10;					\85	r2 += -64;					\86	r4 = 0;						\87	/* Call bpf_ringbuf_output(), it is one of a few helper functions with\88	 * ARG_CONST_SIZE_OR_ZERO parameter allowed in unpriv mode.\89	 * For unpriv this should signal an error, because memory at &fp[-64] is\90	 * not initialized.				\91	 */						\92	call %[bpf_ringbuf_output];			\93	exit;						\94"	:95	: __imm(bpf_get_prandom_u32),96	  __imm(bpf_ringbuf_output),97	  __imm_addr(map_ringbuf)98	: __clobber_all);99}100 101SEC("tracepoint")102__description("helper access to variable memory: stack, bitwise AND + JMP, wrong max")103__failure __msg("invalid indirect access to stack R1 off=-64 size=65")104__naked void bitwise_and_jmp_wrong_max(void)105{106	asm volatile ("					\107	r2 = *(u64*)(r1 + 8);				\108	r1 = r10;					\109	r1 += -64;					\110	*(u64*)(r1 - 128) = r2;				\111	r2 = *(u64*)(r1 - 128);				\112	r2 &= 65;					\113	r4 = 0;						\114	if r4 >= r2 goto l0_%=;				\115	r3 = 0;						\116	call %[bpf_probe_read_kernel];			\117l0_%=:	r0 = 0;						\118	exit;						\119"	:120	: __imm(bpf_probe_read_kernel)121	: __clobber_all);122}123 124SEC("tracepoint")125__description("helper access to variable memory: stack, JMP, correct bounds")126__success127__naked void memory_stack_jmp_correct_bounds(void)128{129	asm volatile ("					\130	r1 = r10;					\131	r1 += -64;					\132	r0 = 0;						\133	*(u64*)(r10 - 64) = r0;				\134	*(u64*)(r10 - 56) = r0;				\135	*(u64*)(r10 - 48) = r0;				\136	*(u64*)(r10 - 40) = r0;				\137	*(u64*)(r10 - 32) = r0;				\138	*(u64*)(r10 - 24) = r0;				\139	*(u64*)(r10 - 16) = r0;				\140	*(u64*)(r10 - 8) = r0;				\141	r2 = 16;					\142	*(u64*)(r1 - 128) = r2;				\143	r2 = *(u64*)(r1 - 128);				\144	if r2 > 64 goto l0_%=;				\145	r4 = 0;						\146	if r4 >= r2 goto l0_%=;				\147	r3 = 0;						\148	call %[bpf_probe_read_kernel];			\149l0_%=:	r0 = 0;						\150	exit;						\151"	:152	: __imm(bpf_probe_read_kernel)153	: __clobber_all);154}155 156SEC("tracepoint")157__description("helper access to variable memory: stack, JMP (signed), correct bounds")158__success159__naked void stack_jmp_signed_correct_bounds(void)160{161	asm volatile ("					\162	r1 = r10;					\163	r1 += -64;					\164	r0 = 0;						\165	*(u64*)(r10 - 64) = r0;				\166	*(u64*)(r10 - 56) = r0;				\167	*(u64*)(r10 - 48) = r0;				\168	*(u64*)(r10 - 40) = r0;				\169	*(u64*)(r10 - 32) = r0;				\170	*(u64*)(r10 - 24) = r0;				\171	*(u64*)(r10 - 16) = r0;				\172	*(u64*)(r10 - 8) = r0;				\173	r2 = 16;					\174	*(u64*)(r1 - 128) = r2;				\175	r2 = *(u64*)(r1 - 128);				\176	if r2 s> 64 goto l0_%=;				\177	r4 = 0;						\178	if r4 s>= r2 goto l0_%=;			\179	r3 = 0;						\180	call %[bpf_probe_read_kernel];			\181l0_%=:	r0 = 0;						\182	exit;						\183"	:184	: __imm(bpf_probe_read_kernel)185	: __clobber_all);186}187 188SEC("tracepoint")189__description("helper access to variable memory: stack, JMP, bounds + offset")190__failure __msg("invalid indirect access to stack R1 off=-64 size=65")191__naked void memory_stack_jmp_bounds_offset(void)192{193	asm volatile ("					\194	r2 = *(u64*)(r1 + 8);				\195	r1 = r10;					\196	r1 += -64;					\197	*(u64*)(r1 - 128) = r2;				\198	r2 = *(u64*)(r1 - 128);				\199	if r2 > 64 goto l0_%=;				\200	r4 = 0;						\201	if r4 >= r2 goto l0_%=;				\202	r2 += 1;					\203	r3 = 0;						\204	call %[bpf_probe_read_kernel];			\205l0_%=:	r0 = 0;						\206	exit;						\207"	:208	: __imm(bpf_probe_read_kernel)209	: __clobber_all);210}211 212SEC("tracepoint")213__description("helper access to variable memory: stack, JMP, wrong max")214__failure __msg("invalid indirect access to stack R1 off=-64 size=65")215__naked void memory_stack_jmp_wrong_max(void)216{217	asm volatile ("					\218	r2 = *(u64*)(r1 + 8);				\219	r1 = r10;					\220	r1 += -64;					\221	*(u64*)(r1 - 128) = r2;				\222	r2 = *(u64*)(r1 - 128);				\223	if r2 > 65 goto l0_%=;				\224	r4 = 0;						\225	if r4 >= r2 goto l0_%=;				\226	r3 = 0;						\227	call %[bpf_probe_read_kernel];			\228l0_%=:	r0 = 0;						\229	exit;						\230"	:231	: __imm(bpf_probe_read_kernel)232	: __clobber_all);233}234 235SEC("tracepoint")236__description("helper access to variable memory: stack, JMP, no max check")237__failure238/* because max wasn't checked, signed min is negative */239__msg("R2 min value is negative, either use unsigned or 'var &= const'")240__naked void stack_jmp_no_max_check(void)241{242	asm volatile ("					\243	r2 = *(u64*)(r1 + 8);				\244	r1 = r10;					\245	r1 += -64;					\246	*(u64*)(r1 - 128) = r2;				\247	r2 = *(u64*)(r1 - 128);				\248	r4 = 0;						\249	if r4 >= r2 goto l0_%=;				\250	r3 = 0;						\251	call %[bpf_probe_read_kernel];			\252l0_%=:	r0 = 0;						\253	exit;						\254"	:255	: __imm(bpf_probe_read_kernel)256	: __clobber_all);257}258 259SEC("socket")260__description("helper access to variable memory: stack, JMP, no min check")261/* in privileged mode reads from uninitialized stack locations are permitted */262__success __failure_unpriv263__msg_unpriv("invalid indirect read from stack R2 off -64+0 size 64")264__retval(0)265__naked void stack_jmp_no_min_check(void)266{267	asm volatile ("					\268	/* set max stack size */			\269	r6 = 0;						\270	*(u64*)(r10 - 128) = r6;			\271	/* set r3 to a random value */			\272	call %[bpf_get_prandom_u32];			\273	r3 = r0;					\274	/* use JMP to limit r3 range to [0, 64] */	\275	if r3 > 64 goto l0_%=;				\276	r1 = %[map_ringbuf] ll;				\277	r2 = r10;					\278	r2 += -64;					\279	r4 = 0;						\280	/* Call bpf_ringbuf_output(), it is one of a few helper functions with\281	 * ARG_CONST_SIZE_OR_ZERO parameter allowed in unpriv mode.\282	 * For unpriv this should signal an error, because memory at &fp[-64] is\283	 * not initialized.				\284	 */						\285	call %[bpf_ringbuf_output];			\286l0_%=:	r0 = 0;						\287	exit;						\288"	:289	: __imm(bpf_get_prandom_u32),290	  __imm(bpf_ringbuf_output),291	  __imm_addr(map_ringbuf)292	: __clobber_all);293}294 295SEC("tracepoint")296__description("helper access to variable memory: stack, JMP (signed), no min check")297__failure __msg("R2 min value is negative")298__naked void jmp_signed_no_min_check(void)299{300	asm volatile ("					\301	r2 = *(u64*)(r1 + 8);				\302	r1 = r10;					\303	r1 += -64;					\304	*(u64*)(r1 - 128) = r2;				\305	r2 = *(u64*)(r1 - 128);				\306	if r2 s> 64 goto l0_%=;				\307	r3 = 0;						\308	call %[bpf_probe_read_kernel];			\309	r0 = 0;						\310l0_%=:	exit;						\311"	:312	: __imm(bpf_probe_read_kernel)313	: __clobber_all);314}315 316SEC("tracepoint")317__description("helper access to variable memory: map, JMP, correct bounds")318__success319__naked void memory_map_jmp_correct_bounds(void)320{321	asm volatile ("					\322	r2 = r10;					\323	r2 += -8;					\324	r1 = 0;						\325	*(u64*)(r2 + 0) = r1;				\326	r1 = %[map_hash_48b] ll;			\327	call %[bpf_map_lookup_elem];			\328	if r0 == 0 goto l0_%=;				\329	r1 = r0;					\330	r2 = %[sizeof_test_val];			\331	*(u64*)(r10 - 128) = r2;			\332	r2 = *(u64*)(r10 - 128);			\333	if r2 s> %[sizeof_test_val] goto l1_%=;		\334	r4 = 0;						\335	if r4 s>= r2 goto l1_%=;			\336	r3 = 0;						\337	call %[bpf_probe_read_kernel];			\338l1_%=:	r0 = 0;						\339l0_%=:	exit;						\340"	:341	: __imm(bpf_map_lookup_elem),342	  __imm(bpf_probe_read_kernel),343	  __imm_addr(map_hash_48b),344	  __imm_const(sizeof_test_val, sizeof(struct test_val))345	: __clobber_all);346}347 348SEC("tracepoint")349__description("helper access to variable memory: map, JMP, wrong max")350__failure __msg("invalid access to map value, value_size=48 off=0 size=49")351__naked void memory_map_jmp_wrong_max(void)352{353	asm volatile ("					\354	r6 = *(u64*)(r1 + 8);				\355	r2 = r10;					\356	r2 += -8;					\357	r1 = 0;						\358	*(u64*)(r2 + 0) = r1;				\359	r1 = %[map_hash_48b] ll;			\360	call %[bpf_map_lookup_elem];			\361	if r0 == 0 goto l0_%=;				\362	r1 = r0;					\363	r2 = r6;					\364	*(u64*)(r10 - 128) = r2;			\365	r2 = *(u64*)(r10 - 128);			\366	if r2 s> %[__imm_0] goto l1_%=;			\367	r4 = 0;						\368	if r4 s>= r2 goto l1_%=;			\369	r3 = 0;						\370	call %[bpf_probe_read_kernel];			\371l1_%=:	r0 = 0;						\372l0_%=:	exit;						\373"	:374	: __imm(bpf_map_lookup_elem),375	  __imm(bpf_probe_read_kernel),376	  __imm_addr(map_hash_48b),377	  __imm_const(__imm_0, sizeof(struct test_val) + 1)378	: __clobber_all);379}380 381SEC("tracepoint")382__description("helper access to variable memory: map adjusted, JMP, correct bounds")383__success384__naked void map_adjusted_jmp_correct_bounds(void)385{386	asm volatile ("					\387	r2 = r10;					\388	r2 += -8;					\389	r1 = 0;						\390	*(u64*)(r2 + 0) = r1;				\391	r1 = %[map_hash_48b] ll;			\392	call %[bpf_map_lookup_elem];			\393	if r0 == 0 goto l0_%=;				\394	r1 = r0;					\395	r1 += 20;					\396	r2 = %[sizeof_test_val];			\397	*(u64*)(r10 - 128) = r2;			\398	r2 = *(u64*)(r10 - 128);			\399	if r2 s> %[__imm_0] goto l1_%=;			\400	r4 = 0;						\401	if r4 s>= r2 goto l1_%=;			\402	r3 = 0;						\403	call %[bpf_probe_read_kernel];			\404l1_%=:	r0 = 0;						\405l0_%=:	exit;						\406"	:407	: __imm(bpf_map_lookup_elem),408	  __imm(bpf_probe_read_kernel),409	  __imm_addr(map_hash_48b),410	  __imm_const(__imm_0, sizeof(struct test_val) - 20),411	  __imm_const(sizeof_test_val, sizeof(struct test_val))412	: __clobber_all);413}414 415SEC("tracepoint")416__description("helper access to variable memory: map adjusted, JMP, wrong max")417__failure __msg("R1 min value is outside of the allowed memory range")418__naked void map_adjusted_jmp_wrong_max(void)419{420	asm volatile ("					\421	r6 = *(u64*)(r1 + 8);				\422	r2 = r10;					\423	r2 += -8;					\424	r1 = 0;						\425	*(u64*)(r2 + 0) = r1;				\426	r1 = %[map_hash_48b] ll;			\427	call %[bpf_map_lookup_elem];			\428	if r0 == 0 goto l0_%=;				\429	r1 = r0;					\430	r1 += 20;					\431	r2 = r6;					\432	*(u64*)(r10 - 128) = r2;			\433	r2 = *(u64*)(r10 - 128);			\434	if r2 s> %[__imm_0] goto l1_%=;			\435	r4 = 0;						\436	if r4 s>= r2 goto l1_%=;			\437	r3 = 0;						\438	call %[bpf_probe_read_kernel];			\439l1_%=:	r0 = 0;						\440l0_%=:	exit;						\441"	:442	: __imm(bpf_map_lookup_elem),443	  __imm(bpf_probe_read_kernel),444	  __imm_addr(map_hash_48b),445	  __imm_const(__imm_0, sizeof(struct test_val) - 19)446	: __clobber_all);447}448 449SEC("tc")450__description("helper access to variable memory: size = 0 allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)")451__success __retval(0)452__naked void ptr_to_mem_or_null_1(void)453{454	asm volatile ("					\455	r1 = 0;						\456	r2 = 0;						\457	r3 = 0;						\458	r4 = 0;						\459	r5 = 0;						\460	call %[bpf_csum_diff];				\461	exit;						\462"	:463	: __imm(bpf_csum_diff)464	: __clobber_all);465}466 467SEC("tc")468__description("helper access to variable memory: size > 0 not allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)")469__failure __msg("R1 type=scalar expected=fp")470__naked void ptr_to_mem_or_null_2(void)471{472	asm volatile ("					\473	r2 = *(u32*)(r1 + 0);				\474	r1 = 0;						\475	*(u64*)(r10 - 128) = r2;			\476	r2 = *(u64*)(r10 - 128);			\477	r2 &= 64;					\478	r3 = 0;						\479	r4 = 0;						\480	r5 = 0;						\481	call %[bpf_csum_diff];				\482	exit;						\483"	:484	: __imm(bpf_csum_diff)485	: __clobber_all);486}487 488SEC("tc")489__description("helper access to variable memory: size = 0 allowed on != NULL stack pointer (ARG_PTR_TO_MEM_OR_NULL)")490__success __retval(0)491__naked void ptr_to_mem_or_null_3(void)492{493	asm volatile ("					\494	r1 = r10;					\495	r1 += -8;					\496	r2 = 0;						\497	*(u64*)(r1 + 0) = r2;				\498	r2 &= 8;					\499	r3 = 0;						\500	r4 = 0;						\501	r5 = 0;						\502	call %[bpf_csum_diff];				\503	exit;						\504"	:505	: __imm(bpf_csum_diff)506	: __clobber_all);507}508 509SEC("tc")510__description("helper access to variable memory: size = 0 allowed on != NULL map pointer (ARG_PTR_TO_MEM_OR_NULL)")511__success __retval(0)512__naked void ptr_to_mem_or_null_4(void)513{514	asm volatile ("					\515	r1 = 0;						\516	*(u64*)(r10 - 8) = r1;				\517	r2 = r10;					\518	r2 += -8;					\519	r1 = %[map_hash_8b] ll;				\520	call %[bpf_map_lookup_elem];			\521	if r0 == 0 goto l0_%=;				\522	r1 = r0;					\523	r2 = 0;						\524	r3 = 0;						\525	r4 = 0;						\526	r5 = 0;						\527	call %[bpf_csum_diff];				\528l0_%=:	exit;						\529"	:530	: __imm(bpf_csum_diff),531	  __imm(bpf_map_lookup_elem),532	  __imm_addr(map_hash_8b)533	: __clobber_all);534}535 536SEC("tc")537__description("helper access to variable memory: size possible = 0 allowed on != NULL stack pointer (ARG_PTR_TO_MEM_OR_NULL)")538__success __retval(0)539__naked void ptr_to_mem_or_null_5(void)540{541	asm volatile ("					\542	r1 = 0;						\543	*(u64*)(r10 - 8) = r1;				\544	r2 = r10;					\545	r2 += -8;					\546	r1 = %[map_hash_8b] ll;				\547	call %[bpf_map_lookup_elem];			\548	if r0 == 0 goto l0_%=;				\549	r2 = *(u64*)(r0 + 0);				\550	if r2 > 8 goto l0_%=;				\551	r1 = r10;					\552	r1 += -8;					\553	*(u64*)(r1 + 0) = r2;				\554	r3 = 0;						\555	r4 = 0;						\556	r5 = 0;						\557	call %[bpf_csum_diff];				\558l0_%=:	exit;						\559"	:560	: __imm(bpf_csum_diff),561	  __imm(bpf_map_lookup_elem),562	  __imm_addr(map_hash_8b)563	: __clobber_all);564}565 566SEC("tc")567__description("helper access to variable memory: size possible = 0 allowed on != NULL map pointer (ARG_PTR_TO_MEM_OR_NULL)")568__success __retval(0)569__naked void ptr_to_mem_or_null_6(void)570{571	asm volatile ("					\572	r1 = 0;						\573	*(u64*)(r10 - 8) = r1;				\574	r2 = r10;					\575	r2 += -8;					\576	r1 = %[map_hash_8b] ll;				\577	call %[bpf_map_lookup_elem];			\578	if r0 == 0 goto l0_%=;				\579	r1 = r0;					\580	r2 = *(u64*)(r0 + 0);				\581	if r2 > 8 goto l0_%=;				\582	r3 = 0;						\583	r4 = 0;						\584	r5 = 0;						\585	call %[bpf_csum_diff];				\586l0_%=:	exit;						\587"	:588	: __imm(bpf_csum_diff),589	  __imm(bpf_map_lookup_elem),590	  __imm_addr(map_hash_8b)591	: __clobber_all);592}593 594SEC("tc")595__description("helper access to variable memory: size possible = 0 allowed on != NULL packet pointer (ARG_PTR_TO_MEM_OR_NULL)")596__success __retval(0)597/* csum_diff of 64-byte packet */598__flag(BPF_F_ANY_ALIGNMENT)599__naked void ptr_to_mem_or_null_7(void)600{601	asm volatile ("					\602	r6 = *(u32*)(r1 + %[__sk_buff_data]);		\603	r3 = *(u32*)(r1 + %[__sk_buff_data_end]);	\604	r0 = r6;					\605	r0 += 8;					\606	if r0 > r3 goto l0_%=;				\607	r1 = r6;					\608	r2 = *(u64*)(r6 + 0);				\609	if r2 > 8 goto l0_%=;				\610	r3 = 0;						\611	r4 = 0;						\612	r5 = 0;						\613	call %[bpf_csum_diff];				\614l0_%=:	exit;						\615"	:616	: __imm(bpf_csum_diff),617	  __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),618	  __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))619	: __clobber_all);620}621 622SEC("tracepoint")623__description("helper access to variable memory: size = 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)")624__failure __msg("R1 type=scalar expected=fp")625__naked void ptr_to_mem_or_null_8(void)626{627	asm volatile ("					\628	r1 = 0;						\629	r2 = 0;						\630	r3 = 0;						\631	call %[bpf_probe_read_kernel];			\632	exit;						\633"	:634	: __imm(bpf_probe_read_kernel)635	: __clobber_all);636}637 638SEC("tracepoint")639__description("helper access to variable memory: size > 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)")640__failure __msg("R1 type=scalar expected=fp")641__naked void ptr_to_mem_or_null_9(void)642{643	asm volatile ("					\644	r1 = 0;						\645	r2 = 1;						\646	r3 = 0;						\647	call %[bpf_probe_read_kernel];			\648	exit;						\649"	:650	: __imm(bpf_probe_read_kernel)651	: __clobber_all);652}653 654SEC("tracepoint")655__description("helper access to variable memory: size = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)")656__success657__naked void ptr_to_mem_or_null_10(void)658{659	asm volatile ("					\660	r1 = r10;					\661	r1 += -8;					\662	r2 = 0;						\663	r3 = 0;						\664	call %[bpf_probe_read_kernel];			\665	exit;						\666"	:667	: __imm(bpf_probe_read_kernel)668	: __clobber_all);669}670 671SEC("tracepoint")672__description("helper access to variable memory: size = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)")673__success674__naked void ptr_to_mem_or_null_11(void)675{676	asm volatile ("					\677	r1 = 0;						\678	*(u64*)(r10 - 8) = r1;				\679	r2 = r10;					\680	r2 += -8;					\681	r1 = %[map_hash_8b] ll;				\682	call %[bpf_map_lookup_elem];			\683	if r0 == 0 goto l0_%=;				\684	r1 = r0;					\685	r2 = 0;						\686	r3 = 0;						\687	call %[bpf_probe_read_kernel];			\688l0_%=:	exit;						\689"	:690	: __imm(bpf_map_lookup_elem),691	  __imm(bpf_probe_read_kernel),692	  __imm_addr(map_hash_8b)693	: __clobber_all);694}695 696SEC("tracepoint")697__description("helper access to variable memory: size possible = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)")698__success699__naked void ptr_to_mem_or_null_12(void)700{701	asm volatile ("					\702	r1 = 0;						\703	*(u64*)(r10 - 8) = r1;				\704	r2 = r10;					\705	r2 += -8;					\706	r1 = %[map_hash_8b] ll;				\707	call %[bpf_map_lookup_elem];			\708	if r0 == 0 goto l0_%=;				\709	r2 = *(u64*)(r0 + 0);				\710	if r2 > 8 goto l0_%=;				\711	r1 = r10;					\712	r1 += -8;					\713	r3 = 0;						\714	call %[bpf_probe_read_kernel];			\715l0_%=:	exit;						\716"	:717	: __imm(bpf_map_lookup_elem),718	  __imm(bpf_probe_read_kernel),719	  __imm_addr(map_hash_8b)720	: __clobber_all);721}722 723SEC("tracepoint")724__description("helper access to variable memory: size possible = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)")725__success726__naked void ptr_to_mem_or_null_13(void)727{728	asm volatile ("					\729	r1 = 0;						\730	*(u64*)(r10 - 8) = r1;				\731	r2 = r10;					\732	r2 += -8;					\733	r1 = %[map_hash_8b] ll;				\734	call %[bpf_map_lookup_elem];			\735	if r0 == 0 goto l0_%=;				\736	r1 = r0;					\737	r2 = *(u64*)(r0 + 0);				\738	if r2 > 8 goto l0_%=;				\739	r3 = 0;						\740	call %[bpf_probe_read_kernel];			\741l0_%=:	exit;						\742"	:743	: __imm(bpf_map_lookup_elem),744	  __imm(bpf_probe_read_kernel),745	  __imm_addr(map_hash_8b)746	: __clobber_all);747}748 749SEC("socket")750__description("helper access to variable memory: 8 bytes leak")751/* in privileged mode reads from uninitialized stack locations are permitted */752__success __failure_unpriv753__msg_unpriv("invalid indirect read from stack R2 off -64+32 size 64")754__retval(0)755__naked void variable_memory_8_bytes_leak(void)756{757	asm volatile ("					\758	/* set max stack size */			\759	r6 = 0;						\760	*(u64*)(r10 - 128) = r6;			\761	/* set r3 to a random value */			\762	call %[bpf_get_prandom_u32];			\763	r3 = r0;					\764	r1 = %[map_ringbuf] ll;				\765	r2 = r10;					\766	r2 += -64;					\767	r0 = 0;						\768	*(u64*)(r10 - 64) = r0;				\769	*(u64*)(r10 - 56) = r0;				\770	*(u64*)(r10 - 48) = r0;				\771	*(u64*)(r10 - 40) = r0;				\772	/* Note: fp[-32] left uninitialized */		\773	*(u64*)(r10 - 24) = r0;				\774	*(u64*)(r10 - 16) = r0;				\775	*(u64*)(r10 - 8) = r0;				\776	/* Limit r3 range to [1, 64] */			\777	r3 &= 63;					\778	r3 += 1;					\779	r4 = 0;						\780	/* Call bpf_ringbuf_output(), it is one of a few helper functions with\781	 * ARG_CONST_SIZE_OR_ZERO parameter allowed in unpriv mode.\782	 * For unpriv this should signal an error, because memory region [1, 64]\783	 * at &fp[-64] is not fully initialized.	\784	 */						\785	call %[bpf_ringbuf_output];			\786	r0 = 0;						\787	exit;						\788"	:789	: __imm(bpf_get_prandom_u32),790	  __imm(bpf_ringbuf_output),791	  __imm_addr(map_ringbuf)792	: __clobber_all);793}794 795SEC("tracepoint")796__description("helper access to variable memory: 8 bytes no leak (init memory)")797__success798__naked void bytes_no_leak_init_memory(void)799{800	asm volatile ("					\801	r1 = r10;					\802	r0 = 0;						\803	r0 = 0;						\804	*(u64*)(r10 - 64) = r0;				\805	*(u64*)(r10 - 56) = r0;				\806	*(u64*)(r10 - 48) = r0;				\807	*(u64*)(r10 - 40) = r0;				\808	*(u64*)(r10 - 32) = r0;				\809	*(u64*)(r10 - 24) = r0;				\810	*(u64*)(r10 - 16) = r0;				\811	*(u64*)(r10 - 8) = r0;				\812	r1 += -64;					\813	r2 = 0;						\814	r2 &= 32;					\815	r2 += 32;					\816	r3 = 0;						\817	call %[bpf_probe_read_kernel];			\818	r1 = *(u64*)(r10 - 16);				\819	exit;						\820"	:821	: __imm(bpf_probe_read_kernel)822	: __clobber_all);823}824 825char _license[] SEC("license") = "GPL";826