From: Henrik Grimler <henrik@grimler.se>
To: Ihor Solodrai <ihor.solodrai@linux.dev>
Cc: Aelin Reidel <aelin@mainlining.org>,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
Eduard Zingerman <eddyz87@gmail.com>,
Kumar Kartikeya Dwivedi <memxor@gmail.com>,
Martin KaFai Lau <martin.lau@linux.dev>,
Song Liu <song@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>,
Jiri Olsa <jolsa@kernel.org>,
Emil Tsalapatis <emil@etsalapatis.com>,
bpf@vger.kernel.org, linux-kernel@vger.kernel.org,
stable@vger.kernel.org
Subject: Re: [PATCH v2] resolve_btfids: preserve tag and parameter names when processing implicit args
Date: Tue, 7 Jul 2026 09:55:00 +0200 [thread overview]
Message-ID: <20260707075500.GA10854@localhost> (raw)
In-Reply-To: <0606be50-1f21-438f-bf00-024f31b9eda8@linux.dev>
Hi Ihor,
On Thu, Jun 25, 2026 at 10:26:27PM -0700, Ihor Solodrai wrote:
> On 2026-06-19 3:49 p.m., Aelin Reidel wrote:
> > process_kfunc_with_implicit_args() obtains parameter names through
> > btf__name_by_offset() and passes them to btf__add_func_param() while
> > constructing a new function prototype. Tag names are processed in a
> > similar fashion.
> >
> > The returned name pointer references memory owned by the BTF object.
> > btf__add_func_param(), btf__add_decl_tag(), etc. modify the same BTF and
> > may grow its internal storage, invalidating previously returned string
> > pointers.
> >
> > This can result in btf__add_func_param(), btf__add_decl_tag(), etc.
> > dereferencing a stale pointer when copying the string, leading to crashes
> > in strset__add_str().
> >
> > Duplicate the parameter name before calling btf__add_func_param() so it
> > remains valid across BTF updates.
> >
> > Fixes: 9d199965990c ("resolve_btfids: Support for KF_IMPLICIT_ARGS")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Aelin Reidel <aelin@mainlining.org>
> > ---
> > We were noticing resolve_btfids crashing almost all the time when
> > building our kernels with BTF debuginfo in postmarketOS. I'm not sure
> > why specificially our environment triggered this extremely reliably, but
> > I'm glad I was able to track down the issue. With the patch, I haven't
> > seen any further issues and our kernel builds are succeeding again.
>
> Hi Aelin, thank you for the report and patch.
>
> My first instinct was to dismiss the patch as over defensive, because
> libbpf gracefully handles reallocation of existing strings, and we
> don't add new strings here.
>
> Take a look at strset_str_append() in libbpf (strset.c:131):
>
> static long strset_str_append(struct strset *set, const char *s)
> {
> [...]
>
> /*
> * The set->strs_data might have reallocated and if 's' pointed
> * to an internal string within the old buffer, then it became
> * dangling and needs to be reconstructed before the copy.
> */
> if (old_data && old_data != (uintptr_t)set->strs_data &&
> old_s >= old_data && old_s < old_data + old_data_len)
> s = set->strs_data + (old_s - old_data);
>
> memcpy(p, s, len);
>
> return len;
> }
>
> In process_kfunc_with_implicit_args() both tag_name and param_name are
> read *after* the first btf__add_func() / btf__add_func_proto() has
> made the BTF modifiable, so btf__name_by_offset() should return a
> pointer into btf->strs_set. I don't see where the bad pointer comes
> from.
>
> However you have a stable reproducer, so your strdup() change probably
> covers a real UAF bug somewhere else (in libbpf?).
>
> Let's track this down before coming up with a fix.
>
> What version/commit of libbpf are you using in your kernel tree?
I use the same build environment as Aelin and get the same issue with
resolve_btfids from linux v7.1.1. System libbpf is at v1.7.0 [1] (but
I guess this is not relevant? resolve_btfids is not linked against
it).
> You could build resolve_btfids with ASAN, or run it with valgrind.
Valgrind reports some invalid reads, see log here:
https://grimler.se/files/valgrind-resolve-btfids.txt
and if run under gdb I get:
```
$ gdb -ex r --args tools/bpf/resolve_btfids/resolve_btfids --fatal_warnings --verbose --btf .tmp_vmlinux1.BTF.1 .tmp_vmlinux1
[ ... ]
found kfunc tcp_reno_ssthresh in BTF_ID_FLAGS bpf_tcp_ca_check_kfunc_ids
found kfunc tcp_reno_undo_cwnd in BTF_ID_FLAGS bpf_tcp_ca_check_kfunc_ids
found kfunc tcp_slow_start in BTF_ID_FLAGS bpf_tcp_ca_check_kfunc_ids
resolve_btfids: function bpf_list_push_back_impl already exists in BTF
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7f7aaa0 in memcpy (dest=0x7fffebb05a93, src=<optimized out>, n=5) at src/string/memcpy.c:23
warning: 23 src/string/memcpy.c: No such file or directory
(gdb) bt
#0 0x00007ffff7f7aaa0 in memcpy (dest=0x7fffebb05a93, src=<optimized out>, n=5) at src/string/memcpy.c:23
#1 0x000055555559865b in _ZL6memcpyPvU17pass_object_size0PKvU17pass_object_size0m (__od=0x7fffeb115c71, __os=0x7fffeb115c71, __n=5) at /usr/include/fortify/string.h:57
#2 strset__add_str (set=0x7fffebb85fd0, s=s@entry=0x7fffeb115c71 <error: Cannot access memory at address 0x7fffeb115c71>) at strset.c:162
#3 0x0000555555587b2c in btf__add_str (btf=btf@entry=0x7fffebb860a0, s=0x7fffeb115c71 <error: Cannot access memory at address 0x7fffeb115c71>) at btf.c:2109
#4 0x00005555555898b1 in btf__add_func_param (btf=0x7fffebb860a0, name=0x7fffeb115c71 <error: Cannot access memory at address 0x7fffeb115c71>, type_id=11011) at btf.c:3108
#5 0x000055555555de50 in process_kfunc_with_implicit_args (ctx=0x7fffffffd7d0, kfunc=0x7fffebb739a0) at main.c:1196
#6 0x000055555555cc02 in btf2btf (obj=0x7fffffffd868) at main.c:1229
#7 0x000055555555b869 in main (argc=1, argv=0x7fffffffec08) at main.c:1535
```
> If you can share a reproducer that's easy to run, that would be
> great too.
I have uploaded .tmp_vmlinux1 and .tmp_vmlinux1.BTF.1 files (for an
ARM kernel) that reproduce the issue here:
https://grimler.se/files/tmp_vmlinux1
https://grimler.se/files/tmp_vmlinux1.BTF.1
When resolve_btfids is compiled with musl and alpine's toolchain, then
the following command segfaults roughly 50 % of the time:
tools/bpf/resolve_btfids/resolve_btfids --fatal_warnings --verbose --btf tmp_vmlinux1.BTF.1 tmp_vmlinux1
With a resolve_btfids compiled for glibc it does not segfault, but valgrind still reports invalid reads.
> Thanks!
[1] https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/main/libbpf/APKBUILD#L3
Best regards,
Henrik Grimler
next prev parent reply other threads:[~2026-07-07 7:55 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-19 22:49 [PATCH v2] resolve_btfids: preserve tag and parameter names when processing implicit args Aelin Reidel
2026-06-19 23:48 ` bot+bpf-ci
2026-06-26 5:26 ` Ihor Solodrai
2026-07-07 7:55 ` Henrik Grimler [this message]
2026-07-07 19:44 ` Ihor Solodrai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260707075500.GA10854@localhost \
--to=henrik@grimler.se \
--cc=aelin@mainlining.org \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=emil@etsalapatis.com \
--cc=ihor.solodrai@linux.dev \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=song@kernel.org \
--cc=stable@vger.kernel.org \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox