Re: [PATCH bpf-next v5] libbpf: avoid overflow in BTF.ext bounds check
Andrii Nakryiko <[email protected]>
| Newsgroups | org.kernel.vger.linux-kselftest,org.kernel.vger.bpf,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CAEf4BzYUgrxxZ2DbXDe+bweKENhzNeeN5EnrG0D2xwLmm-yrTQ@mail.gmail.com> |
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; +