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, 
> &regs);
> +                             mutex_unlock(&btf_module_mutex);
> +                             btf_apply_deferred_regs(btf, &regs);
> +                             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

Reply via email to