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

selftests/bpf: Add test for writes to .rodata

Add a small test to write a (verification-time) fixed vs unknown but
bounded-sized buffer into .rodata BPF map and assert that both get
rejected.

# ./vmtest.sh -- ./test_progs -t verifier_const
[...]
./test_progs -t verifier_const
[ 1.418717] tsc: Refined TSC clocksource calibration: 3407.994 MHz
[ 1.419113] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x311fcde90a1, max_idle_ns: 440795222066 ns
[ 1.419972] clocksource: Switched to clocksource tsc
[ 1.449596] bpf_testmod: loading out-of-tree module taints kernel.
[ 1.449958] bpf_testmod: module verification failed: signature and/or required key missing - tainting kernel
#475/1 verifier_const/rodata/strtol: write rejected:OK
#475/2 verifier_const/bss/strtol: write accepted:OK
#475/3 verifier_const/data/strtol: write accepted:OK
#475/4 verifier_const/rodata/mtu: write rejected:OK
#475/5 verifier_const/bss/mtu: write accepted:OK
#475/6 verifier_const/data/mtu: write accepted:OK
#475/7 verifier_const/rodata/mark: write with unknown reg rejected:OK
#475/8 verifier_const/rodata/mark: write with unknown reg rejected:OK
#475 verifier_const:OK
#476/1 verifier_const_or/constant register |= constant should keep constant type:OK
#476/2 verifier_const_or/constant register |= constant should not bypass stack boundary checks:OK
#476/3 verifier_const_or/constant register |= constant register should keep constant type:OK
#476/4 verifier_const_or/constant register |= constant register should not bypass stack boundary checks:OK
#476 verifier_const_or:OK
Summary: 2/12 PASSED, 0 SKIPPED, 0 FAILED

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20241021152809.33343-4-daniel@iogearbox.net
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Daniel Borkmann and committed by
Alexei Starovoitov
baa802d2 14a3d3ef

+30 -1
+30 -1
tools/testing/selftests/bpf/progs/verifier_const.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* Copyright (c) 2024 Isovalent */ 3 3 4 - #include <linux/bpf.h> 4 + #include "vmlinux.h" 5 5 #include <bpf/bpf_helpers.h> 6 + #include <bpf/bpf_tracing.h> 6 7 #include "bpf_misc.h" 7 8 8 9 const volatile long foo = 42; ··· 65 64 { 66 65 bpf_check_mtu(skb, skb->ifindex, (__u32 *)&bart, 0, 0); 67 66 return TCX_PASS; 67 + } 68 + 69 + static inline void write_fixed(volatile void *p, __u32 val) 70 + { 71 + *(volatile __u32 *)p = val; 72 + } 73 + 74 + static inline void write_dyn(void *p, void *val, int len) 75 + { 76 + bpf_copy_from_user(p, len, val); 77 + } 78 + 79 + SEC("tc/ingress") 80 + __description("rodata/mark: write with unknown reg rejected") 81 + __failure __msg("write into map forbidden") 82 + int tcx7(struct __sk_buff *skb) 83 + { 84 + write_fixed((void *)&foo, skb->mark); 85 + return TCX_PASS; 86 + } 87 + 88 + SEC("lsm.s/bprm_committed_creds") 89 + __description("rodata/mark: write with unknown reg rejected") 90 + __failure __msg("write into map forbidden") 91 + int BPF_PROG(bprm, struct linux_binprm *bprm) 92 + { 93 + write_dyn((void *)&foo, &bart, bpf_get_prandom_u32() & 3); 94 + return 0; 68 95 } 69 96 70 97 char LICENSE[] SEC("license") = "GPL";