[PATCH] libctf: allow ctf_arc_bufpreamble to fail
Nick Alcock
nick.alcock@oracle.com
Tue Nov 4 12:21:56 GMT 2025
More information about the Binutils mailing list
Tue Nov 4 12:21:56 GMT 2025
- Previous message (by thread): ctf-archive sanity checks
- Next message (by thread): GNU Tools Weekly News Week 10 (November 2, 2025)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
The recent libctf fix for ctf_arc_bufpreamble missed a case:
what if the input is exactly sizeof (ctf_archive_t) in size (which can
happen if the archive has no members at all, so returning the preamble
from one of the members is in any case impossible?). In this case
it'll return an off-the-end pointer, and its caller will overrun.
(This can also happen with fuzzed input which has a valid magic
number.)
Allow it to fail in this case, returning NULL, and adjust its sole
caller. The caller's conclusions in this case will be wrong (it will
conclude that the archive is connected to .symtab), but the incorrect
conclusions are harmless because the lack of archive members will
immediately cause a failure in ctf_arc_bufopen(), and an error return.
Thanks to Alan Modra for the original fix this soups up.
libctf/
PR libctf/33548
* ctf-archive.c (ctf_arc_bufpreamble): Fail if the archive is
too short (or empty, with no dicts to contain preambles),
returning NULL.
* ctf-open-bfd.c (ctf_bfdopen_ctfsect): Handle a NULL return.
---
libctf/ctf-archive.c | 13 +++++++++----
libctf/ctf-open-bfd.c | 4 ++--
2 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/libctf/ctf-archive.c b/libctf/ctf-archive.c
index 63184e66244..217d6d4f7c5 100644
--- a/libctf/ctf-archive.c
+++ b/libctf/ctf-archive.c
@@ -389,14 +389,19 @@ ctf_arc_symsect_endianness (ctf_archive_t *arc, int little_endian)
/* Get the CTF preamble from data in a buffer, which may be either an archive or
a CTF dict. If multiple dicts are present in an archive, the preamble comes
from an arbitrary dict. The preamble is a pointer into the ctfsect passed
- in. */
+ in. Returns NULL if this cannot be a CTF archive or dict at all. */
const ctf_preamble_t *
ctf_arc_bufpreamble (const ctf_sect_t *ctfsect)
{
- if (ctfsect->cts_data != NULL
- && ctfsect->cts_size >= sizeof (struct ctf_archive)
- && (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
+ if (ctfsect->cts_data == NULL
+ || ctfsect->cts_size < sizeof (uint64_t)
+ || (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC
+ && ctfsect->cts_size < (sizeof (ctf_archive_t) + sizeof (uint64_t))))
+ return NULL;
+
+ if (ctfsect->cts_size >= (sizeof (struct ctf_archive) + sizeof (uint64_t))
+ && le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC)
{
struct ctf_archive *arc = (struct ctf_archive *) ctfsect->cts_data;
return (const ctf_preamble_t *) ((char *) arc + le64toh (arc->ctfa_ctfs)
diff --git a/libctf/ctf-open-bfd.c b/libctf/ctf-open-bfd.c
index 7241de70709..03ba5b67305 100644
--- a/libctf/ctf-open-bfd.c
+++ b/libctf/ctf-open-bfd.c
@@ -120,13 +120,13 @@ ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_,
}
preamble = ctf_arc_bufpreamble (ctfsect);
- if (preamble->ctp_flags & CTF_F_DYNSTR)
+ if (preamble && (preamble->ctp_flags & CTF_F_DYNSTR))
{
symhdr = &elf_tdata (abfd)->dynsymtab_hdr;
strtab_name = ".dynstr";
symtab_name = ".dynsym";
}
- else
+ else /* Might not be CTF at all: ctf_arc_bufopen will fail if so. */
{
symhdr = &elf_tdata (abfd)->symtab_hdr;
strtab_name = ".strtab";
--
2.51.0.284.g117bcb8de7
- Previous message (by thread): ctf-archive sanity checks
- Next message (by thread): GNU Tools Weekly News Week 10 (November 2, 2025)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list