Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [High] bpf: Use-After-Free in MODULE_STATE_LIVE notifier due to lockless module memory access --
commit 93f5bd60bb80b8878d6319aa725f17dde3127d2c Author: Jay Wang <[email protected]> bpf: keep module BTF until the vmlinux BTF is available This commit delays the parsing and registration of module BTF until the vmlinux BTF is available when the kernel is built with CONFIG_DEBUG_INFO_BTF=m. It keeps a copy of the module's BTF data and processes deferred kfunc, dtor, and struct_ops registrations once the vmlinux BTF arrives. > diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c > index aa3fdc98034bd..39d75e8890601 100644 > --- a/kernel/bpf/btf.c > +++ b/kernel/bpf/btf.c [ ... ] > @@ -8918,6 +9002,26 @@ static int btf_module_notify(struct notifier_block > *nb, unsigned long op, > continue; > > btf_mod->flags |= BTF_MODULE_F_LIVE; > + if (IS_MODULE(CONFIG_DEBUG_INFO_BTF) && btf_mod->btf && > + !list_empty(&btf_mod->deferred_regs)) { > + /* > + * The vmlinux BTF arrived while this module was > + * initializing: btf_parse_deferred_modules() > + * parsed its BTF but left the registrations its > + * init queued to us, now that init is done and > + * the module is not going anywhere. Applying > + * them walks btf_modules, so drop the mutex. > + */ > + LIST_HEAD(regs); > + > + btf = btf_mod->btf; > + btf_get(btf); > + list_splice_init(&btf_mod->deferred_regs, > ®s); > + mutex_unlock(&btf_module_mutex); > + btf_apply_deferred_regs(btf, ®s); > + btf_put(btf); > + goto out; [Severity: High] Is it possible for a concurrent module unload to free the module memory while btf_apply_deferred_regs() is still running here? The MODULE_STATE_LIVE notifier drops btf_module_mutex to call btf_apply_deferred_regs(), which processes deferred_regs that point to the module's memory (such as reg->kfunc.kset). However, it doesn't appear to acquire a module reference via try_module_get() before dropping the lock. Because the initial module reference count is dropped to 0 by do_init_module() before calling the MODULE_STATE_LIVE notifiers, could a concurrent sys_delete_module() successfully unmap the module memory, leading to a use-after-free when btf_apply_deferred_regs() dereferences those pointers? > + } > break; > } > mutex_unlock(&btf_module_mutex); -- Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=6
