Re: [PATCH v15 bpf-next 6/9] libbpf: Support sanitization of BTF layout for older kernels
[email protected] Tue, 24 Mar 2026 18:55:29 +0000 (UTC)
| Newsgroups | org.kernel.vger.dwarves,org.kernel.vger.bpf |
|---|---|
| Message-ID | <ef3fe9d80d24f7498410bffe938da1882448e5b6012fcc3ca97fff5645018ba8@mail.kernel.org> |
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index 1eaa7527d4dab..e32b42ef9be84 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
[ ... ]
> + /* btf_header() gives us endian-safe header info */
> + hdr = btf_header(orig_btf);
> +
> + if (!has_layout && hdr->hdr_len >= sizeof(struct btf_header) &&
> + (hdr->layout_len != 0 || hdr->layout_off != 0)) {
> + const struct btf_header *old_hdr = raw_data;
> + struct btf_header *new_hdr;
> + void *new_raw_data;
> + __u32 new_str_off;
> +
> + /*
> + * Need to rewrite BTF to exclude layout information and
> + * move string section to immediately after types.
> + */
> + new_raw_data = malloc(sz);
> + if (!new_raw_data)
> + return ERR_PTR(-ENOMEM);
> +
> + memcpy(new_raw_data, raw_data, sz);
> + new_hdr = new_raw_data;
> + new_hdr->layout_off = 0;
> + new_hdr->layout_len = 0;
> + new_str_off = hdr->type_off + hdr->type_len;
> + /* Handle swapped endian case */
> + if (old_hdr->str_off != hdr->str_off)
> + new_hdr->str_off = bswap_32(new_str_off);
> + else
> + new_hdr->str_off = new_str_off;
> +
> + memmove(new_raw_data + hdr->hdr_len + new_hdr->str_off,
> + new_raw_data + hdr->hdr_len + hdr->str_off,
> + hdr->str_len);
In the swapped-endian case, new_hdr->str_off holds the byte-swapped
(file-endian) value after the bswap_32() above. When that value is
used here as a host memory offset for the memmove destination, it
produces a nonsensical address.
For example, if new_str_off is 24 (0x00000018), then bswap_32 gives
0x18000000, which is ~400 MB past the buffer. This would overflow
the malloc'd new_raw_data buffer.
Should the memmove destination use new_str_off (the host-endian
offset) instead of new_hdr->str_off? Something like:
memmove(new_raw_data + hdr->hdr_len + new_str_off,
new_raw_data + hdr->hdr_len + hdr->str_off,
hdr->str_len);
> + sz = hdr->hdr_len + hdr->type_off + hdr->type_len + hdr->str_len;
> + btf = btf__new(new_raw_data, sz);
> + free(new_raw_data);
[ ... ]
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/23504838405