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 ce933babfe16a931e56d1981e0a6a13af25cb525..ff67363169f479e35034f58e41ee5350fdec136b 100644 (file)
@@ -1,3 +1,11 @@
+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
index 77acc6a7b42154b6f992959a8bf89ca4483b91d2..3f424c4e63d6779c27c83a2ad8a0d02217fb696b 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;