brintos

brintos / linux-shallow public Read only

0
0
Text · 24.6 KiB · ee76b51 Raw
981 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Converted from tools/testing/selftests/bpf/verifier/sock.c */3 4#include <linux/bpf.h>5#include <bpf/bpf_helpers.h>6#include "bpf_misc.h"7 8#define sizeof_field(TYPE, MEMBER) sizeof((((TYPE *)0)->MEMBER))9#define offsetofend(TYPE, MEMBER) \10	(offsetof(TYPE, MEMBER)	+ sizeof_field(TYPE, MEMBER))11 12struct {13	__uint(type, BPF_MAP_TYPE_REUSEPORT_SOCKARRAY);14	__uint(max_entries, 1);15	__type(key, __u32);16	__type(value, __u64);17} map_reuseport_array SEC(".maps");18 19struct {20	__uint(type, BPF_MAP_TYPE_SOCKHASH);21	__uint(max_entries, 1);22	__type(key, int);23	__type(value, int);24} map_sockhash SEC(".maps");25 26struct {27	__uint(type, BPF_MAP_TYPE_SOCKMAP);28	__uint(max_entries, 1);29	__type(key, int);30	__type(value, int);31} map_sockmap SEC(".maps");32 33struct {34	__uint(type, BPF_MAP_TYPE_XSKMAP);35	__uint(max_entries, 1);36	__type(key, int);37	__type(value, int);38} map_xskmap SEC(".maps");39 40struct val {41	int cnt;42	struct bpf_spin_lock l;43};44 45struct {46	__uint(type, BPF_MAP_TYPE_SK_STORAGE);47	__uint(max_entries, 0);48	__type(key, int);49	__type(value, struct val);50	__uint(map_flags, BPF_F_NO_PREALLOC);51} sk_storage_map SEC(".maps");52 53SEC("cgroup/skb")54__description("skb->sk: no NULL check")55__failure __msg("invalid mem access 'sock_common_or_null'")56__failure_unpriv57__naked void skb_sk_no_null_check(void)58{59	asm volatile ("					\60	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\61	r0 = *(u32*)(r1 + 0);				\62	r0 = 0;						\63	exit;						\64"	:65	: __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk))66	: __clobber_all);67}68 69SEC("cgroup/skb")70__description("skb->sk: sk->family [non fullsock field]")71__success __success_unpriv __retval(0)72__naked void sk_family_non_fullsock_field_1(void)73{74	asm volatile ("					\75	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\76	if r1 != 0 goto l0_%=;				\77	r0 = 0;						\78	exit;						\79l0_%=:	r0 = *(u32*)(r1 + %[bpf_sock_family]);		\80	r0 = 0;						\81	exit;						\82"	:83	: __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),84	  __imm_const(bpf_sock_family, offsetof(struct bpf_sock, family))85	: __clobber_all);86}87 88SEC("cgroup/skb")89__description("skb->sk: sk->type [fullsock field]")90__failure __msg("invalid sock_common access")91__failure_unpriv92__naked void sk_sk_type_fullsock_field_1(void)93{94	asm volatile ("					\95	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\96	if r1 != 0 goto l0_%=;				\97	r0 = 0;						\98	exit;						\99l0_%=:	r0 = *(u32*)(r1 + %[bpf_sock_type]);		\100	r0 = 0;						\101	exit;						\102"	:103	: __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),104	  __imm_const(bpf_sock_type, offsetof(struct bpf_sock, type))105	: __clobber_all);106}107 108SEC("cgroup/skb")109__description("bpf_sk_fullsock(skb->sk): no !skb->sk check")110__failure __msg("type=sock_common_or_null expected=sock_common")111__failure_unpriv112__naked void sk_no_skb_sk_check_1(void)113{114	asm volatile ("					\115	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\116	call %[bpf_sk_fullsock];			\117	r0 = 0;						\118	exit;						\119"	:120	: __imm(bpf_sk_fullsock),121	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk))122	: __clobber_all);123}124 125SEC("cgroup/skb")126__description("sk_fullsock(skb->sk): no NULL check on ret")127__failure __msg("invalid mem access 'sock_or_null'")128__failure_unpriv129__naked void no_null_check_on_ret_1(void)130{131	asm volatile ("					\132	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\133	if r1 != 0 goto l0_%=;				\134	r0 = 0;						\135	exit;						\136l0_%=:	call %[bpf_sk_fullsock];			\137	r0 = *(u32*)(r0 + %[bpf_sock_type]);		\138	r0 = 0;						\139	exit;						\140"	:141	: __imm(bpf_sk_fullsock),142	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),143	  __imm_const(bpf_sock_type, offsetof(struct bpf_sock, type))144	: __clobber_all);145}146 147SEC("cgroup/skb")148__description("sk_fullsock(skb->sk): sk->type [fullsock field]")149__success __success_unpriv __retval(0)150__naked void sk_sk_type_fullsock_field_2(void)151{152	asm volatile ("					\153	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\154	if r1 != 0 goto l0_%=;				\155	r0 = 0;						\156	exit;						\157l0_%=:	call %[bpf_sk_fullsock];			\158	if r0 != 0 goto l1_%=;				\159	r0 = 0;						\160	exit;						\161l1_%=:	r0 = *(u32*)(r0 + %[bpf_sock_type]);		\162	r0 = 0;						\163	exit;						\164"	:165	: __imm(bpf_sk_fullsock),166	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),167	  __imm_const(bpf_sock_type, offsetof(struct bpf_sock, type))168	: __clobber_all);169}170 171SEC("cgroup/skb")172__description("sk_fullsock(skb->sk): sk->family [non fullsock field]")173__success __success_unpriv __retval(0)174__naked void sk_family_non_fullsock_field_2(void)175{176	asm volatile ("					\177	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\178	if r1 != 0 goto l0_%=;				\179	r0 = 0;						\180	exit;						\181l0_%=:	call %[bpf_sk_fullsock];			\182	if r0 != 0 goto l1_%=;				\183	exit;						\184l1_%=:	r0 = *(u32*)(r0 + %[bpf_sock_family]);		\185	r0 = 0;						\186	exit;						\187"	:188	: __imm(bpf_sk_fullsock),189	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),190	  __imm_const(bpf_sock_family, offsetof(struct bpf_sock, family))191	: __clobber_all);192}193 194SEC("cgroup/skb")195__description("sk_fullsock(skb->sk): sk->state [narrow load]")196__success __success_unpriv __retval(0)197__naked void sk_sk_state_narrow_load(void)198{199	asm volatile ("					\200	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\201	if r1 != 0 goto l0_%=;				\202	r0 = 0;						\203	exit;						\204l0_%=:	call %[bpf_sk_fullsock];			\205	if r0 != 0 goto l1_%=;				\206	r0 = 0;						\207	exit;						\208l1_%=:	r0 = *(u8*)(r0 + %[bpf_sock_state]);		\209	r0 = 0;						\210	exit;						\211"	:212	: __imm(bpf_sk_fullsock),213	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),214	  __imm_const(bpf_sock_state, offsetof(struct bpf_sock, state))215	: __clobber_all);216}217 218SEC("cgroup/skb")219__description("sk_fullsock(skb->sk): sk->dst_port [word load] (backward compatibility)")220__success __success_unpriv __retval(0)221__naked void port_word_load_backward_compatibility(void)222{223	asm volatile ("					\224	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\225	if r1 != 0 goto l0_%=;				\226	r0 = 0;						\227	exit;						\228l0_%=:	call %[bpf_sk_fullsock];			\229	if r0 != 0 goto l1_%=;				\230	r0 = 0;						\231	exit;						\232l1_%=:	r0 = *(u32*)(r0 + %[bpf_sock_dst_port]);	\233	r0 = 0;						\234	exit;						\235"	:236	: __imm(bpf_sk_fullsock),237	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),238	  __imm_const(bpf_sock_dst_port, offsetof(struct bpf_sock, dst_port))239	: __clobber_all);240}241 242SEC("cgroup/skb")243__description("sk_fullsock(skb->sk): sk->dst_port [half load]")244__success __success_unpriv __retval(0)245__naked void sk_dst_port_half_load(void)246{247	asm volatile ("					\248	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\249	if r1 != 0 goto l0_%=;				\250	r0 = 0;						\251	exit;						\252l0_%=:	call %[bpf_sk_fullsock];			\253	if r0 != 0 goto l1_%=;				\254	r0 = 0;						\255	exit;						\256l1_%=:	r0 = *(u16*)(r0 + %[bpf_sock_dst_port]);	\257	r0 = 0;						\258	exit;						\259"	:260	: __imm(bpf_sk_fullsock),261	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),262	  __imm_const(bpf_sock_dst_port, offsetof(struct bpf_sock, dst_port))263	: __clobber_all);264}265 266SEC("cgroup/skb")267__description("sk_fullsock(skb->sk): sk->dst_port [half load] (invalid)")268__failure __msg("invalid sock access")269__failure_unpriv270__naked void dst_port_half_load_invalid_1(void)271{272	asm volatile ("					\273	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\274	if r1 != 0 goto l0_%=;				\275	r0 = 0;						\276	exit;						\277l0_%=:	call %[bpf_sk_fullsock];			\278	if r0 != 0 goto l1_%=;				\279	r0 = 0;						\280	exit;						\281l1_%=:	r0 = *(u16*)(r0 + %[__imm_0]);			\282	r0 = 0;						\283	exit;						\284"	:285	: __imm(bpf_sk_fullsock),286	  __imm_const(__imm_0, offsetof(struct bpf_sock, dst_port) + 2),287	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk))288	: __clobber_all);289}290 291SEC("cgroup/skb")292__description("sk_fullsock(skb->sk): sk->dst_port [byte load]")293__success __success_unpriv __retval(0)294__naked void sk_dst_port_byte_load(void)295{296	asm volatile ("					\297	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\298	if r1 != 0 goto l0_%=;				\299	r0 = 0;						\300	exit;						\301l0_%=:	call %[bpf_sk_fullsock];			\302	if r0 != 0 goto l1_%=;				\303	r0 = 0;						\304	exit;						\305l1_%=:	r2 = *(u8*)(r0 + %[bpf_sock_dst_port]);		\306	r2 = *(u8*)(r0 + %[__imm_0]);			\307	r0 = 0;						\308	exit;						\309"	:310	: __imm(bpf_sk_fullsock),311	  __imm_const(__imm_0, offsetof(struct bpf_sock, dst_port) + 1),312	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),313	  __imm_const(bpf_sock_dst_port, offsetof(struct bpf_sock, dst_port))314	: __clobber_all);315}316 317SEC("cgroup/skb")318__description("sk_fullsock(skb->sk): sk->dst_port [byte load] (invalid)")319__failure __msg("invalid sock access")320__failure_unpriv321__naked void dst_port_byte_load_invalid(void)322{323	asm volatile ("					\324	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\325	if r1 != 0 goto l0_%=;				\326	r0 = 0;						\327	exit;						\328l0_%=:	call %[bpf_sk_fullsock];			\329	if r0 != 0 goto l1_%=;				\330	r0 = 0;						\331	exit;						\332l1_%=:	r0 = *(u8*)(r0 + %[__imm_0]);			\333	r0 = 0;						\334	exit;						\335"	:336	: __imm(bpf_sk_fullsock),337	  __imm_const(__imm_0, offsetof(struct bpf_sock, dst_port) + 2),338	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk))339	: __clobber_all);340}341 342SEC("cgroup/skb")343__description("sk_fullsock(skb->sk): past sk->dst_port [half load] (invalid)")344__failure __msg("invalid sock access")345__failure_unpriv346__naked void dst_port_half_load_invalid_2(void)347{348	asm volatile ("					\349	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\350	if r1 != 0 goto l0_%=;				\351	r0 = 0;						\352	exit;						\353l0_%=:	call %[bpf_sk_fullsock];			\354	if r0 != 0 goto l1_%=;				\355	r0 = 0;						\356	exit;						\357l1_%=:	r0 = *(u16*)(r0 + %[bpf_sock_dst_port__end]);	\358	r0 = 0;						\359	exit;						\360"	:361	: __imm(bpf_sk_fullsock),362	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),363	  __imm_const(bpf_sock_dst_port__end, offsetofend(struct bpf_sock, dst_port))364	: __clobber_all);365}366 367SEC("cgroup/skb")368__description("sk_fullsock(skb->sk): sk->dst_ip6 [load 2nd byte]")369__success __success_unpriv __retval(0)370__naked void dst_ip6_load_2nd_byte(void)371{372	asm volatile ("					\373	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\374	if r1 != 0 goto l0_%=;				\375	r0 = 0;						\376	exit;						\377l0_%=:	call %[bpf_sk_fullsock];			\378	if r0 != 0 goto l1_%=;				\379	r0 = 0;						\380	exit;						\381l1_%=:	r0 = *(u8*)(r0 + %[__imm_0]);			\382	r0 = 0;						\383	exit;						\384"	:385	: __imm(bpf_sk_fullsock),386	  __imm_const(__imm_0, offsetof(struct bpf_sock, dst_ip6[0]) + 1),387	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk))388	: __clobber_all);389}390 391SEC("cgroup/skb")392__description("sk_fullsock(skb->sk): sk->type [narrow load]")393__success __success_unpriv __retval(0)394__naked void sk_sk_type_narrow_load(void)395{396	asm volatile ("					\397	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\398	if r1 != 0 goto l0_%=;				\399	r0 = 0;						\400	exit;						\401l0_%=:	call %[bpf_sk_fullsock];			\402	if r0 != 0 goto l1_%=;				\403	r0 = 0;						\404	exit;						\405l1_%=:	r0 = *(u8*)(r0 + %[bpf_sock_type]);		\406	r0 = 0;						\407	exit;						\408"	:409	: __imm(bpf_sk_fullsock),410	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),411	  __imm_const(bpf_sock_type, offsetof(struct bpf_sock, type))412	: __clobber_all);413}414 415SEC("cgroup/skb")416__description("sk_fullsock(skb->sk): sk->protocol [narrow load]")417__success __success_unpriv __retval(0)418__naked void sk_sk_protocol_narrow_load(void)419{420	asm volatile ("					\421	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\422	if r1 != 0 goto l0_%=;				\423	r0 = 0;						\424	exit;						\425l0_%=:	call %[bpf_sk_fullsock];			\426	if r0 != 0 goto l1_%=;				\427	r0 = 0;						\428	exit;						\429l1_%=:	r0 = *(u8*)(r0 + %[bpf_sock_protocol]);		\430	r0 = 0;						\431	exit;						\432"	:433	: __imm(bpf_sk_fullsock),434	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),435	  __imm_const(bpf_sock_protocol, offsetof(struct bpf_sock, protocol))436	: __clobber_all);437}438 439SEC("cgroup/skb")440__description("sk_fullsock(skb->sk): beyond last field")441__failure __msg("invalid sock access")442__failure_unpriv443__naked void skb_sk_beyond_last_field_1(void)444{445	asm volatile ("					\446	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\447	if r1 != 0 goto l0_%=;				\448	r0 = 0;						\449	exit;						\450l0_%=:	call %[bpf_sk_fullsock];			\451	if r0 != 0 goto l1_%=;				\452	r0 = 0;						\453	exit;						\454l1_%=:	r0 = *(u32*)(r0 + %[bpf_sock_rx_queue_mapping__end]);\455	r0 = 0;						\456	exit;						\457"	:458	: __imm(bpf_sk_fullsock),459	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),460	  __imm_const(bpf_sock_rx_queue_mapping__end, offsetofend(struct bpf_sock, rx_queue_mapping))461	: __clobber_all);462}463 464SEC("cgroup/skb")465__description("bpf_tcp_sock(skb->sk): no !skb->sk check")466__failure __msg("type=sock_common_or_null expected=sock_common")467__failure_unpriv468__naked void sk_no_skb_sk_check_2(void)469{470	asm volatile ("					\471	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\472	call %[bpf_tcp_sock];				\473	r0 = 0;						\474	exit;						\475"	:476	: __imm(bpf_tcp_sock),477	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk))478	: __clobber_all);479}480 481SEC("cgroup/skb")482__description("bpf_tcp_sock(skb->sk): no NULL check on ret")483__failure __msg("invalid mem access 'tcp_sock_or_null'")484__failure_unpriv485__naked void no_null_check_on_ret_2(void)486{487	asm volatile ("					\488	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\489	if r1 != 0 goto l0_%=;				\490	r0 = 0;						\491	exit;						\492l0_%=:	call %[bpf_tcp_sock];				\493	r0 = *(u32*)(r0 + %[bpf_tcp_sock_snd_cwnd]);	\494	r0 = 0;						\495	exit;						\496"	:497	: __imm(bpf_tcp_sock),498	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),499	  __imm_const(bpf_tcp_sock_snd_cwnd, offsetof(struct bpf_tcp_sock, snd_cwnd))500	: __clobber_all);501}502 503SEC("cgroup/skb")504__description("bpf_tcp_sock(skb->sk): tp->snd_cwnd")505__success __success_unpriv __retval(0)506__naked void skb_sk_tp_snd_cwnd_1(void)507{508	asm volatile ("					\509	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\510	if r1 != 0 goto l0_%=;				\511	r0 = 0;						\512	exit;						\513l0_%=:	call %[bpf_tcp_sock];				\514	if r0 != 0 goto l1_%=;				\515	exit;						\516l1_%=:	r0 = *(u32*)(r0 + %[bpf_tcp_sock_snd_cwnd]);	\517	r0 = 0;						\518	exit;						\519"	:520	: __imm(bpf_tcp_sock),521	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),522	  __imm_const(bpf_tcp_sock_snd_cwnd, offsetof(struct bpf_tcp_sock, snd_cwnd))523	: __clobber_all);524}525 526SEC("cgroup/skb")527__description("bpf_tcp_sock(skb->sk): tp->bytes_acked")528__success __success_unpriv __retval(0)529__naked void skb_sk_tp_bytes_acked(void)530{531	asm volatile ("					\532	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\533	if r1 != 0 goto l0_%=;				\534	r0 = 0;						\535	exit;						\536l0_%=:	call %[bpf_tcp_sock];				\537	if r0 != 0 goto l1_%=;				\538	exit;						\539l1_%=:	r0 = *(u64*)(r0 + %[bpf_tcp_sock_bytes_acked]);	\540	r0 = 0;						\541	exit;						\542"	:543	: __imm(bpf_tcp_sock),544	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),545	  __imm_const(bpf_tcp_sock_bytes_acked, offsetof(struct bpf_tcp_sock, bytes_acked))546	: __clobber_all);547}548 549SEC("cgroup/skb")550__description("bpf_tcp_sock(skb->sk): beyond last field")551__failure __msg("invalid tcp_sock access")552__failure_unpriv553__naked void skb_sk_beyond_last_field_2(void)554{555	asm volatile ("					\556	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\557	if r1 != 0 goto l0_%=;				\558	r0 = 0;						\559	exit;						\560l0_%=:	call %[bpf_tcp_sock];				\561	if r0 != 0 goto l1_%=;				\562	exit;						\563l1_%=:	r0 = *(u64*)(r0 + %[bpf_tcp_sock_bytes_acked__end]);\564	r0 = 0;						\565	exit;						\566"	:567	: __imm(bpf_tcp_sock),568	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),569	  __imm_const(bpf_tcp_sock_bytes_acked__end, offsetofend(struct bpf_tcp_sock, bytes_acked))570	: __clobber_all);571}572 573SEC("cgroup/skb")574__description("bpf_tcp_sock(bpf_sk_fullsock(skb->sk)): tp->snd_cwnd")575__success __success_unpriv __retval(0)576__naked void skb_sk_tp_snd_cwnd_2(void)577{578	asm volatile ("					\579	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\580	if r1 != 0 goto l0_%=;				\581	r0 = 0;						\582	exit;						\583l0_%=:	call %[bpf_sk_fullsock];			\584	if r0 != 0 goto l1_%=;				\585	exit;						\586l1_%=:	r1 = r0;					\587	call %[bpf_tcp_sock];				\588	if r0 != 0 goto l2_%=;				\589	exit;						\590l2_%=:	r0 = *(u32*)(r0 + %[bpf_tcp_sock_snd_cwnd]);	\591	r0 = 0;						\592	exit;						\593"	:594	: __imm(bpf_sk_fullsock),595	  __imm(bpf_tcp_sock),596	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),597	  __imm_const(bpf_tcp_sock_snd_cwnd, offsetof(struct bpf_tcp_sock, snd_cwnd))598	: __clobber_all);599}600 601SEC("tc")602__description("bpf_sk_release(skb->sk)")603__failure __msg("R1 must be referenced when passed to release function")604__naked void bpf_sk_release_skb_sk(void)605{606	asm volatile ("					\607	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\608	if r1 == 0 goto l0_%=;				\609	call %[bpf_sk_release];				\610l0_%=:	r0 = 0;						\611	exit;						\612"	:613	: __imm(bpf_sk_release),614	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk))615	: __clobber_all);616}617 618SEC("tc")619__description("bpf_sk_release(bpf_sk_fullsock(skb->sk))")620__failure __msg("R1 must be referenced when passed to release function")621__naked void bpf_sk_fullsock_skb_sk(void)622{623	asm volatile ("					\624	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\625	if r1 != 0 goto l0_%=;				\626	r0 = 0;						\627	exit;						\628l0_%=:	call %[bpf_sk_fullsock];			\629	if r0 != 0 goto l1_%=;				\630	exit;						\631l1_%=:	r1 = r0;					\632	call %[bpf_sk_release];				\633	r0 = 1;						\634	exit;						\635"	:636	: __imm(bpf_sk_fullsock),637	  __imm(bpf_sk_release),638	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk))639	: __clobber_all);640}641 642SEC("tc")643__description("bpf_sk_release(bpf_tcp_sock(skb->sk))")644__failure __msg("R1 must be referenced when passed to release function")645__naked void bpf_tcp_sock_skb_sk(void)646{647	asm volatile ("					\648	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\649	if r1 != 0 goto l0_%=;				\650	r0 = 0;						\651	exit;						\652l0_%=:	call %[bpf_tcp_sock];				\653	if r0 != 0 goto l1_%=;				\654	exit;						\655l1_%=:	r1 = r0;					\656	call %[bpf_sk_release];				\657	r0 = 1;						\658	exit;						\659"	:660	: __imm(bpf_sk_release),661	  __imm(bpf_tcp_sock),662	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk))663	: __clobber_all);664}665 666SEC("tc")667__description("sk_storage_get(map, skb->sk, NULL, 0): value == NULL")668__success __retval(0)669__naked void sk_null_0_value_null(void)670{671	asm volatile ("					\672	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\673	if r1 != 0 goto l0_%=;				\674	r0 = 0;						\675	exit;						\676l0_%=:	call %[bpf_sk_fullsock];			\677	if r0 != 0 goto l1_%=;				\678	r0 = 0;						\679	exit;						\680l1_%=:	r4 = 0;						\681	r3 = 0;						\682	r2 = r0;					\683	r1 = %[sk_storage_map] ll;			\684	call %[bpf_sk_storage_get];			\685	r0 = 0;						\686	exit;						\687"	:688	: __imm(bpf_sk_fullsock),689	  __imm(bpf_sk_storage_get),690	  __imm_addr(sk_storage_map),691	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk))692	: __clobber_all);693}694 695SEC("tc")696__description("sk_storage_get(map, skb->sk, 1, 1): value == 1")697__failure __msg("R3 type=scalar expected=fp")698__naked void sk_1_1_value_1(void)699{700	asm volatile ("					\701	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\702	if r1 != 0 goto l0_%=;				\703	r0 = 0;						\704	exit;						\705l0_%=:	call %[bpf_sk_fullsock];			\706	if r0 != 0 goto l1_%=;				\707	r0 = 0;						\708	exit;						\709l1_%=:	r4 = 1;						\710	r3 = 1;						\711	r2 = r0;					\712	r1 = %[sk_storage_map] ll;			\713	call %[bpf_sk_storage_get];			\714	r0 = 0;						\715	exit;						\716"	:717	: __imm(bpf_sk_fullsock),718	  __imm(bpf_sk_storage_get),719	  __imm_addr(sk_storage_map),720	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk))721	: __clobber_all);722}723 724SEC("tc")725__description("sk_storage_get(map, skb->sk, &stack_value, 1): stack_value")726__success __retval(0)727__naked void stack_value_1_stack_value(void)728{729	asm volatile ("					\730	r2 = 0;						\731	*(u64*)(r10 - 8) = r2;				\732	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\733	if r1 != 0 goto l0_%=;				\734	r0 = 0;						\735	exit;						\736l0_%=:	call %[bpf_sk_fullsock];			\737	if r0 != 0 goto l1_%=;				\738	r0 = 0;						\739	exit;						\740l1_%=:	r4 = 1;						\741	r3 = r10;					\742	r3 += -8;					\743	r2 = r0;					\744	r1 = %[sk_storage_map] ll;			\745	call %[bpf_sk_storage_get];			\746	r0 = 0;						\747	exit;						\748"	:749	: __imm(bpf_sk_fullsock),750	  __imm(bpf_sk_storage_get),751	  __imm_addr(sk_storage_map),752	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk))753	: __clobber_all);754}755 756SEC("tc")757__description("bpf_map_lookup_elem(smap, &key)")758__failure __msg("cannot pass map_type 24 into func bpf_map_lookup_elem")759__naked void map_lookup_elem_smap_key(void)760{761	asm volatile ("					\762	r1 = 0;						\763	*(u32*)(r10 - 4) = r1;				\764	r2 = r10;					\765	r2 += -4;					\766	r1 = %[sk_storage_map] ll;			\767	call %[bpf_map_lookup_elem];			\768	r0 = 0;						\769	exit;						\770"	:771	: __imm(bpf_map_lookup_elem),772	  __imm_addr(sk_storage_map)773	: __clobber_all);774}775 776SEC("xdp")777__description("bpf_map_lookup_elem(xskmap, &key); xs->queue_id")778__success __retval(0)779__naked void xskmap_key_xs_queue_id(void)780{781	asm volatile ("					\782	r1 = 0;						\783	*(u32*)(r10 - 8) = r1;				\784	r2 = r10;					\785	r2 += -8;					\786	r1 = %[map_xskmap] ll;				\787	call %[bpf_map_lookup_elem];			\788	if r0 != 0 goto l0_%=;				\789	exit;						\790l0_%=:	r0 = *(u32*)(r0 + %[bpf_xdp_sock_queue_id]);	\791	r0 = 0;						\792	exit;						\793"	:794	: __imm(bpf_map_lookup_elem),795	  __imm_addr(map_xskmap),796	  __imm_const(bpf_xdp_sock_queue_id, offsetof(struct bpf_xdp_sock, queue_id))797	: __clobber_all);798}799 800SEC("sk_skb")801__description("bpf_map_lookup_elem(sockmap, &key)")802__failure __msg("Unreleased reference id=2 alloc_insn=6")803__naked void map_lookup_elem_sockmap_key(void)804{805	asm volatile ("					\806	r1 = 0;						\807	*(u32*)(r10 - 4) = r1;				\808	r2 = r10;					\809	r2 += -4;					\810	r1 = %[map_sockmap] ll;				\811	call %[bpf_map_lookup_elem];			\812	r0 = 0;						\813	exit;						\814"	:815	: __imm(bpf_map_lookup_elem),816	  __imm_addr(map_sockmap)817	: __clobber_all);818}819 820SEC("sk_skb")821__description("bpf_map_lookup_elem(sockhash, &key)")822__failure __msg("Unreleased reference id=2 alloc_insn=6")823__naked void map_lookup_elem_sockhash_key(void)824{825	asm volatile ("					\826	r1 = 0;						\827	*(u32*)(r10 - 4) = r1;				\828	r2 = r10;					\829	r2 += -4;					\830	r1 = %[map_sockhash] ll;			\831	call %[bpf_map_lookup_elem];			\832	r0 = 0;						\833	exit;						\834"	:835	: __imm(bpf_map_lookup_elem),836	  __imm_addr(map_sockhash)837	: __clobber_all);838}839 840SEC("sk_skb")841__description("bpf_map_lookup_elem(sockmap, &key); sk->type [fullsock field]; bpf_sk_release(sk)")842__success843__naked void field_bpf_sk_release_sk_1(void)844{845	asm volatile ("					\846	r1 = 0;						\847	*(u32*)(r10 - 4) = r1;				\848	r2 = r10;					\849	r2 += -4;					\850	r1 = %[map_sockmap] ll;				\851	call %[bpf_map_lookup_elem];			\852	if r0 != 0 goto l0_%=;				\853	exit;						\854l0_%=:	r1 = r0;					\855	r0 = *(u32*)(r0 + %[bpf_sock_type]);		\856	call %[bpf_sk_release];				\857	exit;						\858"	:859	: __imm(bpf_map_lookup_elem),860	  __imm(bpf_sk_release),861	  __imm_addr(map_sockmap),862	  __imm_const(bpf_sock_type, offsetof(struct bpf_sock, type))863	: __clobber_all);864}865 866SEC("sk_skb")867__description("bpf_map_lookup_elem(sockhash, &key); sk->type [fullsock field]; bpf_sk_release(sk)")868__success869__naked void field_bpf_sk_release_sk_2(void)870{871	asm volatile ("					\872	r1 = 0;						\873	*(u32*)(r10 - 4) = r1;				\874	r2 = r10;					\875	r2 += -4;					\876	r1 = %[map_sockhash] ll;			\877	call %[bpf_map_lookup_elem];			\878	if r0 != 0 goto l0_%=;				\879	exit;						\880l0_%=:	r1 = r0;					\881	r0 = *(u32*)(r0 + %[bpf_sock_type]);		\882	call %[bpf_sk_release];				\883	exit;						\884"	:885	: __imm(bpf_map_lookup_elem),886	  __imm(bpf_sk_release),887	  __imm_addr(map_sockhash),888	  __imm_const(bpf_sock_type, offsetof(struct bpf_sock, type))889	: __clobber_all);890}891 892SEC("sk_reuseport")893__description("bpf_sk_select_reuseport(ctx, reuseport_array, &key, flags)")894__success895__naked void ctx_reuseport_array_key_flags(void)896{897	asm volatile ("					\898	r4 = 0;						\899	r2 = 0;						\900	*(u32*)(r10 - 4) = r2;				\901	r3 = r10;					\902	r3 += -4;					\903	r2 = %[map_reuseport_array] ll;			\904	call %[bpf_sk_select_reuseport];		\905	exit;						\906"	:907	: __imm(bpf_sk_select_reuseport),908	  __imm_addr(map_reuseport_array)909	: __clobber_all);910}911 912SEC("sk_reuseport")913__description("bpf_sk_select_reuseport(ctx, sockmap, &key, flags)")914__success915__naked void reuseport_ctx_sockmap_key_flags(void)916{917	asm volatile ("					\918	r4 = 0;						\919	r2 = 0;						\920	*(u32*)(r10 - 4) = r2;				\921	r3 = r10;					\922	r3 += -4;					\923	r2 = %[map_sockmap] ll;				\924	call %[bpf_sk_select_reuseport];		\925	exit;						\926"	:927	: __imm(bpf_sk_select_reuseport),928	  __imm_addr(map_sockmap)929	: __clobber_all);930}931 932SEC("sk_reuseport")933__description("bpf_sk_select_reuseport(ctx, sockhash, &key, flags)")934__success935__naked void reuseport_ctx_sockhash_key_flags(void)936{937	asm volatile ("					\938	r4 = 0;						\939	r2 = 0;						\940	*(u32*)(r10 - 4) = r2;				\941	r3 = r10;					\942	r3 += -4;					\943	r2 = %[map_sockmap] ll;				\944	call %[bpf_sk_select_reuseport];		\945	exit;						\946"	:947	: __imm(bpf_sk_select_reuseport),948	  __imm_addr(map_sockmap)949	: __clobber_all);950}951 952SEC("tc")953__description("mark null check on return value of bpf_skc_to helpers")954__failure __msg("invalid mem access")955__naked void of_bpf_skc_to_helpers(void)956{957	asm volatile ("					\958	r1 = *(u64*)(r1 + %[__sk_buff_sk]);		\959	if r1 != 0 goto l0_%=;				\960	r0 = 0;						\961	exit;						\962l0_%=:	r6 = r1;					\963	call %[bpf_skc_to_tcp_sock];			\964	r7 = r0;					\965	r1 = r6;					\966	call %[bpf_skc_to_tcp_request_sock];		\967	r8 = r0;					\968	if r8 != 0 goto l1_%=;				\969	r0 = 0;						\970	exit;						\971l1_%=:	r0 = *(u8*)(r7 + 0);				\972	exit;						\973"	:974	: __imm(bpf_skc_to_tcp_request_sock),975	  __imm(bpf_skc_to_tcp_sock),976	  __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk))977	: __clobber_all);978}979 980char _license[] SEC("license") = "GPL";981