| // 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"; |