]> git.ipfire.org Git - thirdparty/elfutils.git/commit
libelf: Bounds-check archive symbol index count on the mmap path
authorMatej Smycka <matejsmycka@gmail.com>
Fri, 3 Jul 2026 15:20:55 +0000 (17:20 +0200)
committerMark Wielaard <mark@klomp.org>
Fri, 3 Jul 2026 19:28:28 +0000 (21:28 +0200)
commit3a122a068285b5f64ee8324a7a425f3b632bbc78
tree932e86aea8a54f0aaae1ed2dbca6df1677daea0a
parent67093ba40c8231acba0b3c80c6156087d4bb297a
libelf: Bounds-check archive symbol index count on the mmap path

read_number_entries () reads the archive symbol index entry count.  On
the mmap path it copied w (4 or 8) bytes from the mapping without
checking that those bytes are present:

    if (elf->map_address != NULL)
      memcpy (&u, elf->map_address + *offp, w);
    else if ((size_t) pread_retry (elf->fildes, &u, w, *offp) != w)
      return -1;

The pread path rejects a short read, but the mmap path does not.  The
only preceding size check (SARMAG + sizeof (struct ar_hdr) >
maximum_size) covers the 68-byte index-member header; the count field
sits immediately after it and index_size (the member's real size) is
only validated later.  A mmap'd archive truncated to exactly the index
header (a "/" member with no content) therefore passes the header check,
and read_number_entries () reads w bytes past the end of the mapping.

This is the same defect addressed for the over-wide read in commit
8b192160 ("libelf: fix OOB read in elf_getarsym 32-bit archive index
count"), which narrowed the read from 8 to w bytes but did not add a
bounds check, so a sufficiently truncated archive still over-reads.

Reject the read when the count field lies outside the mapping, matching
the guarantee the pread path already provides.

Reproduced with a guard page: a 68-byte header-only archive built with
elf_memory () and placed at the end of a mapping with an inaccessible
page following it crashes on an unfixed build and returns
ELF_E_NO_INDEX on a fixed build.

Signed-off-by: Matej Smycka <matejsmycka@gmail.com>
libelf/elf_getarsym.c