Unsigned integer overflows in readelf checks
authorAlan Modra <amodra@gmail.com>
Wed, 20 Feb 2019 07:52:50 +0000 (18:22 +1030)
committerAlan Modra <amodra@gmail.com>
Wed, 20 Feb 2019 07:52:50 +0000 (18:22 +1030)
PR 24132
PR 24138
* readelf.c (get_data): Avoid possibility of overflow when
checking for a read that may extend past end of file.
(process_program_headers): Likewise.

binutils/ChangeLog
binutils/readelf.c

index ce933ba..ff67363 100644 (file)
@@ -1,5 +1,13 @@
 2019-02-20  Alan Modra  <amodra@gmail.com>
 
+       PR 24132
+       PR 24138
+       * readelf.c (get_data): Avoid possibility of overflow when
+       checking for a read that may extend past end of file.
+       (process_program_headers): Likewise.
+
+2019-02-20  Alan Modra  <amodra@gmail.com>
+
        PR 24233
        * objdump.c (dump_bfd_private_header): Print warning if
        bfd_print_private_bfd_data returns false.
index 77acc6a..3f424c4 100644 (file)
@@ -398,10 +398,11 @@ get_data (void *         var,
       return NULL;
     }
 
-  /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
+  /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
      attempting to allocate memory when the read is bound to fail.  */
-  if (amt > filedata->file_size
-      || offset + archive_file_offset + amt > filedata->file_size)
+  if (archive_file_offset > filedata->file_size
+      || offset > filedata->file_size - archive_file_offset
+      || amt > filedata->file_size - archive_file_offset - offset)
     {
       if (reason)
        error (_("Reading %s bytes extends past end of file for %s\n"),
@@ -5235,7 +5236,8 @@ process_program_headers (Filedata * filedata)
             segment.  Check this after matching against the section headers
             so we don't warn on debuginfo file (which have NOBITS .dynamic
             sections).  */
-         if (dynamic_addr + dynamic_size >= filedata->file_size)
+         if (dynamic_addr > filedata->file_size
+             || dynamic_size > filedata->file_size - dynamic_addr)
            {
              error (_("the dynamic segment offset + size exceeds the size of the file\n"));
              dynamic_addr = dynamic_size = 0;