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