From: Ihor Solodrai <ihor.solodrai@linux.dev>
To: 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>
Cc: 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: Thu, 25 Jun 2026 22:26:27 -0700 [thread overview]
Message-ID: <0606be50-1f21-438f-bf00-024f31b9eda8@linux.dev> (raw)
In-Reply-To: <20260620-resolve-btfids-implicit-args-use-after-free-v2-1-4132e1f639f0@mainlining.org>
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?
You could build resolve_btfids with ASAN, or run it with valgrind.
If you can share a reproducer that's easy to run, that would be
great too.
Thanks!
> ---
> Changes in v2:
> - Apply the same fix to tag_name and adjust the commit message
> accordingly
> - Fix the remaining use-after-free in the error handling path
> - Link to v1: https://patch.msgid.link/20260619-resolve-btfids-implicit-args-use-after-free-v1-1-2af87d4704c8@mainlining.org
>
> To: Alexei Starovoitov <ast@kernel.org>
> To: Daniel Borkmann <daniel@iogearbox.net>
> To: Andrii Nakryiko <andrii@kernel.org>
> To: Eduard Zingerman <eddyz87@gmail.com>
> To: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> To: Martin KaFai Lau <martin.lau@linux.dev>
> To: Song Liu <song@kernel.org>
> To: Yonghong Song <yonghong.song@linux.dev>
> To: Jiri Olsa <jolsa@kernel.org>
> To: Emil Tsalapatis <emil@etsalapatis.com>
> To: Ihor Solodrai <ihor.solodrai@linux.dev>
> Cc: bpf@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> ---
> tools/bpf/resolve_btfids/main.c | 20 +++++++++++++++-----
> 1 file changed, 15 insertions(+), 5 deletions(-)
>
> diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
> index f8a91fa7584f..94b89e9c942e 100644
> --- a/tools/bpf/resolve_btfids/main.c
> +++ b/tools/bpf/resolve_btfids/main.c
> @@ -1113,6 +1113,7 @@ static int process_kfunc_with_implicit_args(struct btf2btf_context *ctx, struct
> {
> s32 idx, new_proto_id, new_func_id, proto_id;
> const char *param_name, *tag_name;
> + char *tmp_param_name, *tmp_tag_name;
> const struct btf_param *params;
> enum btf_func_linkage linkage;
> char tmp_name[KSYM_NAME_LEN];
> @@ -1163,18 +1164,22 @@ static int process_kfunc_with_implicit_args(struct btf2btf_context *ctx, struct
> if (strcmp(tag_name, "bpf_kfunc") == 0)
> continue;
>
> + tmp_tag_name = strdup(tag_name);
> idx = btf_decl_tag(t)->component_idx;
>
> if (btf_kflag(t))
> - err = btf__add_decl_attr(btf, tag_name, new_func_id, idx);
> + err = btf__add_decl_attr(btf, tmp_tag_name, new_func_id, idx);
> else
> - err = btf__add_decl_tag(btf, tag_name, new_func_id, idx);
> + err = btf__add_decl_tag(btf, tmp_tag_name, new_func_id, idx);
>
> if (err < 0) {
> pr_err("ERROR: resolve_btfids: failed to add decl tag %s for %s\n",
> - tag_name, tmp_name);
> + tmp_tag_name, tmp_name);
> + free(tmp_tag_name);
> return -EINVAL;
> }
> +
> + free(tmp_tag_name);
> }
>
> add_new_proto:
> @@ -1193,12 +1198,17 @@ static int process_kfunc_with_implicit_args(struct btf2btf_context *ctx, struct
> if (is_kf_implicit_arg(btf, ¶ms[i]))
> break;
> param_name = btf__name_by_offset(btf, params[i].name_off);
> - err = btf__add_func_param(btf, param_name, params[i].type);
> + tmp_param_name = strdup(param_name);
> + if (!tmp_param_name)
> + return -ENOMEM;
> + err = btf__add_func_param(btf, tmp_param_name, params[i].type);
> if (err < 0) {
> pr_err("ERROR: resolve_btfids: failed to add param %s for %s\n",
> - param_name, kfunc->name);
> + tmp_param_name, kfunc->name);
> + free(tmp_param_name);
> return err;
> }
> + free(tmp_param_name);
> t = (struct btf_type *)btf__type_by_id(btf, proto_id);
> }
>
>
> ---
> base-commit: 598c7067dd8b65b93f3ccada47e9014a13137f1b
> change-id: 20260619-resolve-btfids-implicit-args-use-after-free-16fc2939529e
>
> Best regards,
> --
> Aelin Reidel <aelin@mainlining.org>
>
prev parent reply other threads:[~2026-06-26 5:26 UTC|newest]
Thread overview: 4+ 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 [this message]
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=0606be50-1f21-438f-bf00-024f31b9eda8@linux.dev \
--to=ihor.solodrai@linux.dev \
--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=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.