Re: [PATCH v9 bpf-next 02/10] libbpf: Support layout section handling in BTF
Alan Maguire <[email protected]>
| Newsgroups | org.kernel.vger.dwarves,org.kernel.vger.bpf |
|---|---|
| Message-ID | <[email protected]> |
On 26/02/2026 10:05, [email protected] wrote: >> diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c >> index 83fe79ffcb8f..3438cc15bb7a 100644 >> --- a/tools/lib/bpf/btf.c >> +++ b/tools/lib/bpf/btf.c > > [ ... ] > >> @@ -224,66 +242,95 @@ static void btf_bswap_hdr(struct btf_header *h) > > [ ... ] > >> static int btf_parse_hdr(struct btf *btf) >> { >> - struct btf_header *hdr = btf->hdr; >> + struct btf_header *hdr = btf->raw_data; >> + __u32 hdr_len = hdr->hdr_len; > > [ ... ] > >> + memcpy(&btf->hdr, hdr, min((size_t)hdr_len, sizeof(struct btf_header))); > > The memcpy here correctly caps the copy at sizeof(struct btf_header), > but btf->hdr.hdr_len retains the original value from the raw data. > If the input BTF has a future-extended header where hdr_len exceeds > sizeof(struct btf_header), only sizeof(struct btf_header) bytes are > stored, yet hdr_len remembers the larger original value. This > matters in btf_get_raw_data() below. > > [ ... ] > >> @@ -1601,7 +1664,7 @@ static const void *btf_strs_data(const struct btf *btf) >> >> static void *btf_get_raw_data(const struct btf *btf, __u32 *size, bool swap_endian) >> { >> - struct btf_header *hdr = btf->hdr; >> + const struct btf_header *hdr = &btf->hdr; >> struct btf_type *t; >> void *data, *p; >> __u32 data_sz; > > [ ... ] > >> memcpy(p, hdr, hdr->hdr_len); > > When hdr_len > sizeof(struct btf_header), does this read past the > end of the embedded btf->hdr struct? hdr points to &btf->hdr which > is sizeof(struct btf_header) bytes, but hdr->hdr_len can be larger > if the parsed BTF had a future-extended header. The extra bytes > would come from adjacent struct btf fields (types_data, etc.), > leaking internal state into the serialized output. > > Previously, btf->hdr pointed directly into raw_data where the full > header (including any extension bytes) was available. The switch to > an embedded struct loses those extra bytes, but the serialization > still tries to write hdr_len bytes. > > One possible fix: > > memcpy(p, hdr, min((__u32)sizeof(struct btf_header), hdr->hdr_len)); > if (hdr->hdr_len > sizeof(struct btf_header)) > memset(p + sizeof(struct btf_header), 0, > hdr->hdr_len - sizeof(struct btf_header)); > yep, this is a good catch, will fix. >> if (swap_endian) >> - btf_bswap_hdr(p); >> + btf_bswap_hdr(p, hdr->hdr_len); >> p += hdr->hdr_len; > > [ ... ] > > > --- > 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/22436234361 > > AI-authorship-score: low > AI-authorship-explanation: The patch went through nine review iterations on lore with detailed human reviewer interactions, follows established libbpf patterns, and the subtle header over-read is characteristic of human-authored refactoring. > issues-found: 1 > issue-severity-score: medium > issue-severity-explanation: btf_get_raw_data() reads past the embedded btf->hdr struct into adjacent fields when hdr_len exceeds sizeof(struct btf_header), silently leaking internal state into serialized BTF output.