]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libelf: Add some ar header sanity checking.
authorMark Wielaard <mjw@redhat.com>
Thu, 11 Dec 2014 15:28:57 +0000 (16:28 +0100)
committerMark Wielaard <mjw@redhat.com>
Mon, 15 Dec 2014 09:03:03 +0000 (10:03 +0100)
Don't allow entries or size to overflow the parent file size.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
libelf/ChangeLog
libelf/elf_begin.c

index 4860530b85a8b6013e1991e4b3263b3ce3730934..e4c58499a299bec93cb3ed524f8f599032189f03 100644 (file)
@@ -1,3 +1,9 @@
+2014-12-11  Mark Wielaard  <mjw@redhat.com>
+
+       * elf_begin.c (read_long_names): Check for offset overflow.
+       (__libelf_next_arhdr_wrlock): Likewise. Sanity check the ar_size.
+       Don't allow it to go beyond end of file.
+
 2014-12-09  Mark Wielaard  <mjw@redhat.com>
 
        * elf_getarsym.c (elf_getarsym): Make sure n * w doesn't overflow.
index d135deab15052d80a747a0320ed5cdfce3af8655..99a9c0a099719b30402aae956bf792931425dea2 100644 (file)
@@ -673,7 +673,8 @@ read_long_names (Elf *elf)
     {
       if (elf->map_address != NULL)
        {
-         if (offset + sizeof (struct ar_hdr) > elf->maximum_size)
+         if ((size_t) offset > elf->maximum_size
+             || elf->maximum_size - offset < sizeof (struct ar_hdr))
            return NULL;
 
          /* The data is mapped.  */
@@ -767,8 +768,10 @@ __libelf_next_arhdr_wrlock (elf)
   if (elf->map_address != NULL)
     {
       /* See whether this entry is in the file.  */
-      if (unlikely (elf->state.ar.offset + sizeof (struct ar_hdr)
-                   > elf->start_offset + elf->maximum_size))
+      if (unlikely ((size_t) elf->state.ar.offset
+                   > elf->start_offset + elf->maximum_size
+                   || (elf->start_offset + elf->maximum_size
+                       - elf->state.ar.offset) < sizeof (struct ar_hdr)))
        {
          /* This record is not anymore in the file.  */
          __libelf_seterrno (ELF_E_RANGE);
@@ -912,6 +915,12 @@ __libelf_next_arhdr_wrlock (elf)
   INT_FIELD (ar_mode);
   INT_FIELD (ar_size);
 
+  /* Truncated file?  */
+  size_t maxsize;
+  maxsize = elf->maximum_size - elf->state.ar.offset - sizeof (struct ar_hdr);
+  if ((size_t) elf_ar_hdr->ar_size > maxsize)
+    elf_ar_hdr->ar_size = maxsize;
+
   return 0;
 }