Re: [PATCH v15 bpf-next 6/9] libbpf: Support sanitization of BTF layout for older kernels
Alan Maguire <[email protected]> Wed, 25 Mar 2026 17:39:34 +0000
| Newsgroups | org.kernel.vger.dwarves,org.kernel.vger.bpf |
|---|---|
| Message-ID | <[email protected]> |
On 24/03/2026 18:55, [email protected] wrote: >> 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); > yep, this is a legit issue and the fix makes sense. sashiko.dev [1] also pointed out it would be better to use hdr->magic for endian comparison. It also suggested doing endian swaps for layout info despite the only endian-impacted field being the unused flags, and given that this will avoid future issues if/when flags starts being used I think that makes sense too. I'll wait a few days for additional feedback if any and roll v16.. [1] https://sashiko.dev/#/patchset/20260324174450.1570809-1-alan.maguire%40oracle.com >> + 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