On Tue, Aug 11, 2026 at 9:49 AM Darren Carreras
<[email protected]> wrote:
>
> An invalid BTF.ext subsection length can wrap the pointer addition used by
> btf_ext_parse_sec_info() on 32-bit builds. The wrapped pointer passes the
> bounds check and parsing then reads beyond the copied BTF.ext data.
>
> Validate the offset and length with subtraction before forming the section
> pointer.
>
> Fixes: ae4ab4b4117d ("btf: expose API to work with raw btf_ext data")
> Closes: https://issues.oss-fuzz.com/issues/477315119
> Signed-off-by: Darren Carreras <[email protected]>
> ---
> Changes in v5:
> - Rebase onto bpf-next commit d114bb989367.
> - Attach one diff-only patch; the v4 MIME body contained a duplicated diff and
> could not be applied by CI.
>
> Changes in v4:
> - Drop the selftest because the malformed length is already rejected by the
> old check on 64-bit CI; the behavioral divergence is specific to 32-bit.
> - Correct the Fixes tag to the commit that introduced the pointer-based check.
>
> Changes in v3:
> - Remove the nested mbox envelope and mail headers from the Gmail attachment
> so Patchwork's generated mbox applies with git am.
>
> Changes in v2:
> - Resend as plain text because Gmail mangled the v1 diff and Patchwork
> reported "Patch is empty."
> - Include the authorized DCO Signed-off-by line.
It's hard to review and reply because you didn't post patch inline
(please don't do this for subsequent contributions), but here's the
gist:
- /* The start of the info sec (including the __u32 record_size). */
- info = btf_ext->data + btf_ext->hdr->hdr_len + ext_sec->off;
- info_left = ext_sec->len;
-
- if (btf_ext->data + btf_ext->data_size < info + ext_sec->len) {
+ data_left = btf_ext->data_size - btf_ext->hdr->hdr_len;
>From what I understand, you are trying to protect against corrupted
ELF that specifies invalid .BTF.ext ELF section size, is that right?
And your fix makes another assumption that btf_ext->hdr->hdr_len is
definitely not malformed, because otherwise this btf_ext->data_size -
btf_ext->hdr->hdr_len can underflow, no?
So in both cases, if ELF or BTF content is corrupted, there might be a problem.
+ if (ext_sec->off > data_left || ext_sec->len > data_left - ext_sec->off) {
pr_debug("%s section (off:%u len:%u) is beyond the end of the ELF
section .BTF.ext\n",
ext_sec->desc, ext_sec->off, ext_sec->len);
return -EINVAL;
}
+ /* The start of the info sec (including the __u32 record_size). */
+ info = btf_ext->data + btf_ext->hdr->hdr_len + ext_sec->off;
+ info_left = ext_sec->len;
+