On Fri, Apr 17, 2026 at 08:10:22PM +0000, [email protected] wrote:
> > diff --git a/tools/testing/selftests/bpf/prog_tests/tracing_multi.c 
> > b/tools/testing/selftests/bpf/prog_tests/tracing_multi.c
> > --- /dev/null
> > +++ b/tools/testing/selftests/bpf/prog_tests/tracing_multi.c
> 
> [ ... ]
> 
> > @@ -0,0 +1,256 @@
> > +static __u32 *get_ids(const char * const funcs[], int funcs_cnt, const 
> > char *mod)
> > +{
> > +   struct btf *btf, *vmlinux_btf = NULL;
> > +   __u32 nr, type_id, cnt = 0;
> > +   void *root = NULL;
> > +   __u32 *ids = NULL;
> > +   int i, err = 0;
> > +
> > +   btf = btf__load_vmlinux_btf();
> > +   if (!ASSERT_OK_PTR(btf, "btf__load_vmlinux_btf"))
> > +           return NULL;
> > +
> > +   if (mod) {
> > +           vmlinux_btf = btf;
> > +           btf = btf__load_module_btf(mod, vmlinux_btf);
> > +           if (!ASSERT_OK_PTR(btf, "btf__load_module_btf")) {
> > +                   btf__free(vmlinux_btf);
> > +                   goto out;
> > +           }
> > +   }
> 
> [ ... ]
> 
> > +out:
> > +   tdestroy(root, tdestroy_free_nop);
> > +   btf__free(vmlinux_btf);
> > +   btf__free(btf);
> > +   return ids;
> > +}
> 
> Does this code double-free vmlinux_btf when btf__load_module_btf() fails?
> If btf__load_module_btf(mod, vmlinux_btf) fails, the error path at
> ASSERT_OK_PTR calls btf__free(vmlinux_btf) and then jumps to the out:
> label, which calls btf__free(vmlinux_btf) again on the same pointer.
> 
> The first free happens here:
> 
>       if (mod) {
>               vmlinux_btf = btf;
>               btf = btf__load_module_btf(mod, vmlinux_btf);
>               if (!ASSERT_OK_PTR(btf, "btf__load_module_btf")) {
>                       btf__free(vmlinux_btf);  <-- FIRST FREE
>                       goto out;
>               }
>       }
> 
> Then at the out: label:
> 
> out:
>       tdestroy(root, tdestroy_free_nop);
>       btf__free(vmlinux_btf);  <-- SECOND FREE
>       btf__free(btf);
> 
> The btf__free() implementation in tools/lib/bpf/btf.c checks only
> IS_ERR_OR_NULL(btf) and does not guard against already-freed memory,
> so this would trigger a double-free that glibc would detect and abort.
> 
> In the current commit, get_ids() is only called with mod=NULL from
> test_link_api_ids(), so this path is latent. However, a subsequent commit
> (4dda98b9e4d0, "selftests/bpf: Add tracing multi skel/pattern/ids module
> attach tests") adds a caller get_ids(bpf_testmod_fentry_test, cnt,
> "bpf_testmod") that activates the buggy path.

yep, double free, will fix

jirka

Reply via email to