On 03/10/2026 20:59, [email protected] wrote: > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) > to consider: > - [High] bpf: kernel panic on NULL pointer dereference in btf_parse_module() > error path > -- > > commit 7871f353137bb8eca880dde9f21fa3041a6f681f > Author: Alan Maguire <[email protected]> > > btf: Relocate and expose module inline BTF > > This commit introduces parsing of module inline BTF data, rebases inline type > IDs on top of the relocated module BTF, and exposes the result via sysfs. > Malformed inline BTF is warned about and skipped without preventing normal > module BTF registration. > >> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c >> index c535e636d41c1..28b7c9786fdce 100644 >> --- a/kernel/bpf/btf.c >> +++ b/kernel/bpf/btf.c > [ ... ] >> @@ -6954,67 +7076,66 @@ static struct btf *btf_parse_module(const char >> *module_name, const void *data, >> base_btf = vmlinux_btf; >> } >> >> - btf = kzalloc_obj(*btf, GFP_KERNEL | __GFP_NOWARN); >> - if (!btf) { >> - err = -ENOMEM; >> + btf = btf_parse_split(env, module_name, data, data_size, base_btf); >> + if (IS_ERR(btf)) { >> + err = PTR_ERR(btf); >> + btf = NULL; >> goto errout; >> } > [ ... ] >> errout: >> + kvfree(module_str_map); >> btf_verifier_env_free(env); >> + btf_free(inline_btf); >> if (!IS_ERR(base_btf) && base_btf != vmlinux_btf) >> btf_free(base_btf); >> - if (btf) { >> - kvfree(btf->data); >> - kvfree(btf->types); >> - kfree(btf); >> - } >> + btf_free(btf); > > [Severity: High] > Will this cause a kernel panic if btf_parse_split() fails? > > In the error path above, if btf_parse_split() returns an error, btf is > explicitly set to NULL and execution jumps to errout. At this point, > inline_btf is also initialized to NULL. > > The errout path then calls btf_free() unconditionally for both inline_btf > and btf. Looking at btf_free(): > > static void btf_free(struct btf *btf) > { > btf_free_struct_meta_tab(btf); > ... > } > > And btf_free_struct_meta_tab() unconditionally dereferences the pointer: > > static void btf_free_struct_meta_tab(struct btf *btf) > { > struct btf_struct_metas *tab = btf->struct_meta_tab; > ... > } > > Does this result in an immediate NULL pointer dereference when > btf_free() is called on the NULL btf or inline_btf pointers? > >> return ERR_PTR(err); >> } >
we need non-null guards on the btf_free()s alright, good catch.
