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 <[email protected]>
---

This, plus Aaron's fix for libdw_open_elf, should resolve the ossfuzz
issues.

 libelf/elf_begin.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index 7e722ea642b9..d3ab887d34e3 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -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)
     {
-- 
2.50.1

Reply via email to