From: Nick Clifton Date: Tue, 5 Sep 2017 14:32:04 +0000 (+0100) Subject: Import patches from mainline to fix minor binutils bugs: X-Git-Tag: binutils-2_29_1~20 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=64aa1246572306b72dc479b46d13ff749b0c3236;p=thirdparty%2Fbinutils-gdb.git Import patches from mainline to fix minor binutils bugs: 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 ): Check for invalid vn_next field before adding to idx. Use unsigned long for index vars. Move index checks. : Likewise for vd_next. PR 21994 * readelf.c (process_version_sections ): Check vd_aux and vda_next for sanity. Delete "end". Correct overflow checks. (process_version_sections ): Correct overflow check. Don't report invalid vna_next on overflow. Do report invalid vna_next on size less than aux info. --- diff --git a/binutils/ChangeLog b/binutils/ChangeLog index f74a4367b8b..cffc49a66ea 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -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 ): Check + for invalid vn_next field before adding to idx. Use unsigned + long for index vars. Move index checks. + : Likewise for vd_next. + + PR 21994 + * readelf.c (process_version_sections ): Check + vd_aux and vda_next for sanity. Delete "end". Correct overflow + checks. + (process_version_sections ): 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 * readelf.c (process_note): Qualify NT_GNU_BUILD_ATTRIBUTE notes diff --git a/binutils/prdbg.c b/binutils/prdbg.c index 9bd01bc071a..7b24fbe6161 100644 --- a/binutils/prdbg.c +++ b/binutils/prdbg.c @@ -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); diff --git a/binutils/rddbg.c b/binutils/rddbg.c index 1d8c4471887..b9780608cf3 100644 --- a/binutils/rddbg.c +++ b/binutils/rddbg.c @@ -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; diff --git a/binutils/readelf.c b/binutils/readelf.c index 93496621971..fb16df8e2a9 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -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; diff --git a/binutils/winduni.c b/binutils/winduni.c index 9868d4bc11f..ec4f71c5baa 100644 --- a/binutils/winduni.c +++ b/binutils/winduni.c @@ -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" },