]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libelf: Check ELF parent size can contain ar member
authorMark Wielaard <mark@klomp.org>
Sat, 6 Sep 2025 10:39:15 +0000 (12:39 +0200)
committerMark Wielaard <mark@klomp.org>
Sat, 6 Sep 2025 21:55:55 +0000 (23:55 +0200)
Don't trust the ar header offset and size. When creating an Elf
descriptor for an ar member check the offset isn't past the end of the
containing Elf and don't use/set the member maximum_size larger than
the remaining size of the parent.

* libelf/elf_begin.c (dup_elf): Only call read_file if the
        offset isn't past the end and with a maximum_size not too large.

Signed-off-by: Mark Wielaard <mark@klomp.org>
libelf/elf_begin.c

index 7e722ea642b9ed0bdb47f3656af23da759f4c6cd..d3ab887d34e3db4910bf41940da63bb1ba834de4 100644 (file)
@@ -1113,9 +1113,16 @@ dup_elf (int fildes, Elf_Cmd cmd, Elf *ref)
     return NULL;
 
   /* We have all the information we need about the next archive member.
-     Now create a descriptor for it.  */
-  result = read_file (fildes, ref->state.ar.offset + sizeof (struct ar_hdr),
-                     ref->state.ar.elf_ar_hdr.ar_size, cmd, ref);
+     Now create a descriptor for it. Check parent size can contain member.  */
+  size_t max_size = ref->maximum_size;
+  size_t offset = (size_t) ref->state.ar.offset;
+  size_t hdr_size = sizeof (struct ar_hdr);
+  size_t ar_size = (size_t) ref->state.ar.elf_ar_hdr.ar_size;
+  if (max_size - hdr_size < offset)
+    return NULL;
+  else
+    result = read_file (fildes, ref->state.ar.offset + sizeof (struct ar_hdr),
+                       MIN (max_size - hdr_size - offset, ar_size), cmd, ref);
 
   if (result != NULL)
     {