From: sashiko-bot@kernel.org
To: "Alan Maguire" <alan.maguire@oracle.com>
Cc: bpf@vger.kernel.org, linux-modules@vger.kernel.org
Subject: Re: [PATCH v2 bpf-next 03/18] libbpf: Support moving permuted BTF types into split BTF
Date: Tue, 01 Sep 2026 17:15:04 +0000 [thread overview]
Message-ID: <20260901171505.2A73F1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260901165757.801449-4-alan.maguire@oracle.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
New issues:
- [High] If `btf_compact_strings()` fails, `btf__permute()` returns an error but leaves the BTF object in an irreversibly truncated and permuted state without updating the caller's `id_map`.
- [Low] LIBBPF-001 API rule violation: `btf_add_local_str` incorrectly uses `libbpf_err()` as an internal function, and `btf__add_str` fails to use it on its error return.
Pre-existing issues:
- [High] `btf__permute` completely corrupts base BTF permutations due to incorrect handling of `start_offs`, resulting in heap out-of-bounds accesses and total deletion of the VOID type.
--
commit 9de40ca1824ca5dbac1f65a763fe3a6beedba81f
Author: Alan Maguire <alan.maguire@oracle.com>
libbpf: Support moving permuted BTF types into split BTF
This commit extends btf__permute() with an optional transfer mode to move
specific permuted BTF types into a newly-created split BTF. It handles
remapping type IDs, migrating referenced strings, and compacting string
tables so that strings exclusive to the moved types reside only in the
split BTF.
> diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
> index 9449f6f50f18f..30f8c426d1453 100644
> --- a/tools/lib/bpf/btf.c
> +++ b/tools/lib/bpf/btf.c
> @@ -2147,16 +2147,9 @@ int btf__find_str(struct btf *btf, const char *s)
> * - > 0 offset into string section, on success;
> * - < 0, on error.
> */
> -int btf__add_str(struct btf *btf, const char *s)
> +static int btf_add_local_str(struct btf *btf, const char *s)
> {
> - int off;
> - int err;
> -
> - if (btf->base_btf) {
> - off = btf__find_str(btf->base_btf, s);
> - if (off != -ENOENT)
> - return off;
> - }
> + int off, err;
>
> err = btf_ensure_modifiable(btf);
> if (err)
> @@ -2167,10 +2160,24 @@ int btf__add_str(struct btf *btf, const char *s)
> return libbpf_err(off);
^^^^^^^^^^^^^^^^^^^^^^
[Severity: Low]
Does the internal static function btf_add_local_str() incorrectly use the
libbpf_err() wrapper here, while the public API btf__add_str() below fails
to wrap its own error return?
>
> btf->hdr.str_len = strset__data_size(btf->strs_set);
> + btf->strs_deduped = false;
>
> return btf->start_str_off + off;
> }
>
> +int btf__add_str(struct btf *btf, const char *s)
> +{
> + int off;
> +
> + if (btf->base_btf) {
> + off = btf__find_str(btf->base_btf, s);
> + if (off != -ENOENT)
> + return off;
> + }
> +
> + return btf_add_local_str(btf, s);
> +}
[ ... ]
> @@ -6678,33 +6759,82 @@ int btf__permute(struct btf *btf, __u32 *id_map, __u32 id_map_cnt,
> if (err)
> goto done;
>
> + /*
> + * Build the inverse map: for each requested destination ID, record the
> + * original type ID that will occupy it. order_map is indexed by the
> + * destination ID relative to the first ID represented by id_map. The
> + * caller id_map maps old IDs to requested destinations, but BTF types
> + * must be emitted in destination-ID order; the inverse map supplies the
> + * old type to copy for each output slot without repeatedly searching
> + * id_map.
> + */
> for (i = start_offs; i < id_map_cnt; i++) {
> - id = id_map[i];
> - if (id < btf->start_id || id >= btf__type_cnt(btf)) {
> + __u32 requested_id = new_id_map[i];
> + __u32 order_idx;
> +
> + if (btf_permute_id_is_transfer(requested_id)) {
> + if (!transfer_btfp) {
> + err = -EINVAL;
> + goto done;
> + }
> + requested_id &= ~BTF_PERMUTE_ID_TRANSFER;
> + nr_transfer++;
> + }
> + if (requested_id < btf->start_id || requested_id >= btf__type_cnt(btf)) {
> err = -EINVAL;
> goto done;
> }
> - id -= btf->start_id - start_offs;
> + order_idx = requested_id - btf->start_id + start_offs;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[Severity: High]
This is a pre-existing issue, but does the order_idx calculation go out of
bounds for base BTFs?
For a base BTF, btf->start_id is 0 and start_offs is 1. If requested_id
reaches id_map_cnt - 1 (the maximum valid ID), order_idx will become
id_map_cnt.
This would cause an out-of-bounds access when writing to order_map[order_idx]
below, since order_map is allocated with size id_map_cnt.
> /* cannot be mapped to the same ID */
> - if (order_map[id]) {
> + if (order_map[order_idx]) {
> err = -EINVAL;
> goto done;
> }
> - order_map[id] = i + btf->start_id - start_offs;
> + order_map[order_idx] = i + btf->start_id - start_offs;
> + }
[ ... ]
> @@ -6729,18 +6916,58 @@ int btf__permute(struct btf *btf, __u32 *id_map, __u32 id_map_cnt,
> goto done;
> }
>
> - for (nt = new_types, i = 0; i < id_map_cnt - start_offs; i++) {
> + /* Install the compacted parent types and rebuild their index. */
> + for (nt = new_types, i = 0; i < nr_base_types; i++) {
> btf->type_offs[i] = nt - new_types;
> nt += btf_type_size(btf, nt);
> }
> -
> - free(order_map);
> free(btf->types_data);
> btf->types_data = new_types;
> + committed = true;
> + btf_hdr_update_type_len(btf, nt - new_types);
> + btf->nr_types = nr_base_types;
> +
> + /*
> + * An important goal is to also transfer strings to the transfer
> + * BTF where they do not have duplicates in BTF. This is important
> + * for cases like inline BTF where inline function names could
> + * comprise a significant portion of the string table. The approach
> + * is to first compact the set of strings in the base now transfer
> + * is complete; this will remove unreferenced strings. Then
> + * local references in the transfer BTF have to be moved downwards
> + * based upon that compaction. Finally also compact transfer BTF
> + * references so that we replace duplicate references in split with
> + * base references where present.
> + *
> + * Once all this is done, we end up with transfer-only strings in
> + * transfer split BTF and shared strings in BTF. The result is
> + * a transfer BTF with a lot of transfer-only strings will not
> + * pollute the string table of the non-transfer BTF.
> + */
> + if (transfer_btf) {
> + err = btf_compact_strings(btf, btf_ext);
> + if (err)
> + goto done;
^^^^^^^^^
[Severity: High]
If btf_compact_strings() fails here, we return an error but the
btf->types_data replacement has already been committed.
Does this leave the BTF object in an irreversibly corrupted state from the
caller's perspective, since id_map is not updated on the error path and the
transferred types are lost?
> + err = btf_permute_rebase_split_strs(transfer_btf, old_str_off);
> + if (err)
> + goto done;
> + err = btf_compact_strings(transfer_btf, NULL);
> + if (err)
> + goto done;
> + *transfer_btfp = transfer_btf;
> + }
> +
> + /* On success return the final old-to-new type-ID map to the caller. */
> + memcpy(id_map, new_id_map, id_map_cnt * sizeof(*id_map));
> + free(new_id_map);
> + free(order_map);
> return 0;
>
> done:
> + free(new_id_map);
> free(order_map);
> - free(new_types);
> + if (!committed)
> + free(new_types);
> + btf__free(transfer_btf);
> return libbpf_err(err);
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260901165757.801449-1-alan.maguire@oracle.com?part=3
next prev parent reply other threads:[~2026-09-01 17:15 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-01 16:57 [PATCH v2 bpf-next 00/18] Support inline functions in BTF Alan Maguire
2026-09-01 16:57 ` [PATCH v2 bpf-next 01/18] btf: Extend UAPI to support BTF location (inline site) info Alan Maguire
2026-09-01 17:17 ` sashiko-bot
2026-09-01 17:55 ` bot+bpf-ci
2026-09-01 16:57 ` [PATCH v2 bpf-next 02/18] libbpf: Add support for BTF kinds LOC[_PARAM|_PROTO|SEC] Alan Maguire
2026-09-01 17:11 ` sashiko-bot
2026-09-01 16:57 ` [PATCH v2 bpf-next 03/18] libbpf: Support moving permuted BTF types into split BTF Alan Maguire
2026-09-01 17:15 ` sashiko-bot [this message]
2026-09-01 18:14 ` bot+bpf-ci
2026-09-01 16:57 ` [PATCH v2 bpf-next 04/18] selftests/bpf: Test helper support for BTF_KIND_LOC[_PARAM|_PROTO|SEC] Alan Maguire
2026-09-01 17:06 ` sashiko-bot
2026-09-01 16:57 ` [PATCH v2 bpf-next 05/18] selftests/bpf: Add LOC_PARAM, LOC_PROTO, LOCSEC to field iter tests Alan Maguire
2026-09-01 16:57 ` [PATCH v2 bpf-next 06/18] selftests/bpf: Add LOC_PARAM, LOC_PROTO, LOCSEC to dedup split tests Alan Maguire
2026-09-01 17:55 ` bot+bpf-ci
2026-09-01 16:57 ` [PATCH v2 bpf-next 07/18] selftests/bpf: BTF distill tests to ensure LOC[_PARAM|_PROTO] add to split BTF Alan Maguire
2026-09-01 17:55 ` bot+bpf-ci
2026-09-01 16:57 ` [PATCH v2 bpf-next 08/18] selftests/bpf: Validate that btf__permute transfer works Alan Maguire
2026-09-01 17:16 ` sashiko-bot
2026-09-01 17:55 ` bot+bpf-ci
2026-09-01 16:57 ` [PATCH v2 bpf-next 09/18] bpftool: Handle multi-split BTF by supporting multiple base BTFs Alan Maguire
2026-09-01 17:13 ` sashiko-bot
2026-09-01 16:57 ` [PATCH v2 bpf-next 10/18] bpftool: Document support for multi-split BTF Alan Maguire
2026-09-01 17:12 ` sashiko-bot
2026-09-01 16:57 ` [PATCH v2 bpf-next 11/18] bpftool: Add ability to dump LOC_PARAM, LOC_PROTO and LOCSEC Alan Maguire
2026-09-01 17:16 ` sashiko-bot
2026-09-01 17:55 ` bot+bpf-ci
2026-09-01 16:57 ` [PATCH v2 bpf-next 12/18] resolve_btfids: Extract inline BTF Alan Maguire
2026-09-01 17:23 ` sashiko-bot
2026-09-01 16:57 ` [PATCH v2 bpf-next 13/18] kbuild: Add support for BTF inline information Alan Maguire
2026-09-01 17:55 ` bot+bpf-ci
2026-09-01 16:57 ` [PATCH v2 bpf-next 14/18] btf: Make vmlinux, module inline info available in /sys/kernel/btf Alan Maguire
2026-09-01 16:57 ` [PATCH v2 bpf-next 15/18] btf: Support CONFIG_DEBUG_INFO_BTF_INLINE=m Alan Maguire
2026-09-01 17:24 ` sashiko-bot
2026-09-01 16:57 ` [PATCH v2 bpf-next 16/18] btf: Relocate inline BTF for modules with distilled base BTF Alan Maguire
2026-09-01 17:29 ` sashiko-bot
2026-09-01 17:55 ` bot+bpf-ci
2026-09-01 16:57 ` [PATCH v2 bpf-next 17/18] selftests/bpf: Test BTF sysfs inline representations Alan Maguire
2026-09-01 17:22 ` sashiko-bot
2026-09-01 17:55 ` bot+bpf-ci
2026-09-01 16:57 ` [PATCH v2 bpf-next 18/18] selftests/bpf: Add a test verifying inline information Alan Maguire
2026-09-01 17:28 ` sashiko-bot
2026-09-01 17:55 ` bot+bpf-ci
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=20260901171505.2A73F1F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=alan.maguire@oracle.com \
--cc=bpf@vger.kernel.org \
--cc=linux-modules@vger.kernel.org \
--cc=sashiko-reviews@lists.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