|  | // SPDX-License-Identifier: GPL-2.0 | 
|  | /* Converted from tools/testing/selftests/bpf/verifier/ringbuf.c */ | 
|  |  | 
|  | #include <linux/bpf.h> | 
|  | #include <bpf/bpf_helpers.h> | 
|  | #include "bpf_misc.h" | 
|  |  | 
|  | struct { | 
|  | __uint(type, BPF_MAP_TYPE_RINGBUF); | 
|  | __uint(max_entries, 4096); | 
|  | } map_ringbuf SEC(".maps"); | 
|  |  | 
|  | SEC("socket") | 
|  | __description("ringbuf: invalid reservation offset 1") | 
|  | __failure __msg("R1 must have zero offset when passed to release func") | 
|  | __failure_unpriv | 
|  | __naked void ringbuf_invalid_reservation_offset_1(void) | 
|  | { | 
|  | asm volatile ("					\ | 
|  | /* reserve 8 byte ringbuf memory */		\ | 
|  | r1 = 0;						\ | 
|  | *(u64*)(r10 - 8) = r1;				\ | 
|  | r1 = %[map_ringbuf] ll;				\ | 
|  | r2 = 8;						\ | 
|  | r3 = 0;						\ | 
|  | call %[bpf_ringbuf_reserve];			\ | 
|  | /* store a pointer to the reserved memory in R6 */\ | 
|  | r6 = r0;					\ | 
|  | /* check whether the reservation was successful */\ | 
|  | if r0 == 0 goto l0_%=;				\ | 
|  | /* spill R6(mem) into the stack */		\ | 
|  | *(u64*)(r10 - 8) = r6;				\ | 
|  | /* fill it back in R7 */			\ | 
|  | r7 = *(u64*)(r10 - 8);				\ | 
|  | /* should be able to access *(R7) = 0 */	\ | 
|  | r1 = 0;						\ | 
|  | *(u64*)(r7 + 0) = r1;				\ | 
|  | /* submit the reserved ringbuf memory */	\ | 
|  | r1 = r7;					\ | 
|  | /* add invalid offset to reserved ringbuf memory */\ | 
|  | r1 += 0xcafe;					\ | 
|  | r2 = 0;						\ | 
|  | call %[bpf_ringbuf_submit];			\ | 
|  | l0_%=:	r0 = 0;						\ | 
|  | exit;						\ | 
|  | "	: | 
|  | : __imm(bpf_ringbuf_reserve), | 
|  | __imm(bpf_ringbuf_submit), | 
|  | __imm_addr(map_ringbuf) | 
|  | : __clobber_all); | 
|  | } | 
|  |  | 
|  | SEC("socket") | 
|  | __description("ringbuf: invalid reservation offset 2") | 
|  | __failure __msg("R7 min value is outside of the allowed memory range") | 
|  | __failure_unpriv | 
|  | __naked void ringbuf_invalid_reservation_offset_2(void) | 
|  | { | 
|  | asm volatile ("					\ | 
|  | /* reserve 8 byte ringbuf memory */		\ | 
|  | r1 = 0;						\ | 
|  | *(u64*)(r10 - 8) = r1;				\ | 
|  | r1 = %[map_ringbuf] ll;				\ | 
|  | r2 = 8;						\ | 
|  | r3 = 0;						\ | 
|  | call %[bpf_ringbuf_reserve];			\ | 
|  | /* store a pointer to the reserved memory in R6 */\ | 
|  | r6 = r0;					\ | 
|  | /* check whether the reservation was successful */\ | 
|  | if r0 == 0 goto l0_%=;				\ | 
|  | /* spill R6(mem) into the stack */		\ | 
|  | *(u64*)(r10 - 8) = r6;				\ | 
|  | /* fill it back in R7 */			\ | 
|  | r7 = *(u64*)(r10 - 8);				\ | 
|  | /* add invalid offset to reserved ringbuf memory */\ | 
|  | r7 += 0xcafe;					\ | 
|  | /* should be able to access *(R7) = 0 */	\ | 
|  | r1 = 0;						\ | 
|  | *(u64*)(r7 + 0) = r1;				\ | 
|  | /* submit the reserved ringbuf memory */	\ | 
|  | r1 = r7;					\ | 
|  | r2 = 0;						\ | 
|  | call %[bpf_ringbuf_submit];			\ | 
|  | l0_%=:	r0 = 0;						\ | 
|  | exit;						\ | 
|  | "	: | 
|  | : __imm(bpf_ringbuf_reserve), | 
|  | __imm(bpf_ringbuf_submit), | 
|  | __imm_addr(map_ringbuf) | 
|  | : __clobber_all); | 
|  | } | 
|  |  | 
|  | SEC("xdp") | 
|  | __description("ringbuf: check passing rb mem to helpers") | 
|  | __success __retval(0) | 
|  | __naked void passing_rb_mem_to_helpers(void) | 
|  | { | 
|  | asm volatile ("					\ | 
|  | r6 = r1;					\ | 
|  | /* reserve 8 byte ringbuf memory */		\ | 
|  | r1 = 0;						\ | 
|  | *(u64*)(r10 - 8) = r1;				\ | 
|  | r1 = %[map_ringbuf] ll;				\ | 
|  | r2 = 8;						\ | 
|  | r3 = 0;						\ | 
|  | call %[bpf_ringbuf_reserve];			\ | 
|  | r7 = r0;					\ | 
|  | /* check whether the reservation was successful */\ | 
|  | if r0 != 0 goto l0_%=;				\ | 
|  | exit;						\ | 
|  | l0_%=:	/* pass allocated ring buffer memory to fib lookup */\ | 
|  | r1 = r6;					\ | 
|  | r2 = r0;					\ | 
|  | r3 = 8;						\ | 
|  | r4 = 0;						\ | 
|  | call %[bpf_fib_lookup];				\ | 
|  | /* submit the ringbuf memory */			\ | 
|  | r1 = r7;					\ | 
|  | r2 = 0;						\ | 
|  | call %[bpf_ringbuf_submit];			\ | 
|  | r0 = 0;						\ | 
|  | exit;						\ | 
|  | "	: | 
|  | : __imm(bpf_fib_lookup), | 
|  | __imm(bpf_ringbuf_reserve), | 
|  | __imm(bpf_ringbuf_submit), | 
|  | __imm_addr(map_ringbuf) | 
|  | : __clobber_all); | 
|  | } | 
|  |  | 
|  | char _license[] SEC("license") = "GPL"; |