Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bpf, selftests: Add ringbuf memory type confusion test

Add two tests, one which asserts that ring buffer memory can be passed to
other helpers for populating its entry area, and another one where verifier
rejects different type of memory passed to bpf_ringbuf_submit().

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>

+79 -2
+14
tools/testing/selftests/bpf/prog_tests/d_path.c
··· 10 10 11 11 #include "test_d_path.skel.h" 12 12 #include "test_d_path_check_rdonly_mem.skel.h" 13 + #include "test_d_path_check_types.skel.h" 13 14 14 15 static int duration; 15 16 ··· 168 167 test_d_path_check_rdonly_mem__destroy(skel); 169 168 } 170 169 170 + static void test_d_path_check_types(void) 171 + { 172 + struct test_d_path_check_types *skel; 173 + 174 + skel = test_d_path_check_types__open_and_load(); 175 + ASSERT_ERR_PTR(skel, "unexpected_load_passing_wrong_type"); 176 + 177 + test_d_path_check_types__destroy(skel); 178 + } 179 + 171 180 void test_d_path(void) 172 181 { 173 182 if (test__start_subtest("basic")) ··· 185 174 186 175 if (test__start_subtest("check_rdonly_mem")) 187 176 test_d_path_check_rdonly_mem(); 177 + 178 + if (test__start_subtest("check_alloc_mem")) 179 + test_d_path_check_types(); 188 180 }
+32
tools/testing/selftests/bpf/progs/test_d_path_check_types.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include "vmlinux.h" 4 + #include <bpf/bpf_helpers.h> 5 + #include <bpf/bpf_tracing.h> 6 + 7 + extern const int bpf_prog_active __ksym; 8 + 9 + struct { 10 + __uint(type, BPF_MAP_TYPE_RINGBUF); 11 + __uint(max_entries, 1 << 12); 12 + } ringbuf SEC(".maps"); 13 + 14 + SEC("fentry/security_inode_getattr") 15 + int BPF_PROG(d_path_check_rdonly_mem, struct path *path, struct kstat *stat, 16 + __u32 request_mask, unsigned int query_flags) 17 + { 18 + void *active; 19 + u32 cpu; 20 + 21 + cpu = bpf_get_smp_processor_id(); 22 + active = (void *)bpf_per_cpu_ptr(&bpf_prog_active, cpu); 23 + if (active) { 24 + /* FAIL here! 'active' points to 'regular' memory. It 25 + * cannot be submitted to ring buffer. 26 + */ 27 + bpf_ringbuf_submit(active, 0); 28 + } 29 + return 0; 30 + } 31 + 32 + char _license[] SEC("license") = "GPL";
+32 -1
tools/testing/selftests/bpf/verifier/ringbuf.c
··· 28 28 }, 29 29 .fixup_map_ringbuf = { 1 }, 30 30 .result = REJECT, 31 - .errstr = "dereference of modified mem ptr R1", 31 + .errstr = "dereference of modified alloc_mem ptr R1", 32 32 }, 33 33 { 34 34 "ringbuf: invalid reservation offset 2", ··· 61 61 .fixup_map_ringbuf = { 1 }, 62 62 .result = REJECT, 63 63 .errstr = "R7 min value is outside of the allowed memory range", 64 + }, 65 + { 66 + "ringbuf: check passing rb mem to helpers", 67 + .insns = { 68 + BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 69 + /* reserve 8 byte ringbuf memory */ 70 + BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 71 + BPF_LD_MAP_FD(BPF_REG_1, 0), 72 + BPF_MOV64_IMM(BPF_REG_2, 8), 73 + BPF_MOV64_IMM(BPF_REG_3, 0), 74 + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_reserve), 75 + BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), 76 + /* check whether the reservation was successful */ 77 + BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 78 + BPF_EXIT_INSN(), 79 + /* pass allocated ring buffer memory to fib lookup */ 80 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 81 + BPF_MOV64_REG(BPF_REG_2, BPF_REG_0), 82 + BPF_MOV64_IMM(BPF_REG_3, 8), 83 + BPF_MOV64_IMM(BPF_REG_4, 0), 84 + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_fib_lookup), 85 + /* submit the ringbuf memory */ 86 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 87 + BPF_MOV64_IMM(BPF_REG_2, 0), 88 + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_submit), 89 + BPF_MOV64_IMM(BPF_REG_0, 0), 90 + BPF_EXIT_INSN(), 91 + }, 92 + .fixup_map_ringbuf = { 2 }, 93 + .prog_type = BPF_PROG_TYPE_XDP, 94 + .result = ACCEPT, 64 95 },
+1 -1
tools/testing/selftests/bpf/verifier/spill_fill.c
··· 84 84 }, 85 85 .fixup_map_ringbuf = { 1 }, 86 86 .result = REJECT, 87 - .errstr = "R0 pointer arithmetic on mem_or_null prohibited", 87 + .errstr = "R0 pointer arithmetic on alloc_mem_or_null prohibited", 88 88 }, 89 89 { 90 90 "check corrupted spill/fill",