bpf, selftests: Add ringbuf memory type confusion test
authorDaniel Borkmann <daniel@iogearbox.net>
Wed, 12 Jan 2022 12:39:48 +0000 (12:39 +0000)
committerDaniel Borkmann <daniel@iogearbox.net>
Wed, 19 Jan 2022 00:27:03 +0000 (01:27 +0100)
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>
tools/testing/selftests/bpf/prog_tests/d_path.c
tools/testing/selftests/bpf/progs/test_d_path_check_types.c [new file with mode: 0644]
tools/testing/selftests/bpf/verifier/ringbuf.c
tools/testing/selftests/bpf/verifier/spill_fill.c

index 32fc5b3b5cf6c1133ef0429804f1b9fe9321c9c9..911345c526e6a188bf97e2a02708a6cde0af53b2 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "test_d_path.skel.h"
 #include "test_d_path_check_rdonly_mem.skel.h"
+#include "test_d_path_check_types.skel.h"
 
 static int duration;
 
@@ -167,6 +168,16 @@ static void test_d_path_check_rdonly_mem(void)
        test_d_path_check_rdonly_mem__destroy(skel);
 }
 
+static void test_d_path_check_types(void)
+{
+       struct test_d_path_check_types *skel;
+
+       skel = test_d_path_check_types__open_and_load();
+       ASSERT_ERR_PTR(skel, "unexpected_load_passing_wrong_type");
+
+       test_d_path_check_types__destroy(skel);
+}
+
 void test_d_path(void)
 {
        if (test__start_subtest("basic"))
@@ -174,4 +185,7 @@ void test_d_path(void)
 
        if (test__start_subtest("check_rdonly_mem"))
                test_d_path_check_rdonly_mem();
+
+       if (test__start_subtest("check_alloc_mem"))
+               test_d_path_check_types();
 }
diff --git a/tools/testing/selftests/bpf/progs/test_d_path_check_types.c b/tools/testing/selftests/bpf/progs/test_d_path_check_types.c
new file mode 100644 (file)
index 0000000..7e02b73
--- /dev/null
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "vmlinux.h"
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+
+extern const int bpf_prog_active __ksym;
+
+struct {
+       __uint(type, BPF_MAP_TYPE_RINGBUF);
+       __uint(max_entries, 1 << 12);
+} ringbuf SEC(".maps");
+
+SEC("fentry/security_inode_getattr")
+int BPF_PROG(d_path_check_rdonly_mem, struct path *path, struct kstat *stat,
+            __u32 request_mask, unsigned int query_flags)
+{
+       void *active;
+       u32 cpu;
+
+       cpu = bpf_get_smp_processor_id();
+       active = (void *)bpf_per_cpu_ptr(&bpf_prog_active, cpu);
+       if (active) {
+               /* FAIL here! 'active' points to 'regular' memory. It
+                * cannot be submitted to ring buffer.
+                */
+               bpf_ringbuf_submit(active, 0);
+       }
+       return 0;
+}
+
+char _license[] SEC("license") = "GPL";
index 68cae6947cc405719e080a8c34bf0aa67b31277b..b64d33e4833c8582fbbf8d5de8fbb640f4352a22 100644 (file)
@@ -28,7 +28,7 @@
        },
        .fixup_map_ringbuf = { 1 },
        .result = REJECT,
-       .errstr = "dereference of modified mem ptr R1",
+       .errstr = "dereference of modified alloc_mem ptr R1",
 },
 {
        "ringbuf: invalid reservation offset 2",
        .result = REJECT,
        .errstr = "R7 min value is outside of the allowed memory range",
 },
+{
+       "ringbuf: check passing rb mem to helpers",
+       .insns = {
+       BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
+       /* reserve 8 byte ringbuf memory */
+       BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+       BPF_LD_MAP_FD(BPF_REG_1, 0),
+       BPF_MOV64_IMM(BPF_REG_2, 8),
+       BPF_MOV64_IMM(BPF_REG_3, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_reserve),
+       BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
+       /* check whether the reservation was successful */
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
+       BPF_EXIT_INSN(),
+       /* pass allocated ring buffer memory to fib lookup */
+       BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
+       BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
+       BPF_MOV64_IMM(BPF_REG_3, 8),
+       BPF_MOV64_IMM(BPF_REG_4, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_fib_lookup),
+       /* submit the ringbuf memory */
+       BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
+       BPF_MOV64_IMM(BPF_REG_2, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_submit),
+       BPF_MOV64_IMM(BPF_REG_0, 0),
+       BPF_EXIT_INSN(),
+       },
+       .fixup_map_ringbuf = { 2 },
+       .prog_type = BPF_PROG_TYPE_XDP,
+       .result = ACCEPT,
+},
index 1a8eb9672bd137ecead6b0cf82d80c1170237a04..8cfc5349d2a8444fd3049322d525abea77d43a13 100644 (file)
@@ -84,7 +84,7 @@
        },
        .fixup_map_ringbuf = { 1 },
        .result = REJECT,
-       .errstr = "R0 pointer arithmetic on mem_or_null prohibited",
+       .errstr = "R0 pointer arithmetic on alloc_mem_or_null prohibited",
 },
 {
        "check corrupted spill/fill",