1 // SPDX-License-Identifier: GPL-2.0 2 /* Converted from tools/testing/selftests/bpf/verifier/ringbuf.c */ 3 4 #include <linux/bpf.h> 5 #include <bpf/bpf_helpers.h> 6 #include "bpf_misc.h" 7 8 struct { 9 __uint(type, BPF_MAP_TYPE_RINGBUF); 10 __uint(max_entries, 4096); 11 } map_ringbuf SEC(".maps"); 12 13 SEC("socket") 14 __description("ringbuf: invalid reservation offset 1") 15 __failure __msg("R1 must have zero offset when passed to release func") 16 __failure_unpriv ringbuf_invalid_reservation_offset_1(void)17__naked void ringbuf_invalid_reservation_offset_1(void) 18 { 19 asm volatile (" \ 20 /* reserve 8 byte ringbuf memory */ \ 21 r1 = 0; \ 22 *(u64*)(r10 - 8) = r1; \ 23 r1 = %[map_ringbuf] ll; \ 24 r2 = 8; \ 25 r3 = 0; \ 26 call %[bpf_ringbuf_reserve]; \ 27 /* store a pointer to the reserved memory in R6 */\ 28 r6 = r0; \ 29 /* check whether the reservation was successful */\ 30 if r0 == 0 goto l0_%=; \ 31 /* spill R6(mem) into the stack */ \ 32 *(u64*)(r10 - 8) = r6; \ 33 /* fill it back in R7 */ \ 34 r7 = *(u64*)(r10 - 8); \ 35 /* should be able to access *(R7) = 0 */ \ 36 r1 = 0; \ 37 *(u64*)(r7 + 0) = r1; \ 38 /* submit the reserved ringbuf memory */ \ 39 r1 = r7; \ 40 /* add invalid offset to reserved ringbuf memory */\ 41 r1 += 0xcafe; \ 42 r2 = 0; \ 43 call %[bpf_ringbuf_submit]; \ 44 l0_%=: r0 = 0; \ 45 exit; \ 46 " : 47 : __imm(bpf_ringbuf_reserve), 48 __imm(bpf_ringbuf_submit), 49 __imm_addr(map_ringbuf) 50 : __clobber_all); 51 } 52 53 SEC("socket") 54 __description("ringbuf: invalid reservation offset 2") 55 __failure __msg("R7 min value is outside of the allowed memory range") 56 __failure_unpriv ringbuf_invalid_reservation_offset_2(void)57__naked void ringbuf_invalid_reservation_offset_2(void) 58 { 59 asm volatile (" \ 60 /* reserve 8 byte ringbuf memory */ \ 61 r1 = 0; \ 62 *(u64*)(r10 - 8) = r1; \ 63 r1 = %[map_ringbuf] ll; \ 64 r2 = 8; \ 65 r3 = 0; \ 66 call %[bpf_ringbuf_reserve]; \ 67 /* store a pointer to the reserved memory in R6 */\ 68 r6 = r0; \ 69 /* check whether the reservation was successful */\ 70 if r0 == 0 goto l0_%=; \ 71 /* spill R6(mem) into the stack */ \ 72 *(u64*)(r10 - 8) = r6; \ 73 /* fill it back in R7 */ \ 74 r7 = *(u64*)(r10 - 8); \ 75 /* add invalid offset to reserved ringbuf memory */\ 76 r7 += 0xcafe; \ 77 /* should be able to access *(R7) = 0 */ \ 78 r1 = 0; \ 79 *(u64*)(r7 + 0) = r1; \ 80 /* submit the reserved ringbuf memory */ \ 81 r1 = r7; \ 82 r2 = 0; \ 83 call %[bpf_ringbuf_submit]; \ 84 l0_%=: r0 = 0; \ 85 exit; \ 86 " : 87 : __imm(bpf_ringbuf_reserve), 88 __imm(bpf_ringbuf_submit), 89 __imm_addr(map_ringbuf) 90 : __clobber_all); 91 } 92 93 SEC("xdp") 94 __description("ringbuf: check passing rb mem to helpers") 95 __success __retval(0) passing_rb_mem_to_helpers(void)96__naked void passing_rb_mem_to_helpers(void) 97 { 98 asm volatile (" \ 99 r6 = r1; \ 100 /* reserve 8 byte ringbuf memory */ \ 101 r1 = 0; \ 102 *(u64*)(r10 - 8) = r1; \ 103 r1 = %[map_ringbuf] ll; \ 104 r2 = 8; \ 105 r3 = 0; \ 106 call %[bpf_ringbuf_reserve]; \ 107 r7 = r0; \ 108 /* check whether the reservation was successful */\ 109 if r0 != 0 goto l0_%=; \ 110 exit; \ 111 l0_%=: /* pass allocated ring buffer memory to fib lookup */\ 112 r1 = r6; \ 113 r2 = r0; \ 114 r3 = 8; \ 115 r4 = 0; \ 116 call %[bpf_fib_lookup]; \ 117 /* submit the ringbuf memory */ \ 118 r1 = r7; \ 119 r2 = 0; \ 120 call %[bpf_ringbuf_submit]; \ 121 r0 = 0; \ 122 exit; \ 123 " : 124 : __imm(bpf_fib_lookup), 125 __imm(bpf_ringbuf_reserve), 126 __imm(bpf_ringbuf_submit), 127 __imm_addr(map_ringbuf) 128 : __clobber_all); 129 } 130 131 char _license[] SEC("license") = "GPL"; 132