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