Fix shift overflow when parsing an overlarge note value.
authorNick Clifton <nickc@redhat.com>
Fri, 21 Apr 2017 11:31:59 +0000 (12:31 +0100)
committerNick Clifton <nickc@redhat.com>
Fri, 21 Apr 2017 11:31:59 +0000 (12:31 +0100)
PR binutils/21378
* readelf.c (print_gnu_build_attribute_name): Check for an
overlarge name field.

binutils/ChangeLog
binutils/readelf.c

index 5f75c170fa8667c102d7fb2400652b0310149d56..e833b0554044414f7520c30cc804a854822dba14 100644 (file)
@@ -1,3 +1,9 @@
+2017-04-21  Nick Clifton  <nickc@redhat.com>
+
+       PR binutils/21378
+       * readelf.c (print_gnu_build_attribute_name): Check for an
+       overlarge name field.
+
 2017-04-13  Nick Clifton  <nickc@redhat.com>
 
        PR binutils/21379
index ab53473b4336930ddd84fad414d6f4c1077abb9f..e5756672f4906126f398b74febaf9ef2e67c2ba6 100644 (file)
@@ -16948,10 +16948,18 @@ print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
     {
     case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
       {
-       unsigned int   bytes = pnote->namesz - (name - pnote->namedata);
-       unsigned long  val = 0;
-       unsigned int   shift = 0;
-       char *         decoded = NULL;
+       unsigned int        bytes = pnote->namesz - (name - pnote->namedata);
+       unsigned long long  val = 0;
+       unsigned int        shift = 0;
+       char *              decoded = NULL;
+
+       /* PR 21378 */
+       if (bytes > sizeof (val))
+         {
+           error (_("corrupt name field: namesz of %lu is too large for a numeric value\n"),
+                  pnote->namesz);
+           return FALSE;
+         }
 
        while (bytes --)
          {
@@ -16995,9 +17003,9 @@ print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
        else
          {
            if (do_wide)
-             left -= printf ("0x%lx", val);
+             left -= printf ("0x%llx", val);
            else
-             left -= printf ("0x%-.*lx", left, val);
+             left -= printf ("0x%-.*llx", left, val);
          }
       }
       break;