summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/bpf/verifier/pseudo_func.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-09-06 13:49:44 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-09-06 13:49:44 -0700
commit2beb1b31a12b57e19cd5c82ea6d54e56520605e8 (patch)
tree622b0fd0b7fd41bdf9240873cb6d7514c248330b /tools/testing/selftests/bpf/verifier/pseudo_func.c
parent88405f0ad1d5c680afe3ea0ce9345fa9e1deaac8 (diff)
parent536b523b407397c8d3967c020ce7aad70a0ea030 (diff)
downloadlinux-next-2beb1b31a12b57e19cd5c82ea6d54e56520605e8.tar.gz
linux-next-2beb1b31a12b57e19cd5c82ea6d54e56520605e8.zip
Merge tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Pull bpf fixes from Alexei Starovoitov: "This mainly contains verifier fixes that address bugs reported by Nicholas Carlini. - Fix incorrect non-NULL inference in pointer comparisons: pointer types that may be NULL at runtime, pointers with unbounded offsets, JMP32 comparisons with zero, and imprecise zero registers (Eduard Zingerman) - Fix precision tracking for half-dead zero spills, ld_abs/ld_ind implicit subprog exit, bpf_loop() callbacks, linked scalar ids and NULL call arguments (Eduard Zingerman) - Reject BPF_PSEUDO_FUNC reference to the main program, fix zero extension of arena 32-bit cmpxchg, don't rewrite bpf_fastcall patterns entered by a jump (Eduard Zingerman) - Fix percpu map update and BPF_F_CPU validation with sparse CPU IDs (Hui Su) - Fix NULL-ptr-derefs in bpf_snprintf_btf() for void and VAR types, and reject key-less BTF for hash maps (Jiayuan Chen) - Various fixes (Kumar Kartikeya Dwivedi): - Fix out-of-bounds access in disassembler on invalid LDSX instruction - mark siginfo of signal tracepoints as scalar and sched_process_wait argument as nullable - mark faultable stack helpers as sleepable - reject tail calls and legacy packet loads from callbacks - enforce rbtree callback lock restrictions for resilient locks - require MEM_PERCPU for percpu kptr stores - clear NON_OWN_REF after RCU protection ends - mark NULL kptr stores precise - preserve inner map identity in callback frames - reject non-scalar bpf_loop() iteration counts - Fix trampoline allocation slowdown on x86 by using EXECMEM_MODULE_DATA (Mike Rapoport) - Keep bpf_refcount_acquire() nullable for borrowed RCU kptrs and reject untrusted allocated-object pointers (Ning Ding) - Fix special fields handling in recycled rhtab elements (Nuoqi Gui, Yuan Chen)" * tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf: (86 commits) bpf, riscv: Make arena support depend on ZACAS selftests/bpf: Test pointer bpf_loop iteration count rejection bpf: Reject non-scalar bpf_loop iteration counts bpf: use mark_arg_precision() in check_mem_size_reg() bpf: propagate mark_chain_precision() errors out of loop_flag_is_zero() selftests/bpf: precision of a NULL global subprogram BTF_ID argument bpf: mark a NULL BTF_ID argument of a global subprogram precise selftests/bpf: precision of a NULL kfunc argument bpf: mark a NULL kfunc argument precise selftests/bpf: precision of a NULL global subprogram memory argument bpf: mark a NULL memory argument of a call precise selftests/bpf: precision of a NULL helper argument bpf: mark a NULL call argument precise selftests/bpf: Test inner map identities in callbacks bpf: Preserve inner map identity in callback frames selftests/bpf: Test imprecise scalar kptr stores bpf: Mark NULL kptr stores precise selftests/bpf: Test rhtab kptr cancellation semantics bpf: Cancel special fields when recycling rhtab elements selftests/bpf: Test timer field on recycled rhtab element ...
Diffstat (limited to 'tools/testing/selftests/bpf/verifier/pseudo_func.c')
-rw-r--r--tools/testing/selftests/bpf/verifier/pseudo_func.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/tools/testing/selftests/bpf/verifier/pseudo_func.c b/tools/testing/selftests/bpf/verifier/pseudo_func.c
new file mode 100644
index 000000000000..63c5c67d51de
--- /dev/null
+++ b/tools/testing/selftests/bpf/verifier/pseudo_func.c
@@ -0,0 +1,45 @@
+/*
+ * Buggy verifier accepted the program below while not patching BPF_PSEUDO_FUNC
+ * load instruction to contain a real address. Which resulted in a function call
+ * to a bogus address.
+ */
+{
+ "BPF_PSEUDO_FUNC reference to the main program",
+ .insns = {
+ /* r6 = bpf_map_lookup_elem(&timer_map, &(int){0}); */
+ BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 0),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
+ BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
+ /* bpf_timer_init(r6, &timer_map, 0); */
+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
+ BPF_LD_MAP_FD(BPF_REG_2, 0),
+ BPF_MOV64_IMM(BPF_REG_3, 0),
+ BPF_EMIT_CALL(BPF_FUNC_timer_init),
+ /* bpf_timer_set_callback(r6, <insn #0>); */
+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
+ BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, -15),
+ BPF_RAW_INSN(0, 0, 0, 0, 0),
+ BPF_EMIT_CALL(BPF_FUNC_timer_set_callback),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .prog_type = BPF_PROG_TYPE_TRACEPOINT,
+ .fixup_map_timer = { 3, 9 },
+ .result = REJECT,
+ .errstr = "callback function cannot be the main program",
+ .func_info = { { 0, 4 /* main_prog */ } },
+ .func_info_cnt = 1,
+ .btf_strings = "\0int\0ctx\0main_prog",
+ .btf_types = {
+ /* 1: int */ BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4),
+ /* 2: void* */ BTF_PTR_ENC(0),
+ /* 3: int __(void *) */ BTF_FUNC_PROTO_ENC(1, 1),
+ BTF_FUNC_PROTO_ARG_ENC(5, 2),
+ /* 4: main_prog */ BTF_FUNC_ENC(9, 3),
+ BTF_END_RAW
+ }
+},