Work around integer overflows when readelf is checking for corrupt ELF notes when...
authorMingi Cho <mgcho.minic@gmail.com>
Thu, 2 Nov 2017 17:01:08 +0000 (17:01 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 2 Nov 2017 17:01:08 +0000 (17:01 +0000)
PR 22384
* readelf.c (print_gnu_property_note): Improve overflow checks so
that they will work on a 32-bit host.

binutils/ChangeLog
binutils/readelf.c

index 231fc844b6b736bfe88c31536d3091fe9a1c3e5f..19f926155dd33772d5250895857e2611aa534f68 100644 (file)
@@ -1,3 +1,9 @@
+2017-11-02  Mingi Cho  <mgcho.minic@gmail.com>
+
+       PR 22384
+       * readelf.c (print_gnu_property_note): Improve overflow checks so
+       that they will work on a 32-bit host.
+
 2017-11-01  James Bowman  <james.bowman@ftdichip.com>
 
        * readelf.c (is_16bit_abs_reloc): Add entry for FT32.
index 9af5d42e8b5e2a159b2a545a7d7ecb08b78bb4da..cfd37eb3b6edb43799ee392beb5be9a1c05c6bff 100644 (file)
@@ -16519,15 +16519,24 @@ print_gnu_property_note (Elf_Internal_Note * pnote)
       return;
     }
 
-  while (1)
+  while (ptr < ptr_end)
     {
       unsigned int j;
-      unsigned int type = byte_get (ptr, 4);
-      unsigned int datasz = byte_get (ptr + 4, 4);
+      unsigned int type;
+      unsigned int datasz;
+
+      if ((size_t) (ptr_end - ptr) < 8)
+       {
+         printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
+         break;
+       }
+
+      type = byte_get (ptr, 4);
+      datasz = byte_get (ptr + 4, 4);
 
       ptr += 8;
 
-      if ((ptr + datasz) > ptr_end)
+      if (datasz > (size_t) (ptr_end - ptr))
        {
          printf (_("<corrupt type (%#x) datasz: %#x>\n"),
                  type, datasz);
@@ -16608,19 +16617,11 @@ next:
       ptr += ((datasz + (size - 1)) & ~ (size - 1));
       if (ptr == ptr_end)
        break;
-      else
-       {
-         if (do_wide)
-           printf (", ");
-         else
-           printf ("\n\t");
-       }
 
-      if (ptr > (ptr_end - 8))
-       {
-         printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
-         break;
-       }
+      if (do_wide)
+       printf (", ");
+      else
+       printf ("\n\t");
     }
 
   printf ("\n");