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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.