selftests/bpf: Test passing rdonly mem to global func
authorKumar Kartikeya Dwivedi <memxor@gmail.com>
Sat, 19 Mar 2022 08:08:26 +0000 (13:38 +0530)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 6 Apr 2022 17:32:12 +0000 (10:32 -0700)
Add two test cases, one pass read only map value pointer to global
func, which should be rejected. The same code checks it for kfunc, so
that is covered as well. Second one tries to use the missing check for
PTR_TO_MEM's MEM_RDONLY flag and tries to write to a read only memory
pointer. Without prior patches, both of these tests fail.

Reviewed-by: Hao Luo <haoluo@google.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20220319080827.73251-5-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/prog_tests/ksyms_btf.c
tools/testing/selftests/bpf/prog_tests/test_global_funcs.c
tools/testing/selftests/bpf/progs/test_global_func17.c [new file with mode: 0644]
tools/testing/selftests/bpf/progs/test_ksyms_btf_write_check.c

index f6933b06daf886a476a564667bbb53c3fbe0ed92..1d7a2f1e073171176fed95dd4e3771a867ee751f 100644 (file)
@@ -138,12 +138,16 @@ cleanup:
        test_ksyms_weak_lskel__destroy(skel);
 }
 
-static void test_write_check(void)
+static void test_write_check(bool test_handler1)
 {
        struct test_ksyms_btf_write_check *skel;
 
-       skel = test_ksyms_btf_write_check__open_and_load();
-       ASSERT_ERR_PTR(skel, "unexpected load of a prog writing to ksym memory\n");
+       skel = test_ksyms_btf_write_check__open();
+       if (!ASSERT_OK_PTR(skel, "test_ksyms_btf_write_check__open"))
+               return;
+       bpf_program__set_autoload(test_handler1 ? skel->progs.handler2 : skel->progs.handler1, false);
+       ASSERT_ERR(test_ksyms_btf_write_check__load(skel),
+                  "unexpected load of a prog writing to ksym memory\n");
 
        test_ksyms_btf_write_check__destroy(skel);
 }
@@ -179,6 +183,9 @@ void test_ksyms_btf(void)
        if (test__start_subtest("weak_ksyms_lskel"))
                test_weak_syms_lskel();
 
-       if (test__start_subtest("write_check"))
-               test_write_check();
+       if (test__start_subtest("write_check1"))
+               test_write_check(true);
+
+       if (test__start_subtest("write_check2"))
+               test_write_check(false);
 }
index 509e21d5cb9da0f60d0251f6c826cfdb50615fb6..b90ee47d31113c1b2c0b155c0a9bf914396f5b4e 100644 (file)
@@ -81,6 +81,7 @@ void test_test_global_funcs(void)
                { "test_global_func14.o", "reference type('FWD S') size cannot be determined" },
                { "test_global_func15.o", "At program exit the register R0 has value" },
                { "test_global_func16.o", "invalid indirect read from stack" },
+               { "test_global_func17.o", "Caller passes invalid args into func#1" },
        };
        libbpf_print_fn_t old_print_fn = NULL;
        int err, i, duration = 0;
diff --git a/tools/testing/selftests/bpf/progs/test_global_func17.c b/tools/testing/selftests/bpf/progs/test_global_func17.c
new file mode 100644 (file)
index 0000000..2b8b9b8
--- /dev/null
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <vmlinux.h>
+#include <bpf/bpf_helpers.h>
+
+__noinline int foo(int *p)
+{
+       return p ? (*p = 42) : 0;
+}
+
+const volatile int i;
+
+SEC("tc")
+int test_cls(struct __sk_buff *skb)
+{
+       return foo((int *)&i);
+}
index 2180c41cd890f26c6f245b9b06563ad1f0e8b69a..a72a5bf3812a8f9877e3be7645c75be03d38e860 100644 (file)
@@ -8,7 +8,7 @@
 extern const int bpf_prog_active __ksym; /* int type global var. */
 
 SEC("raw_tp/sys_enter")
-int handler(const void *ctx)
+int handler1(const void *ctx)
 {
        int *active;
        __u32 cpu;
@@ -26,4 +26,20 @@ int handler(const void *ctx)
        return 0;
 }
 
+__noinline int write_active(int *p)
+{
+       return p ? (*p = 42) : 0;
+}
+
+SEC("raw_tp/sys_enter")
+int handler2(const void *ctx)
+{
+       int *active;
+       __u32 cpu;
+
+       active = bpf_this_cpu_ptr(&bpf_prog_active);
+       write_active(active);
+       return 0;
+}
+
 char _license[] SEC("license") = "GPL";