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

selftests/bpf: Test passing rdonly mem to global func

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>

authored by

Kumar Kartikeya Dwivedi and committed by
Alexei Starovoitov
7cb29b1c 7b3552d3

+46 -6
+12 -5
tools/testing/selftests/bpf/prog_tests/ksyms_btf.c
··· 138 138 test_ksyms_weak_lskel__destroy(skel); 139 139 } 140 140 141 - static void test_write_check(void) 141 + static void test_write_check(bool test_handler1) 142 142 { 143 143 struct test_ksyms_btf_write_check *skel; 144 144 145 - skel = test_ksyms_btf_write_check__open_and_load(); 146 - ASSERT_ERR_PTR(skel, "unexpected load of a prog writing to ksym memory\n"); 145 + skel = test_ksyms_btf_write_check__open(); 146 + if (!ASSERT_OK_PTR(skel, "test_ksyms_btf_write_check__open")) 147 + return; 148 + bpf_program__set_autoload(test_handler1 ? skel->progs.handler2 : skel->progs.handler1, false); 149 + ASSERT_ERR(test_ksyms_btf_write_check__load(skel), 150 + "unexpected load of a prog writing to ksym memory\n"); 147 151 148 152 test_ksyms_btf_write_check__destroy(skel); 149 153 } ··· 183 179 if (test__start_subtest("weak_ksyms_lskel")) 184 180 test_weak_syms_lskel(); 185 181 186 - if (test__start_subtest("write_check")) 187 - test_write_check(); 182 + if (test__start_subtest("write_check1")) 183 + test_write_check(true); 184 + 185 + if (test__start_subtest("write_check2")) 186 + test_write_check(false); 188 187 }
+1
tools/testing/selftests/bpf/prog_tests/test_global_funcs.c
··· 81 81 { "test_global_func14.o", "reference type('FWD S') size cannot be determined" }, 82 82 { "test_global_func15.o", "At program exit the register R0 has value" }, 83 83 { "test_global_func16.o", "invalid indirect read from stack" }, 84 + { "test_global_func17.o", "Caller passes invalid args into func#1" }, 84 85 }; 85 86 libbpf_print_fn_t old_print_fn = NULL; 86 87 int err, i, duration = 0;
+16
tools/testing/selftests/bpf/progs/test_global_func17.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + #include <vmlinux.h> 3 + #include <bpf/bpf_helpers.h> 4 + 5 + __noinline int foo(int *p) 6 + { 7 + return p ? (*p = 42) : 0; 8 + } 9 + 10 + const volatile int i; 11 + 12 + SEC("tc") 13 + int test_cls(struct __sk_buff *skb) 14 + { 15 + return foo((int *)&i); 16 + }
+17 -1
tools/testing/selftests/bpf/progs/test_ksyms_btf_write_check.c
··· 8 8 extern const int bpf_prog_active __ksym; /* int type global var. */ 9 9 10 10 SEC("raw_tp/sys_enter") 11 - int handler(const void *ctx) 11 + int handler1(const void *ctx) 12 12 { 13 13 int *active; 14 14 __u32 cpu; ··· 23 23 *(volatile int *)active = -1; 24 24 } 25 25 26 + return 0; 27 + } 28 + 29 + __noinline int write_active(int *p) 30 + { 31 + return p ? (*p = 42) : 0; 32 + } 33 + 34 + SEC("raw_tp/sys_enter") 35 + int handler2(const void *ctx) 36 + { 37 + int *active; 38 + __u32 cpu; 39 + 40 + active = bpf_this_cpu_ptr(&bpf_prog_active); 41 + write_active(active); 26 42 return 0; 27 43 } 28 44