brintos

brintos / linux-shallow public Read only

0
0
Text · 31.7 KiB · 886498b Raw
1283 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Converted from tools/testing/selftests/bpf/verifier/helper_value_access.c */3 4#include <linux/bpf.h>5#include <bpf/bpf_helpers.h>6#include "bpf_misc.h"7 8struct other_val {9	long long foo;10	long long bar;11};12 13struct {14	__uint(type, BPF_MAP_TYPE_HASH);15	__uint(max_entries, 1);16	__type(key, long long);17	__type(value, struct other_val);18} map_hash_16b SEC(".maps");19 20#define MAX_ENTRIES 1121 22struct test_val {23	unsigned int index;24	int foo[MAX_ENTRIES];25};26 27struct {28	__uint(type, BPF_MAP_TYPE_HASH);29	__uint(max_entries, 1);30	__type(key, long long);31	__type(value, struct test_val);32} map_hash_48b SEC(".maps");33 34struct {35	__uint(type, BPF_MAP_TYPE_HASH);36	__uint(max_entries, 1);37	__type(key, long long);38	__type(value, long long);39} map_hash_8b SEC(".maps");40 41SEC("tracepoint")42__description("helper access to map: full range")43__success44__naked void access_to_map_full_range(void)45{46	asm volatile ("					\47	r2 = r10;					\48	r2 += -8;					\49	r1 = 0;						\50	*(u64*)(r2 + 0) = r1;				\51	r1 = %[map_hash_48b] ll;			\52	call %[bpf_map_lookup_elem];			\53	if r0 == 0 goto l0_%=;				\54	r1 = r0;					\55	r2 = %[sizeof_test_val];			\56	r3 = 0;						\57	call %[bpf_probe_read_kernel];			\58l0_%=:	exit;						\59"	:60	: __imm(bpf_map_lookup_elem),61	  __imm(bpf_probe_read_kernel),62	  __imm_addr(map_hash_48b),63	  __imm_const(sizeof_test_val, sizeof(struct test_val))64	: __clobber_all);65}66 67SEC("tracepoint")68__description("helper access to map: partial range")69__success70__naked void access_to_map_partial_range(void)71{72	asm volatile ("					\73	r2 = r10;					\74	r2 += -8;					\75	r1 = 0;						\76	*(u64*)(r2 + 0) = r1;				\77	r1 = %[map_hash_48b] ll;			\78	call %[bpf_map_lookup_elem];			\79	if r0 == 0 goto l0_%=;				\80	r1 = r0;					\81	r2 = 8;						\82	r3 = 0;						\83	call %[bpf_probe_read_kernel];			\84l0_%=:	exit;						\85"	:86	: __imm(bpf_map_lookup_elem),87	  __imm(bpf_probe_read_kernel),88	  __imm_addr(map_hash_48b)89	: __clobber_all);90}91 92/* Call a function taking a pointer and a size which doesn't allow the size to93 * be zero (i.e. bpf_trace_printk() declares the second argument to be94 * ARG_CONST_SIZE, not ARG_CONST_SIZE_OR_ZERO). We attempt to pass zero for the95 * size and expect to fail.96 */97SEC("tracepoint")98__description("helper access to map: empty range")99__failure __msg("R2 invalid zero-sized read: u64=[0,0]")100__naked void access_to_map_empty_range(void)101{102	asm volatile ("					\103	r2 = r10;					\104	r2 += -8;					\105	r1 = 0;						\106	*(u64*)(r2 + 0) = r1;				\107	r1 = %[map_hash_48b] ll;			\108	call %[bpf_map_lookup_elem];			\109	if r0 == 0 goto l0_%=;				\110	r1 = r0;					\111	r2 = 0;						\112	call %[bpf_trace_printk];			\113l0_%=:	exit;						\114"	:115	: __imm(bpf_map_lookup_elem),116	  __imm(bpf_trace_printk),117	  __imm_addr(map_hash_48b)118	: __clobber_all);119}120 121/* Like the test above, but this time the size register is not known to be zero;122 * its lower-bound is zero though, which is still unacceptable.123 */124SEC("tracepoint")125__description("helper access to map: possibly-empty ange")126__failure __msg("R2 invalid zero-sized read: u64=[0,4]")127__naked void access_to_map_possibly_empty_range(void)128{129	asm volatile ("                                         \130	r2 = r10;                                               \131	r2 += -8;                                               \132	r1 = 0;                                                 \133	*(u64*)(r2 + 0) = r1;                                   \134	r1 = %[map_hash_48b] ll;                                \135	call %[bpf_map_lookup_elem];                            \136	if r0 == 0 goto l0_%=;                                  \137	r1 = r0;                                                \138	/* Read an unknown value */                             \139	r7 = *(u64*)(r0 + 0);                                   \140	/* Make it small and positive, to avoid other errors */ \141	r7 &= 4;                                                \142	r2 = 0;                                                 \143	r2 += r7;                                               \144	call %[bpf_trace_printk];                               \145l0_%=:	exit;                                               \146"	:147	: __imm(bpf_map_lookup_elem),148	  __imm(bpf_trace_printk),149	  __imm_addr(map_hash_48b)150	: __clobber_all);151}152 153SEC("tracepoint")154__description("helper access to map: out-of-bound range")155__failure __msg("invalid access to map value, value_size=48 off=0 size=56")156__naked void map_out_of_bound_range(void)157{158	asm volatile ("					\159	r2 = r10;					\160	r2 += -8;					\161	r1 = 0;						\162	*(u64*)(r2 + 0) = r1;				\163	r1 = %[map_hash_48b] ll;			\164	call %[bpf_map_lookup_elem];			\165	if r0 == 0 goto l0_%=;				\166	r1 = r0;					\167	r2 = %[__imm_0];				\168	r3 = 0;						\169	call %[bpf_probe_read_kernel];			\170l0_%=:	exit;						\171"	:172	: __imm(bpf_map_lookup_elem),173	  __imm(bpf_probe_read_kernel),174	  __imm_addr(map_hash_48b),175	  __imm_const(__imm_0, sizeof(struct test_val) + 8)176	: __clobber_all);177}178 179SEC("tracepoint")180__description("helper access to map: negative range")181__failure __msg("R2 min value is negative")182__naked void access_to_map_negative_range(void)183{184	asm volatile ("					\185	r2 = r10;					\186	r2 += -8;					\187	r1 = 0;						\188	*(u64*)(r2 + 0) = r1;				\189	r1 = %[map_hash_48b] ll;			\190	call %[bpf_map_lookup_elem];			\191	if r0 == 0 goto l0_%=;				\192	r1 = r0;					\193	r2 = -8;					\194	r3 = 0;						\195	call %[bpf_probe_read_kernel];			\196l0_%=:	exit;						\197"	:198	: __imm(bpf_map_lookup_elem),199	  __imm(bpf_probe_read_kernel),200	  __imm_addr(map_hash_48b)201	: __clobber_all);202}203 204SEC("tracepoint")205__description("helper access to adjusted map (via const imm): full range")206__success207__naked void via_const_imm_full_range(void)208{209	asm volatile ("					\210	r2 = r10;					\211	r2 += -8;					\212	r1 = 0;						\213	*(u64*)(r2 + 0) = r1;				\214	r1 = %[map_hash_48b] ll;			\215	call %[bpf_map_lookup_elem];			\216	if r0 == 0 goto l0_%=;				\217	r1 = r0;					\218	r1 += %[test_val_foo];				\219	r2 = %[__imm_0];				\220	r3 = 0;						\221	call %[bpf_probe_read_kernel];			\222l0_%=:	exit;						\223"	:224	: __imm(bpf_map_lookup_elem),225	  __imm(bpf_probe_read_kernel),226	  __imm_addr(map_hash_48b),227	  __imm_const(__imm_0, sizeof(struct test_val) - offsetof(struct test_val, foo)),228	  __imm_const(test_val_foo, offsetof(struct test_val, foo))229	: __clobber_all);230}231 232SEC("tracepoint")233__description("helper access to adjusted map (via const imm): partial range")234__success235__naked void via_const_imm_partial_range(void)236{237	asm volatile ("					\238	r2 = r10;					\239	r2 += -8;					\240	r1 = 0;						\241	*(u64*)(r2 + 0) = r1;				\242	r1 = %[map_hash_48b] ll;			\243	call %[bpf_map_lookup_elem];			\244	if r0 == 0 goto l0_%=;				\245	r1 = r0;					\246	r1 += %[test_val_foo];				\247	r2 = 8;						\248	r3 = 0;						\249	call %[bpf_probe_read_kernel];			\250l0_%=:	exit;						\251"	:252	: __imm(bpf_map_lookup_elem),253	  __imm(bpf_probe_read_kernel),254	  __imm_addr(map_hash_48b),255	  __imm_const(test_val_foo, offsetof(struct test_val, foo))256	: __clobber_all);257}258 259SEC("tracepoint")260__description("helper access to adjusted map (via const imm): empty range")261__failure __msg("R2 invalid zero-sized read")262__naked void via_const_imm_empty_range(void)263{264	asm volatile ("					\265	r2 = r10;					\266	r2 += -8;					\267	r1 = 0;						\268	*(u64*)(r2 + 0) = r1;				\269	r1 = %[map_hash_48b] ll;			\270	call %[bpf_map_lookup_elem];			\271	if r0 == 0 goto l0_%=;				\272	r1 = r0;					\273	r1 += %[test_val_foo];				\274	r2 = 0;						\275	call %[bpf_trace_printk];			\276l0_%=:	exit;						\277"	:278	: __imm(bpf_map_lookup_elem),279	  __imm(bpf_trace_printk),280	  __imm_addr(map_hash_48b),281	  __imm_const(test_val_foo, offsetof(struct test_val, foo))282	: __clobber_all);283}284 285SEC("tracepoint")286__description("helper access to adjusted map (via const imm): out-of-bound range")287__failure __msg("invalid access to map value, value_size=48 off=4 size=52")288__naked void imm_out_of_bound_range(void)289{290	asm volatile ("					\291	r2 = r10;					\292	r2 += -8;					\293	r1 = 0;						\294	*(u64*)(r2 + 0) = r1;				\295	r1 = %[map_hash_48b] ll;			\296	call %[bpf_map_lookup_elem];			\297	if r0 == 0 goto l0_%=;				\298	r1 = r0;					\299	r1 += %[test_val_foo];				\300	r2 = %[__imm_0];				\301	r3 = 0;						\302	call %[bpf_probe_read_kernel];			\303l0_%=:	exit;						\304"	:305	: __imm(bpf_map_lookup_elem),306	  __imm(bpf_probe_read_kernel),307	  __imm_addr(map_hash_48b),308	  __imm_const(__imm_0, sizeof(struct test_val) - offsetof(struct test_val, foo) + 8),309	  __imm_const(test_val_foo, offsetof(struct test_val, foo))310	: __clobber_all);311}312 313SEC("tracepoint")314__description("helper access to adjusted map (via const imm): negative range (> adjustment)")315__failure __msg("R2 min value is negative")316__naked void const_imm_negative_range_adjustment_1(void)317{318	asm volatile ("					\319	r2 = r10;					\320	r2 += -8;					\321	r1 = 0;						\322	*(u64*)(r2 + 0) = r1;				\323	r1 = %[map_hash_48b] ll;			\324	call %[bpf_map_lookup_elem];			\325	if r0 == 0 goto l0_%=;				\326	r1 = r0;					\327	r1 += %[test_val_foo];				\328	r2 = -8;					\329	r3 = 0;						\330	call %[bpf_probe_read_kernel];			\331l0_%=:	exit;						\332"	:333	: __imm(bpf_map_lookup_elem),334	  __imm(bpf_probe_read_kernel),335	  __imm_addr(map_hash_48b),336	  __imm_const(test_val_foo, offsetof(struct test_val, foo))337	: __clobber_all);338}339 340SEC("tracepoint")341__description("helper access to adjusted map (via const imm): negative range (< adjustment)")342__failure __msg("R2 min value is negative")343__naked void const_imm_negative_range_adjustment_2(void)344{345	asm volatile ("					\346	r2 = r10;					\347	r2 += -8;					\348	r1 = 0;						\349	*(u64*)(r2 + 0) = r1;				\350	r1 = %[map_hash_48b] ll;			\351	call %[bpf_map_lookup_elem];			\352	if r0 == 0 goto l0_%=;				\353	r1 = r0;					\354	r1 += %[test_val_foo];				\355	r2 = -1;					\356	r3 = 0;						\357	call %[bpf_probe_read_kernel];			\358l0_%=:	exit;						\359"	:360	: __imm(bpf_map_lookup_elem),361	  __imm(bpf_probe_read_kernel),362	  __imm_addr(map_hash_48b),363	  __imm_const(test_val_foo, offsetof(struct test_val, foo))364	: __clobber_all);365}366 367SEC("tracepoint")368__description("helper access to adjusted map (via const reg): full range")369__success370__naked void via_const_reg_full_range(void)371{372	asm volatile ("					\373	r2 = r10;					\374	r2 += -8;					\375	r1 = 0;						\376	*(u64*)(r2 + 0) = r1;				\377	r1 = %[map_hash_48b] ll;			\378	call %[bpf_map_lookup_elem];			\379	if r0 == 0 goto l0_%=;				\380	r1 = r0;					\381	r3 = %[test_val_foo];				\382	r1 += r3;					\383	r2 = %[__imm_0];				\384	r3 = 0;						\385	call %[bpf_probe_read_kernel];			\386l0_%=:	exit;						\387"	:388	: __imm(bpf_map_lookup_elem),389	  __imm(bpf_probe_read_kernel),390	  __imm_addr(map_hash_48b),391	  __imm_const(__imm_0, sizeof(struct test_val) - offsetof(struct test_val, foo)),392	  __imm_const(test_val_foo, offsetof(struct test_val, foo))393	: __clobber_all);394}395 396SEC("tracepoint")397__description("helper access to adjusted map (via const reg): partial range")398__success399__naked void via_const_reg_partial_range(void)400{401	asm volatile ("					\402	r2 = r10;					\403	r2 += -8;					\404	r1 = 0;						\405	*(u64*)(r2 + 0) = r1;				\406	r1 = %[map_hash_48b] ll;			\407	call %[bpf_map_lookup_elem];			\408	if r0 == 0 goto l0_%=;				\409	r1 = r0;					\410	r3 = %[test_val_foo];				\411	r1 += r3;					\412	r2 = 8;						\413	r3 = 0;						\414	call %[bpf_probe_read_kernel];			\415l0_%=:	exit;						\416"	:417	: __imm(bpf_map_lookup_elem),418	  __imm(bpf_probe_read_kernel),419	  __imm_addr(map_hash_48b),420	  __imm_const(test_val_foo, offsetof(struct test_val, foo))421	: __clobber_all);422}423 424SEC("tracepoint")425__description("helper access to adjusted map (via const reg): empty range")426__failure __msg("R2 invalid zero-sized read")427__naked void via_const_reg_empty_range(void)428{429	asm volatile ("					\430	r2 = r10;					\431	r2 += -8;					\432	r1 = 0;						\433	*(u64*)(r2 + 0) = r1;				\434	r1 = %[map_hash_48b] ll;			\435	call %[bpf_map_lookup_elem];			\436	if r0 == 0 goto l0_%=;				\437	r1 = r0;					\438	r3 = 0;						\439	r1 += r3;					\440	r2 = 0;						\441	call %[bpf_trace_printk];			\442l0_%=:	exit;						\443"	:444	: __imm(bpf_map_lookup_elem),445	  __imm(bpf_trace_printk),446	  __imm_addr(map_hash_48b)447	: __clobber_all);448}449 450SEC("tracepoint")451__description("helper access to adjusted map (via const reg): out-of-bound range")452__failure __msg("invalid access to map value, value_size=48 off=4 size=52")453__naked void reg_out_of_bound_range(void)454{455	asm volatile ("					\456	r2 = r10;					\457	r2 += -8;					\458	r1 = 0;						\459	*(u64*)(r2 + 0) = r1;				\460	r1 = %[map_hash_48b] ll;			\461	call %[bpf_map_lookup_elem];			\462	if r0 == 0 goto l0_%=;				\463	r1 = r0;					\464	r3 = %[test_val_foo];				\465	r1 += r3;					\466	r2 = %[__imm_0];				\467	r3 = 0;						\468	call %[bpf_probe_read_kernel];			\469l0_%=:	exit;						\470"	:471	: __imm(bpf_map_lookup_elem),472	  __imm(bpf_probe_read_kernel),473	  __imm_addr(map_hash_48b),474	  __imm_const(__imm_0, sizeof(struct test_val) - offsetof(struct test_val, foo) + 8),475	  __imm_const(test_val_foo, offsetof(struct test_val, foo))476	: __clobber_all);477}478 479SEC("tracepoint")480__description("helper access to adjusted map (via const reg): negative range (> adjustment)")481__failure __msg("R2 min value is negative")482__naked void const_reg_negative_range_adjustment_1(void)483{484	asm volatile ("					\485	r2 = r10;					\486	r2 += -8;					\487	r1 = 0;						\488	*(u64*)(r2 + 0) = r1;				\489	r1 = %[map_hash_48b] ll;			\490	call %[bpf_map_lookup_elem];			\491	if r0 == 0 goto l0_%=;				\492	r1 = r0;					\493	r3 = %[test_val_foo];				\494	r1 += r3;					\495	r2 = -8;					\496	r3 = 0;						\497	call %[bpf_probe_read_kernel];			\498l0_%=:	exit;						\499"	:500	: __imm(bpf_map_lookup_elem),501	  __imm(bpf_probe_read_kernel),502	  __imm_addr(map_hash_48b),503	  __imm_const(test_val_foo, offsetof(struct test_val, foo))504	: __clobber_all);505}506 507SEC("tracepoint")508__description("helper access to adjusted map (via const reg): negative range (< adjustment)")509__failure __msg("R2 min value is negative")510__naked void const_reg_negative_range_adjustment_2(void)511{512	asm volatile ("					\513	r2 = r10;					\514	r2 += -8;					\515	r1 = 0;						\516	*(u64*)(r2 + 0) = r1;				\517	r1 = %[map_hash_48b] ll;			\518	call %[bpf_map_lookup_elem];			\519	if r0 == 0 goto l0_%=;				\520	r1 = r0;					\521	r3 = %[test_val_foo];				\522	r1 += r3;					\523	r2 = -1;					\524	r3 = 0;						\525	call %[bpf_probe_read_kernel];			\526l0_%=:	exit;						\527"	:528	: __imm(bpf_map_lookup_elem),529	  __imm(bpf_probe_read_kernel),530	  __imm_addr(map_hash_48b),531	  __imm_const(test_val_foo, offsetof(struct test_val, foo))532	: __clobber_all);533}534 535SEC("tracepoint")536__description("helper access to adjusted map (via variable): full range")537__success538__naked void map_via_variable_full_range(void)539{540	asm volatile ("					\541	r2 = r10;					\542	r2 += -8;					\543	r1 = 0;						\544	*(u64*)(r2 + 0) = r1;				\545	r1 = %[map_hash_48b] ll;			\546	call %[bpf_map_lookup_elem];			\547	if r0 == 0 goto l0_%=;				\548	r1 = r0;					\549	r3 = *(u32*)(r0 + 0);				\550	if r3 > %[test_val_foo] goto l0_%=;		\551	r1 += r3;					\552	r2 = %[__imm_0];				\553	r3 = 0;						\554	call %[bpf_probe_read_kernel];			\555l0_%=:	exit;						\556"	:557	: __imm(bpf_map_lookup_elem),558	  __imm(bpf_probe_read_kernel),559	  __imm_addr(map_hash_48b),560	  __imm_const(__imm_0, sizeof(struct test_val) - offsetof(struct test_val, foo)),561	  __imm_const(test_val_foo, offsetof(struct test_val, foo))562	: __clobber_all);563}564 565SEC("tracepoint")566__description("helper access to adjusted map (via variable): partial range")567__success568__naked void map_via_variable_partial_range(void)569{570	asm volatile ("					\571	r2 = r10;					\572	r2 += -8;					\573	r1 = 0;						\574	*(u64*)(r2 + 0) = r1;				\575	r1 = %[map_hash_48b] ll;			\576	call %[bpf_map_lookup_elem];			\577	if r0 == 0 goto l0_%=;				\578	r1 = r0;					\579	r3 = *(u32*)(r0 + 0);				\580	if r3 > %[test_val_foo] goto l0_%=;		\581	r1 += r3;					\582	r2 = 8;						\583	r3 = 0;						\584	call %[bpf_probe_read_kernel];			\585l0_%=:	exit;						\586"	:587	: __imm(bpf_map_lookup_elem),588	  __imm(bpf_probe_read_kernel),589	  __imm_addr(map_hash_48b),590	  __imm_const(test_val_foo, offsetof(struct test_val, foo))591	: __clobber_all);592}593 594SEC("tracepoint")595__description("helper access to adjusted map (via variable): empty range")596__failure __msg("R2 invalid zero-sized read")597__naked void map_via_variable_empty_range(void)598{599	asm volatile ("					\600	r2 = r10;					\601	r2 += -8;					\602	r1 = 0;						\603	*(u64*)(r2 + 0) = r1;				\604	r1 = %[map_hash_48b] ll;			\605	call %[bpf_map_lookup_elem];			\606	if r0 == 0 goto l0_%=;				\607	r1 = r0;					\608	r3 = *(u32*)(r0 + 0);				\609	if r3 > %[test_val_foo] goto l0_%=;		\610	r1 += r3;					\611	r2 = 0;						\612	call %[bpf_trace_printk];			\613l0_%=:	exit;						\614"	:615	: __imm(bpf_map_lookup_elem),616	  __imm(bpf_trace_printk),617	  __imm_addr(map_hash_48b),618	  __imm_const(test_val_foo, offsetof(struct test_val, foo))619	: __clobber_all);620}621 622SEC("tracepoint")623__description("helper access to adjusted map (via variable): no max check")624__failure __msg("R1 unbounded memory access")625__naked void via_variable_no_max_check_1(void)626{627	asm volatile ("					\628	r2 = r10;					\629	r2 += -8;					\630	r1 = 0;						\631	*(u64*)(r2 + 0) = r1;				\632	r1 = %[map_hash_48b] ll;			\633	call %[bpf_map_lookup_elem];			\634	if r0 == 0 goto l0_%=;				\635	r1 = r0;					\636	r3 = *(u32*)(r0 + 0);				\637	r1 += r3;					\638	r2 = 1;						\639	r3 = 0;						\640	call %[bpf_probe_read_kernel];			\641l0_%=:	exit;						\642"	:643	: __imm(bpf_map_lookup_elem),644	  __imm(bpf_probe_read_kernel),645	  __imm_addr(map_hash_48b)646	: __clobber_all);647}648 649SEC("tracepoint")650__description("helper access to adjusted map (via variable): wrong max check")651__failure __msg("invalid access to map value, value_size=48 off=4 size=45")652__naked void via_variable_wrong_max_check_1(void)653{654	asm volatile ("					\655	r2 = r10;					\656	r2 += -8;					\657	r1 = 0;						\658	*(u64*)(r2 + 0) = r1;				\659	r1 = %[map_hash_48b] ll;			\660	call %[bpf_map_lookup_elem];			\661	if r0 == 0 goto l0_%=;				\662	r1 = r0;					\663	r3 = *(u32*)(r0 + 0);				\664	if r3 > %[test_val_foo] goto l0_%=;		\665	r1 += r3;					\666	r2 = %[__imm_0];				\667	r3 = 0;						\668	call %[bpf_probe_read_kernel];			\669l0_%=:	exit;						\670"	:671	: __imm(bpf_map_lookup_elem),672	  __imm(bpf_probe_read_kernel),673	  __imm_addr(map_hash_48b),674	  __imm_const(__imm_0, sizeof(struct test_val) - offsetof(struct test_val, foo) + 1),675	  __imm_const(test_val_foo, offsetof(struct test_val, foo))676	: __clobber_all);677}678 679SEC("tracepoint")680__description("helper access to map: bounds check using <, good access")681__success682__naked void bounds_check_using_good_access_1(void)683{684	asm volatile ("					\685	r2 = r10;					\686	r2 += -8;					\687	r1 = 0;						\688	*(u64*)(r2 + 0) = r1;				\689	r1 = %[map_hash_48b] ll;			\690	call %[bpf_map_lookup_elem];			\691	if r0 == 0 goto l0_%=;				\692	r1 = r0;					\693	r3 = *(u32*)(r0 + 0);				\694	if r3 < 32 goto l1_%=;				\695	r0 = 0;						\696l0_%=:	exit;						\697l1_%=:	r1 += r3;					\698	r0 = 0;						\699	*(u8*)(r1 + 0) = r0;				\700	r0 = 0;						\701	exit;						\702"	:703	: __imm(bpf_map_lookup_elem),704	  __imm_addr(map_hash_48b)705	: __clobber_all);706}707 708SEC("tracepoint")709__description("helper access to map: bounds check using <, bad access")710__failure __msg("R1 unbounded memory access")711__naked void bounds_check_using_bad_access_1(void)712{713	asm volatile ("					\714	r2 = r10;					\715	r2 += -8;					\716	r1 = 0;						\717	*(u64*)(r2 + 0) = r1;				\718	r1 = %[map_hash_48b] ll;			\719	call %[bpf_map_lookup_elem];			\720	if r0 == 0 goto l0_%=;				\721	r1 = r0;					\722	r3 = *(u32*)(r0 + 0);				\723	if r3 < 32 goto l1_%=;				\724	r1 += r3;					\725l0_%=:	r0 = 0;						\726	*(u8*)(r1 + 0) = r0;				\727	r0 = 0;						\728	exit;						\729l1_%=:	r0 = 0;						\730	exit;						\731"	:732	: __imm(bpf_map_lookup_elem),733	  __imm_addr(map_hash_48b)734	: __clobber_all);735}736 737SEC("tracepoint")738__description("helper access to map: bounds check using <=, good access")739__success740__naked void bounds_check_using_good_access_2(void)741{742	asm volatile ("					\743	r2 = r10;					\744	r2 += -8;					\745	r1 = 0;						\746	*(u64*)(r2 + 0) = r1;				\747	r1 = %[map_hash_48b] ll;			\748	call %[bpf_map_lookup_elem];			\749	if r0 == 0 goto l0_%=;				\750	r1 = r0;					\751	r3 = *(u32*)(r0 + 0);				\752	if r3 <= 32 goto l1_%=;				\753	r0 = 0;						\754l0_%=:	exit;						\755l1_%=:	r1 += r3;					\756	r0 = 0;						\757	*(u8*)(r1 + 0) = r0;				\758	r0 = 0;						\759	exit;						\760"	:761	: __imm(bpf_map_lookup_elem),762	  __imm_addr(map_hash_48b)763	: __clobber_all);764}765 766SEC("tracepoint")767__description("helper access to map: bounds check using <=, bad access")768__failure __msg("R1 unbounded memory access")769__naked void bounds_check_using_bad_access_2(void)770{771	asm volatile ("					\772	r2 = r10;					\773	r2 += -8;					\774	r1 = 0;						\775	*(u64*)(r2 + 0) = r1;				\776	r1 = %[map_hash_48b] ll;			\777	call %[bpf_map_lookup_elem];			\778	if r0 == 0 goto l0_%=;				\779	r1 = r0;					\780	r3 = *(u32*)(r0 + 0);				\781	if r3 <= 32 goto l1_%=;				\782	r1 += r3;					\783l0_%=:	r0 = 0;						\784	*(u8*)(r1 + 0) = r0;				\785	r0 = 0;						\786	exit;						\787l1_%=:	r0 = 0;						\788	exit;						\789"	:790	: __imm(bpf_map_lookup_elem),791	  __imm_addr(map_hash_48b)792	: __clobber_all);793}794 795SEC("tracepoint")796__description("helper access to map: bounds check using s<, good access")797__success798__naked void check_using_s_good_access_1(void)799{800	asm volatile ("					\801	r2 = r10;					\802	r2 += -8;					\803	r1 = 0;						\804	*(u64*)(r2 + 0) = r1;				\805	r1 = %[map_hash_48b] ll;			\806	call %[bpf_map_lookup_elem];			\807	if r0 == 0 goto l0_%=;				\808	r1 = r0;					\809	r3 = *(u32*)(r0 + 0);				\810	if r3 s< 32 goto l1_%=;				\811l2_%=:	r0 = 0;						\812l0_%=:	exit;						\813l1_%=:	if r3 s< 0 goto l2_%=;				\814	r1 += r3;					\815	r0 = 0;						\816	*(u8*)(r1 + 0) = r0;				\817	r0 = 0;						\818	exit;						\819"	:820	: __imm(bpf_map_lookup_elem),821	  __imm_addr(map_hash_48b)822	: __clobber_all);823}824 825SEC("tracepoint")826__description("helper access to map: bounds check using s<, good access 2")827__success828__naked void using_s_good_access_2_1(void)829{830	asm volatile ("					\831	r2 = r10;					\832	r2 += -8;					\833	r1 = 0;						\834	*(u64*)(r2 + 0) = r1;				\835	r1 = %[map_hash_48b] ll;			\836	call %[bpf_map_lookup_elem];			\837	if r0 == 0 goto l0_%=;				\838	r1 = r0;					\839	r3 = *(u32*)(r0 + 0);				\840	if r3 s< 32 goto l1_%=;				\841l2_%=:	r0 = 0;						\842l0_%=:	exit;						\843l1_%=:	if r3 s< -3 goto l2_%=;				\844	r1 += r3;					\845	r0 = 0;						\846	*(u8*)(r1 + 0) = r0;				\847	r0 = 0;						\848	exit;						\849"	:850	: __imm(bpf_map_lookup_elem),851	  __imm_addr(map_hash_48b)852	: __clobber_all);853}854 855SEC("tracepoint")856__description("helper access to map: bounds check using s<, bad access")857__failure __msg("R1 min value is negative")858__naked void check_using_s_bad_access_1(void)859{860	asm volatile ("					\861	r2 = r10;					\862	r2 += -8;					\863	r1 = 0;						\864	*(u64*)(r2 + 0) = r1;				\865	r1 = %[map_hash_48b] ll;			\866	call %[bpf_map_lookup_elem];			\867	if r0 == 0 goto l0_%=;				\868	r1 = r0;					\869	r3 = *(u64*)(r0 + 0);				\870	if r3 s< 32 goto l1_%=;				\871l2_%=:	r0 = 0;						\872l0_%=:	exit;						\873l1_%=:	if r3 s< -3 goto l2_%=;				\874	r1 += r3;					\875	r0 = 0;						\876	*(u8*)(r1 + 0) = r0;				\877	r0 = 0;						\878	exit;						\879"	:880	: __imm(bpf_map_lookup_elem),881	  __imm_addr(map_hash_48b)882	: __clobber_all);883}884 885SEC("tracepoint")886__description("helper access to map: bounds check using s<=, good access")887__success888__naked void check_using_s_good_access_2(void)889{890	asm volatile ("					\891	r2 = r10;					\892	r2 += -8;					\893	r1 = 0;						\894	*(u64*)(r2 + 0) = r1;				\895	r1 = %[map_hash_48b] ll;			\896	call %[bpf_map_lookup_elem];			\897	if r0 == 0 goto l0_%=;				\898	r1 = r0;					\899	r3 = *(u32*)(r0 + 0);				\900	if r3 s<= 32 goto l1_%=;			\901l2_%=:	r0 = 0;						\902l0_%=:	exit;						\903l1_%=:	if r3 s<= 0 goto l2_%=;				\904	r1 += r3;					\905	r0 = 0;						\906	*(u8*)(r1 + 0) = r0;				\907	r0 = 0;						\908	exit;						\909"	:910	: __imm(bpf_map_lookup_elem),911	  __imm_addr(map_hash_48b)912	: __clobber_all);913}914 915SEC("tracepoint")916__description("helper access to map: bounds check using s<=, good access 2")917__success918__naked void using_s_good_access_2_2(void)919{920	asm volatile ("					\921	r2 = r10;					\922	r2 += -8;					\923	r1 = 0;						\924	*(u64*)(r2 + 0) = r1;				\925	r1 = %[map_hash_48b] ll;			\926	call %[bpf_map_lookup_elem];			\927	if r0 == 0 goto l0_%=;				\928	r1 = r0;					\929	r3 = *(u32*)(r0 + 0);				\930	if r3 s<= 32 goto l1_%=;			\931l2_%=:	r0 = 0;						\932l0_%=:	exit;						\933l1_%=:	if r3 s<= -3 goto l2_%=;			\934	r1 += r3;					\935	r0 = 0;						\936	*(u8*)(r1 + 0) = r0;				\937	r0 = 0;						\938	exit;						\939"	:940	: __imm(bpf_map_lookup_elem),941	  __imm_addr(map_hash_48b)942	: __clobber_all);943}944 945SEC("tracepoint")946__description("helper access to map: bounds check using s<=, bad access")947__failure __msg("R1 min value is negative")948__naked void check_using_s_bad_access_2(void)949{950	asm volatile ("					\951	r2 = r10;					\952	r2 += -8;					\953	r1 = 0;						\954	*(u64*)(r2 + 0) = r1;				\955	r1 = %[map_hash_48b] ll;			\956	call %[bpf_map_lookup_elem];			\957	if r0 == 0 goto l0_%=;				\958	r1 = r0;					\959	r3 = *(u64*)(r0 + 0);				\960	if r3 s<= 32 goto l1_%=;			\961l2_%=:	r0 = 0;						\962l0_%=:	exit;						\963l1_%=:	if r3 s<= -3 goto l2_%=;			\964	r1 += r3;					\965	r0 = 0;						\966	*(u8*)(r1 + 0) = r0;				\967	r0 = 0;						\968	exit;						\969"	:970	: __imm(bpf_map_lookup_elem),971	  __imm_addr(map_hash_48b)972	: __clobber_all);973}974 975SEC("tracepoint")976__description("map lookup helper access to map")977__success978__naked void lookup_helper_access_to_map(void)979{980	asm volatile ("					\981	r2 = r10;					\982	r2 += -8;					\983	r1 = 0;						\984	*(u64*)(r2 + 0) = r1;				\985	r1 = %[map_hash_16b] ll;			\986	call %[bpf_map_lookup_elem];			\987	if r0 == 0 goto l0_%=;				\988	r2 = r0;					\989	r1 = %[map_hash_16b] ll;			\990	call %[bpf_map_lookup_elem];			\991l0_%=:	exit;						\992"	:993	: __imm(bpf_map_lookup_elem),994	  __imm_addr(map_hash_16b)995	: __clobber_all);996}997 998SEC("tracepoint")999__description("map update helper access to map")1000__success1001__naked void update_helper_access_to_map(void)1002{1003	asm volatile ("					\1004	r2 = r10;					\1005	r2 += -8;					\1006	r1 = 0;						\1007	*(u64*)(r2 + 0) = r1;				\1008	r1 = %[map_hash_16b] ll;			\1009	call %[bpf_map_lookup_elem];			\1010	if r0 == 0 goto l0_%=;				\1011	r4 = 0;						\1012	r3 = r0;					\1013	r2 = r0;					\1014	r1 = %[map_hash_16b] ll;			\1015	call %[bpf_map_update_elem];			\1016l0_%=:	exit;						\1017"	:1018	: __imm(bpf_map_lookup_elem),1019	  __imm(bpf_map_update_elem),1020	  __imm_addr(map_hash_16b)1021	: __clobber_all);1022}1023 1024SEC("tracepoint")1025__description("map update helper access to map: wrong size")1026__failure __msg("invalid access to map value, value_size=8 off=0 size=16")1027__naked void access_to_map_wrong_size(void)1028{1029	asm volatile ("					\1030	r2 = r10;					\1031	r2 += -8;					\1032	r1 = 0;						\1033	*(u64*)(r2 + 0) = r1;				\1034	r1 = %[map_hash_8b] ll;				\1035	call %[bpf_map_lookup_elem];			\1036	if r0 == 0 goto l0_%=;				\1037	r4 = 0;						\1038	r3 = r0;					\1039	r2 = r0;					\1040	r1 = %[map_hash_16b] ll;			\1041	call %[bpf_map_update_elem];			\1042l0_%=:	exit;						\1043"	:1044	: __imm(bpf_map_lookup_elem),1045	  __imm(bpf_map_update_elem),1046	  __imm_addr(map_hash_16b),1047	  __imm_addr(map_hash_8b)1048	: __clobber_all);1049}1050 1051SEC("tracepoint")1052__description("map helper access to adjusted map (via const imm)")1053__success1054__naked void adjusted_map_via_const_imm(void)1055{1056	asm volatile ("					\1057	r2 = r10;					\1058	r2 += -8;					\1059	r1 = 0;						\1060	*(u64*)(r2 + 0) = r1;				\1061	r1 = %[map_hash_16b] ll;			\1062	call %[bpf_map_lookup_elem];			\1063	if r0 == 0 goto l0_%=;				\1064	r2 = r0;					\1065	r2 += %[other_val_bar];				\1066	r1 = %[map_hash_16b] ll;			\1067	call %[bpf_map_lookup_elem];			\1068l0_%=:	exit;						\1069"	:1070	: __imm(bpf_map_lookup_elem),1071	  __imm_addr(map_hash_16b),1072	  __imm_const(other_val_bar, offsetof(struct other_val, bar))1073	: __clobber_all);1074}1075 1076SEC("tracepoint")1077__description("map helper access to adjusted map (via const imm): out-of-bound 1")1078__failure __msg("invalid access to map value, value_size=16 off=12 size=8")1079__naked void imm_out_of_bound_1(void)1080{1081	asm volatile ("					\1082	r2 = r10;					\1083	r2 += -8;					\1084	r1 = 0;						\1085	*(u64*)(r2 + 0) = r1;				\1086	r1 = %[map_hash_16b] ll;			\1087	call %[bpf_map_lookup_elem];			\1088	if r0 == 0 goto l0_%=;				\1089	r2 = r0;					\1090	r2 += %[__imm_0];				\1091	r1 = %[map_hash_16b] ll;			\1092	call %[bpf_map_lookup_elem];			\1093l0_%=:	exit;						\1094"	:1095	: __imm(bpf_map_lookup_elem),1096	  __imm_addr(map_hash_16b),1097	  __imm_const(__imm_0, sizeof(struct other_val) - 4)1098	: __clobber_all);1099}1100 1101SEC("tracepoint")1102__description("map helper access to adjusted map (via const imm): out-of-bound 2")1103__failure __msg("invalid access to map value, value_size=16 off=-4 size=8")1104__naked void imm_out_of_bound_2(void)1105{1106	asm volatile ("					\1107	r2 = r10;					\1108	r2 += -8;					\1109	r1 = 0;						\1110	*(u64*)(r2 + 0) = r1;				\1111	r1 = %[map_hash_16b] ll;			\1112	call %[bpf_map_lookup_elem];			\1113	if r0 == 0 goto l0_%=;				\1114	r2 = r0;					\1115	r2 += -4;					\1116	r1 = %[map_hash_16b] ll;			\1117	call %[bpf_map_lookup_elem];			\1118l0_%=:	exit;						\1119"	:1120	: __imm(bpf_map_lookup_elem),1121	  __imm_addr(map_hash_16b)1122	: __clobber_all);1123}1124 1125SEC("tracepoint")1126__description("map helper access to adjusted map (via const reg)")1127__success1128__naked void adjusted_map_via_const_reg(void)1129{1130	asm volatile ("					\1131	r2 = r10;					\1132	r2 += -8;					\1133	r1 = 0;						\1134	*(u64*)(r2 + 0) = r1;				\1135	r1 = %[map_hash_16b] ll;			\1136	call %[bpf_map_lookup_elem];			\1137	if r0 == 0 goto l0_%=;				\1138	r2 = r0;					\1139	r3 = %[other_val_bar];				\1140	r2 += r3;					\1141	r1 = %[map_hash_16b] ll;			\1142	call %[bpf_map_lookup_elem];			\1143l0_%=:	exit;						\1144"	:1145	: __imm(bpf_map_lookup_elem),1146	  __imm_addr(map_hash_16b),1147	  __imm_const(other_val_bar, offsetof(struct other_val, bar))1148	: __clobber_all);1149}1150 1151SEC("tracepoint")1152__description("map helper access to adjusted map (via const reg): out-of-bound 1")1153__failure __msg("invalid access to map value, value_size=16 off=12 size=8")1154__naked void reg_out_of_bound_1(void)1155{1156	asm volatile ("					\1157	r2 = r10;					\1158	r2 += -8;					\1159	r1 = 0;						\1160	*(u64*)(r2 + 0) = r1;				\1161	r1 = %[map_hash_16b] ll;			\1162	call %[bpf_map_lookup_elem];			\1163	if r0 == 0 goto l0_%=;				\1164	r2 = r0;					\1165	r3 = %[__imm_0];				\1166	r2 += r3;					\1167	r1 = %[map_hash_16b] ll;			\1168	call %[bpf_map_lookup_elem];			\1169l0_%=:	exit;						\1170"	:1171	: __imm(bpf_map_lookup_elem),1172	  __imm_addr(map_hash_16b),1173	  __imm_const(__imm_0, sizeof(struct other_val) - 4)1174	: __clobber_all);1175}1176 1177SEC("tracepoint")1178__description("map helper access to adjusted map (via const reg): out-of-bound 2")1179__failure __msg("invalid access to map value, value_size=16 off=-4 size=8")1180__naked void reg_out_of_bound_2(void)1181{1182	asm volatile ("					\1183	r2 = r10;					\1184	r2 += -8;					\1185	r1 = 0;						\1186	*(u64*)(r2 + 0) = r1;				\1187	r1 = %[map_hash_16b] ll;			\1188	call %[bpf_map_lookup_elem];			\1189	if r0 == 0 goto l0_%=;				\1190	r2 = r0;					\1191	r3 = -4;					\1192	r2 += r3;					\1193	r1 = %[map_hash_16b] ll;			\1194	call %[bpf_map_lookup_elem];			\1195l0_%=:	exit;						\1196"	:1197	: __imm(bpf_map_lookup_elem),1198	  __imm_addr(map_hash_16b)1199	: __clobber_all);1200}1201 1202SEC("tracepoint")1203__description("map helper access to adjusted map (via variable)")1204__success1205__naked void to_adjusted_map_via_variable(void)1206{1207	asm volatile ("					\1208	r2 = r10;					\1209	r2 += -8;					\1210	r1 = 0;						\1211	*(u64*)(r2 + 0) = r1;				\1212	r1 = %[map_hash_16b] ll;			\1213	call %[bpf_map_lookup_elem];			\1214	if r0 == 0 goto l0_%=;				\1215	r2 = r0;					\1216	r3 = *(u32*)(r0 + 0);				\1217	if r3 > %[other_val_bar] goto l0_%=;		\1218	r2 += r3;					\1219	r1 = %[map_hash_16b] ll;			\1220	call %[bpf_map_lookup_elem];			\1221l0_%=:	exit;						\1222"	:1223	: __imm(bpf_map_lookup_elem),1224	  __imm_addr(map_hash_16b),1225	  __imm_const(other_val_bar, offsetof(struct other_val, bar))1226	: __clobber_all);1227}1228 1229SEC("tracepoint")1230__description("map helper access to adjusted map (via variable): no max check")1231__failure1232__msg("R2 unbounded memory access, make sure to bounds check any such access")1233__naked void via_variable_no_max_check_2(void)1234{1235	asm volatile ("					\1236	r2 = r10;					\1237	r2 += -8;					\1238	r1 = 0;						\1239	*(u64*)(r2 + 0) = r1;				\1240	r1 = %[map_hash_16b] ll;			\1241	call %[bpf_map_lookup_elem];			\1242	if r0 == 0 goto l0_%=;				\1243	r2 = r0;					\1244	r3 = *(u32*)(r0 + 0);				\1245	r2 += r3;					\1246	r1 = %[map_hash_16b] ll;			\1247	call %[bpf_map_lookup_elem];			\1248l0_%=:	exit;						\1249"	:1250	: __imm(bpf_map_lookup_elem),1251	  __imm_addr(map_hash_16b)1252	: __clobber_all);1253}1254 1255SEC("tracepoint")1256__description("map helper access to adjusted map (via variable): wrong max check")1257__failure __msg("invalid access to map value, value_size=16 off=9 size=8")1258__naked void via_variable_wrong_max_check_2(void)1259{1260	asm volatile ("					\1261	r2 = r10;					\1262	r2 += -8;					\1263	r1 = 0;						\1264	*(u64*)(r2 + 0) = r1;				\1265	r1 = %[map_hash_16b] ll;			\1266	call %[bpf_map_lookup_elem];			\1267	if r0 == 0 goto l0_%=;				\1268	r2 = r0;					\1269	r3 = *(u32*)(r0 + 0);				\1270	if r3 > %[__imm_0] goto l0_%=;			\1271	r2 += r3;					\1272	r1 = %[map_hash_16b] ll;			\1273	call %[bpf_map_lookup_elem];			\1274l0_%=:	exit;						\1275"	:1276	: __imm(bpf_map_lookup_elem),1277	  __imm_addr(map_hash_16b),1278	  __imm_const(__imm_0, offsetof(struct other_val, bar) + 1)1279	: __clobber_all);1280}1281 1282char _license[] SEC("license") = "GPL";1283