All of lore.kernel.org
 help / color / mirror / Atom feed
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

  reply	other threads:[~2026-07-07  7:55 UTC|newest]

Thread overview: 6+ 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:02 ` sashiko-bot
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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.