]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Import patches from mainline to fix minor binutils bugs:
authorNick Clifton <nickc@redhat.com>
Tue, 5 Sep 2017 14:32:04 +0000 (15:32 +0100)
committerNick Clifton <nickc@redhat.com>
Tue, 5 Sep 2017 14:32:04 +0000 (15:32 +0100)
PR 21861
* winduni.c (codepages): Use cp1252 for codepage 0.

PR 21813
* rddbg.c (read_symbol_stabs_debugging_info): Check for an empty
string whilst concatenating symbol names.

PR 21909
* prdbg.c (pr_int_type): Increase size of local string buffer.
(pr_float_type): Likewise.
(pr_bool_type): Likewise.

PR 21820
* readelf.c (dump_section_as_strings): Do not fail if the section
was empty.
(dump_section_as_bytes): Likewise.

PR 21990
* readelf.c (process_version_sections <SHT_GNU_verneed>): Check
for invalid vn_next field before adding to idx.  Use unsigned
long for index vars.  Move index checks.
<SHT_GNU_verdef>: Likewise for vd_next.

PR 21994
* readelf.c (process_version_sections <SHT_GNU_verdef>): Check
vd_aux and vda_next for sanity.  Delete "end".  Correct overflow
checks.
(process_version_sections <SHT_GNU_verneed>): Correct overflow
check.  Don't report invalid vna_next on overflow.  Do report
invalid vna_next on size less than aux info.

binutils/ChangeLog
binutils/prdbg.c
binutils/rddbg.c
binutils/readelf.c
binutils/winduni.c

index f74a4367b8be1d9dda12a3721600badaccdf8fbd..cffc49a66ea1aee878663bece8900031ee052202 100644 (file)
@@ -6,6 +6,37 @@
        * readelf.c (process_mips_specific): Add checks for a NULL data
        pointer.
 
+       PR 21861
+       * winduni.c (codepages): Use cp1252 for codepage 0.
+
+       PR 21813
+       * rddbg.c (read_symbol_stabs_debugging_info): Check for an empty
+       string whilst concatenating symbol names.
+
+       PR 21909
+       * prdbg.c (pr_int_type): Increase size of local string buffer.
+       (pr_float_type): Likewise.
+       (pr_bool_type): Likewise.
+
+       PR 21820
+       * readelf.c (dump_section_as_strings): Do not fail if the section
+       was empty.
+       (dump_section_as_bytes): Likewise.
+
+       PR 21990
+       * readelf.c (process_version_sections <SHT_GNU_verneed>): Check
+       for invalid vn_next field before adding to idx.  Use unsigned
+       long for index vars.  Move index checks.
+       <SHT_GNU_verdef>: Likewise for vd_next.
+
+       PR 21994
+       * readelf.c (process_version_sections <SHT_GNU_verdef>): Check
+       vd_aux and vda_next for sanity.  Delete "end".  Correct overflow
+       checks.
+       (process_version_sections <SHT_GNU_verneed>): Correct overflow
+       check.  Don't report invalid vna_next on overflow.  Do report
+       invalid vna_next on size less than aux info.
+
 2017-08-12  Alan Modra  <amodra@gmail.com>
 
        * readelf.c (process_note): Qualify NT_GNU_BUILD_ATTRIBUTE notes
index 9bd01bc071a8704e0c0662708d4eae8338e3b6f6..7b24fbe61613da28708a3dd746e5bc2bb24b8d0a 100644 (file)
@@ -581,7 +581,7 @@ static bfd_boolean
 pr_int_type (void *p, unsigned int size, bfd_boolean unsignedp)
 {
   struct pr_handle *info = (struct pr_handle *) p;
-  char ab[10];
+  char ab[40];
 
   sprintf (ab, "%sint%d", unsignedp ? "u" : "", size * 8);
   return push_type (info, ab);
@@ -593,7 +593,7 @@ static bfd_boolean
 pr_float_type (void *p, unsigned int size)
 {
   struct pr_handle *info = (struct pr_handle *) p;
-  char ab[10];
+  char ab[40];
 
   if (size == 4)
     return push_type (info, "float");
@@ -623,7 +623,7 @@ static bfd_boolean
 pr_bool_type (void *p, unsigned int size)
 {
   struct pr_handle *info = (struct pr_handle *) p;
-  char ab[10];
+  char ab[40];
 
   sprintf (ab, "bool%d", size * 8);
 
index 1d8c4471887c29877ef23d021b05bb5b22ca9c61..b9780608cf366561cf4de2c261fb3c8248cbd55d 100644 (file)
@@ -303,7 +303,8 @@ read_symbol_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
            return FALSE;
          f = NULL;
 
-         while (s[strlen (s) - 1] == '\\'
+         while (strlen (s) > 0
+                && s[strlen (s) - 1] == '\\'
                 && ps + 1 < symend)
            {
              char *sc, *n;
index 934966219710dfd1840ba045da5dc9c9066f8a3a..fb16df8e2a9bf609f52f8a0f1cc73f51dacbb51e 100644 (file)
@@ -10153,9 +10153,8 @@ process_version_sections (FILE * file)
        case SHT_GNU_verdef:
          {
            Elf_External_Verdef * edefs;
-           unsigned int idx;
-           unsigned int cnt;
-           unsigned int end;
+           unsigned long idx;
+           unsigned long cnt;
            char * endbuf;
 
            found = TRUE;
@@ -10177,23 +10176,16 @@ process_version_sections (FILE * file)
              break;
            endbuf = (char *) edefs + section->sh_size;
 
-           /* PR 17531: file: id:000001,src:000172+005151,op:splice,rep:2.  */
-           end = (section->sh_info < section->sh_size
-                  ? section->sh_info : section->sh_size);
-           for (idx = cnt = 0; cnt < end; ++cnt)
+           for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
              {
                char * vstart;
                Elf_External_Verdef * edef;
                Elf_Internal_Verdef ent;
                Elf_External_Verdaux * eaux;
                Elf_Internal_Verdaux aux;
-               unsigned int isum;
+               unsigned long isum;
                int j;
 
-               /* Check for very large indices.  */
-               if (idx > (size_t) (endbuf - (char *) edefs))
-                 break;
-
                vstart = ((char *) edefs) + idx;
                if (vstart + sizeof (*edef) > endbuf)
                  break;
@@ -10208,19 +10200,20 @@ process_version_sections (FILE * file)
                ent.vd_aux     = BYTE_GET (edef->vd_aux);
                ent.vd_next    = BYTE_GET (edef->vd_next);
 
-               printf (_("  %#06x: Rev: %d  Flags: %s"),
+               printf (_("  %#06lx: Rev: %d  Flags: %s"),
                        idx, ent.vd_version, get_ver_flags (ent.vd_flags));
 
                printf (_("  Index: %d  Cnt: %d  "),
                        ent.vd_ndx, ent.vd_cnt);
 
-               /* Check for overflow and underflow.  */
-               if (ent.vd_aux + sizeof (* eaux) > (size_t) (endbuf - vstart)
-                   || (vstart + ent.vd_aux < vstart))
+               /* Check for overflow.  */
+               if (ent.vd_aux > (size_t) (endbuf - vstart))
                  break;
 
                vstart += ent.vd_aux;
 
+               if (vstart + sizeof (*eaux) > endbuf)
+                 break;
                eaux = (Elf_External_Verdaux *) vstart;
 
                aux.vda_name = BYTE_GET (eaux->vda_name);
@@ -10235,6 +10228,14 @@ process_version_sections (FILE * file)
 
                for (j = 1; j < ent.vd_cnt; j++)
                  {
+                   if (aux.vda_next < sizeof (*eaux)
+                       && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
+                     {
+                       warn (_("Invalid vda_next field of %lx\n"),
+                             aux.vda_next);
+                       j = ent.vd_cnt;
+                       break;
+                     }
                    /* Check for overflow.  */
                    if (aux.vda_next > (size_t) (endbuf - vstart))
                      break;
@@ -10242,18 +10243,18 @@ process_version_sections (FILE * file)
                    isum   += aux.vda_next;
                    vstart += aux.vda_next;
 
-                   eaux = (Elf_External_Verdaux *) vstart;
                    if (vstart + sizeof (*eaux) > endbuf)
                      break;
+                   eaux = (Elf_External_Verdaux *) vstart;
 
                    aux.vda_name = BYTE_GET (eaux->vda_name);
                    aux.vda_next = BYTE_GET (eaux->vda_next);
 
                    if (VALID_DYNAMIC_NAME (aux.vda_name))
-                     printf (_("  %#06x: Parent %d: %s\n"),
+                     printf (_("  %#06lx: Parent %d: %s\n"),
                              isum, j, GET_DYNAMIC_NAME (aux.vda_name));
                    else
-                     printf (_("  %#06x: Parent %d, name index: %ld\n"),
+                     printf (_("  %#06lx: Parent %d, name index: %ld\n"),
                              isum, j, aux.vda_name);
                  }
 
@@ -10262,7 +10263,14 @@ process_version_sections (FILE * file)
 
                /* PR 17531:
                   file: id:000001,src:000172+005151,op:splice,rep:2.  */
-               if (idx + ent.vd_next < idx)
+               if (ent.vd_next < sizeof (*edef)
+                   && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
+                 {
+                   warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
+                   cnt = section->sh_info;
+                   break;
+                 }
+               if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
                  break;
 
                idx += ent.vd_next;
@@ -10278,8 +10286,8 @@ process_version_sections (FILE * file)
        case SHT_GNU_verneed:
          {
            Elf_External_Verneed * eneed;
-           unsigned int idx;
-           unsigned int cnt;
+           unsigned long idx;
+           unsigned long cnt;
            char * endbuf;
 
            found = TRUE;
@@ -10305,13 +10313,10 @@ process_version_sections (FILE * file)
              {
                Elf_External_Verneed * entry;
                Elf_Internal_Verneed ent;
-               unsigned int isum;
+               unsigned long isum;
                int j;
                char * vstart;
 
-               if (idx > (size_t) (endbuf - (char *) eneed))
-                 break;
-
                vstart = ((char *) eneed) + idx;
                if (vstart + sizeof (*entry) > endbuf)
                  break;
@@ -10324,7 +10329,7 @@ process_version_sections (FILE * file)
                ent.vn_aux     = BYTE_GET (entry->vn_aux);
                ent.vn_next    = BYTE_GET (entry->vn_next);
 
-               printf (_("  %#06x: Version: %d"), idx, ent.vn_version);
+               printf (_("  %#06lx: Version: %d"), idx, ent.vn_version);
 
                if (VALID_DYNAMIC_NAME (ent.vn_file))
                  printf (_("  File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
@@ -10354,24 +10359,26 @@ process_version_sections (FILE * file)
                    aux.vna_next  = BYTE_GET (eaux->vna_next);
 
                    if (VALID_DYNAMIC_NAME (aux.vna_name))
-                     printf (_("  %#06x:   Name: %s"),
+                     printf (_("  %#06lx:   Name: %s"),
                              isum, GET_DYNAMIC_NAME (aux.vna_name));
                    else
-                     printf (_("  %#06x:   Name index: %lx"),
+                     printf (_("  %#06lx:   Name index: %lx"),
                              isum, aux.vna_name);
 
                    printf (_("  Flags: %s  Version: %d\n"),
                            get_ver_flags (aux.vna_flags), aux.vna_other);
 
-                   /* Check for overflow.  */
-                   if (aux.vna_next > (size_t) (endbuf - vstart)
-                       || (aux.vna_next == 0 && j < ent.vn_cnt - 1))
+                   if (aux.vna_next < sizeof (*eaux)
+                       && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
                      {
                        warn (_("Invalid vna_next field of %lx\n"),
                              aux.vna_next);
                        j = ent.vn_cnt;
                        break;
                      }
+                   /* Check for overflow.  */
+                   if (aux.vna_next > (size_t) (endbuf - vstart))
+                     break;
                    isum   += aux.vna_next;
                    vstart += aux.vna_next;
                  }
@@ -10379,12 +10386,15 @@ process_version_sections (FILE * file)
                if (j < ent.vn_cnt)
                  warn (_("Missing Version Needs auxillary information\n"));
 
-               if (ent.vn_next == 0 && cnt < section->sh_info - 1)
+               if (ent.vn_next < sizeof (*entry)
+                   && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
                  {
-                   warn (_("Corrupt Version Needs structure - offset to next structure is zero with entries still left to be processed\n"));
+                   warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
                    cnt = section->sh_info;
                    break;
                  }
+               if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
+                 break;
                idx += ent.vn_next;
              }
 
@@ -12837,7 +12847,9 @@ dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
   real_start = start = (unsigned char *) get_section_contents (section,
                                                               file);
   if (start == NULL)
-    return FALSE;
+    /* PR 21820: Do not fail if the section was empty.  */
+    return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
+
   num_bytes = section->sh_size;
 
   printf (_("\nString dump of section '%s':\n"), printable_section_name (section));
@@ -12983,7 +12995,8 @@ dump_section_as_bytes (Elf_Internal_Shdr * section,
 
   real_start = start = (unsigned char *) get_section_contents (section, file);
   if (start == NULL)
-    return FALSE;
+    /* PR 21820: Do not fail if the section was empty.  */
+    return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
 
   section_size = section->sh_size;
 
index 9868d4bc11fbb599cd76e68647e893ae69ebdcbf..ec4f71c5baa417ca934711d2626945c7cfcb30b2 100644 (file)
@@ -57,7 +57,7 @@ static int unichar_isascii (const unichar *, rc_uint_type);
 /* Codepages mapped.  */
 static local_iconv_map codepages[] =
 {
-  { 0, "MS-ANSI" },
+  { 0, "cp1252" },
   { 1, "WINDOWS-1252" },
   { 437, "MS-ANSI" },
   { 737, "MS-GREEK" },