mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-10 20:29:56 -04:00
bpf: Fix NULL-ptr-deref when showing a void BTF type
btf_modifier_show() resolves the modifier and then calls
btf_type_ops(t)->show() unconditionally. For the void type (type_id 0,
BTF_KIND_UNKN) kind_ops[] has no entry, so ->show is NULL.
A "const void" (a modifier resolving to void) cannot be a map key or
value - map_check_btf() rejects it because void has no size - so the map
dump path does not reach it. But bpf_snprintf_btf() takes a type_id
straight from the BPF program, and passing such a "const void" from the
vmlinux BTF NULL-derefs:
KASAN: null-ptr-deref in range [0x0000000000000028-0x000000000000002f]
RIP: 0010:btf_modifier_show (kernel/bpf/btf.c:2914)
Call Trace:
<TASK>
btf_type_show (kernel/bpf/btf.c:8251)
btf_type_snprintf_show (kernel/bpf/btf.c:8321)
bpf_snprintf_btf (kernel/trace/bpf_trace.c:1047)
bpf_prog_test_run_raw_tp (net/bpf/test_run.c:829)
__sys_bpf (kernel/bpf/syscall.c:4804)
do_syscall_64 (arch/x86/entry/syscall_64.c:94)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
</TASK>
Fall back to btf_df_show() when the resolved type has no show op; it
emits the "<unsupported kind:N>" placeholder already used for kinds like
FWD and FUNC. bpf_snprintf_btf() then returns the length as usual.
Fixes: c4d0bfb450 ("bpf: Add bpf_snprintf_btf helper")
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Acked-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Link: https://lore.kernel.org/r/20260901104924.346187-3-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
committed by
Alexei Starovoitov
parent
0895a0c073
commit
4ea508b9eb
@@ -2911,7 +2911,14 @@ static void btf_modifier_show(const struct btf *btf,
|
||||
else
|
||||
t = btf_type_skip_modifiers(btf, type_id, NULL);
|
||||
|
||||
btf_type_ops(t)->show(btf, t, type_id, data, bits_offset, show);
|
||||
/*
|
||||
* A modifier can resolve to void, which has no show op; print a
|
||||
* placeholder rather than dereferencing NULL.
|
||||
*/
|
||||
if (!btf_type_ops(t))
|
||||
btf_df_show(btf, t, type_id, data, bits_offset, show);
|
||||
else
|
||||
btf_type_ops(t)->show(btf, t, type_id, data, bits_offset, show);
|
||||
}
|
||||
|
||||
static void btf_var_show(const struct btf *btf, const struct btf_type *t,
|
||||
|
||||
Reference in New Issue
Block a user