From f65434a0e9a6e7adb4a9b331a0535e4f788303a25c1f0cb718432a95352e9533 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Fri, 17 Mar 2017 15:42:08 +0000 Subject: [PATCH] - Add fix-security-bugs.diff to fix bnc#1029907, bnc#1029908, bnc#1029909 and more. Upstream bugs fixed: PR 21135, PR 21137, PR 21139, PR 21147, PR 21148, PR 21149, PR 21150, PR 21151, PR 21155, PR 21156, PR 21157, PR 21158, PR 21159 OBS-URL: https://build.opensuse.org/package/show/devel:gcc/binutils?expand=0&rev=233 --- binutils.changes | 9 + binutils.spec | 2 + fix-security-bugs.diff | 762 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 773 insertions(+) create mode 100644 fix-security-bugs.diff diff --git a/binutils.changes b/binutils.changes index f43c9bc..a4f65a5 100644 --- a/binutils.changes +++ b/binutils.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Fri Mar 17 15:28:26 UTC 2017 - matz@suse.com + +- Add fix-security-bugs.diff to fix bnc#1029907, bnc#1029908, + bnc#1029909 and more. Upstream bugs fixed: + PR 21135, PR 21137, PR 21139, PR 21147, PR 21148, PR 21149, + PR 21150, PR 21151, PR 21155, PR 21156, PR 21157, PR 21158, + PR 21159 + ------------------------------------------------------------------- Wed Mar 8 11:25:04 UTC 2017 - rguenther@suse.com diff --git a/binutils.spec b/binutils.spec index 7d77b50..3b20208 100644 --- a/binutils.spec +++ b/binutils.spec @@ -99,6 +99,7 @@ Patch22: binutils-bfd_h.patch Patch34: aarch64-common-pagesize.patch # Backport 758d96d834ba725461a Patch36: binutils-bso21193.diff +Patch37: fix-security-bugs.diff Patch90: cross-avr-nesc-as.patch Patch92: cross-avr-omit_section_dynsym.patch Patch93: cross-avr-size.patch @@ -175,6 +176,7 @@ echo "make check will return with %{make_check_handling} in case of testsuite fa %patch22 %patch34 -p1 %patch36 -p1 +%patch37 -p1 %if "%{TARGET}" == "avr" cp gas/config/tc-avr.h gas/config/tc-avr-nesc.h %patch90 diff --git a/fix-security-bugs.diff b/fix-security-bugs.diff new file mode 100644 index 0000000..73013b7 --- /dev/null +++ b/fix-security-bugs.diff @@ -0,0 +1,762 @@ +This contains a merge of the following commits. +It fixes bnc#1029907, bnc#1029908, bnc#1029909 and more. + +commit 03f7786e2f440b9892b1c34a58fb26222ce1b493 +Author: Nick Clifton +Date: Mon Feb 13 13:08:32 2017 +0000 + + Fix readelf writing to illegal addresses whilst processing corrupt input files containing symbol-difference relocations. + + PR binutils/21137 + * readelf.c (target_specific_reloc_handling): Add end parameter. + Check for buffer overflow before writing relocated values. + (apply_relocations): Pass end to target_specific_reloc_handling. + +commit f84ce13b6708801ca1d6289b7c4003e2f5a6d7f9 +Author: Nick Clifton +Date: Mon Feb 13 14:03:22 2017 +0000 + + Fix read-after-free error in readelf when processing multiple, relocated sections in an MSP430 binary. + + PR binutils/21139 + * readelf.c (target_specific_reloc_handling): Add num_syms + parameter. Check for symbol table overflow before accessing + symbol value. If reloc pointer is NULL, discard all saved state. + (apply_relocations): Pass num_syms to target_specific_reloc_handling. + Call target_specific_reloc_handling with a NULL reloc pointer + after processing all of the relocs. + +commit 0ee3043f58aae078a1ecc54b7be2810cae39a718 +Author: Nick Clifton +Date: Mon Feb 13 14:17:07 2017 +0000 + + Fix access violation when reporting sections that could not be dumped. + + PR binutils/21147 + * readelf.c (process_section_contents): Fix off by one error + reporting un-dumped sections. + +commit 4aeb00ad3cc6a29b32f0a4e42c2f64d55e25b76d +Author: Nick Clifton +Date: Mon Feb 13 14:35:24 2017 +0000 + + Fix check for buffer overflow when processing version information. + + PR binutils/21148 + * readelf.c (process_version_sections): Include size of auxillary + version information when checking for buffer overflow. + +commit ebdf1ebfa551fd4624c3cd05401aa3c01ea2ebbe +Author: Nick Clifton +Date: Mon Feb 13 14:52:48 2017 +0000 + + Fix invalid memory access attempting to read the compression header of a too-small compressed section. + + PR binutils/21149 + * readelf.c (get_compression_header): Add size parameter. Check + size against sizeof compression header before attempting to + extract the header. + (process_section_headers): Pass size to get_compression_header. + (dump_section_as_strings): Likewise. + (dump_section_as_bytes): Likewise. + (load_specific_debug_section): Likewise. + +commit f055032e4e922f1e1a5e11026c7c2669fa2a7d19 +Author: Nick Clifton +Date: Mon Feb 13 15:04:37 2017 +0000 + + Fix invalid read of section contents whilst processing a corrupt binary. + + PR binutils/21135 + * readelf.c (dump_section_as_bytes): Handle the case where + uncompress_section_contents returns false. + +commit 1835f746a7c7fff70a2cc03a051b14fdc6b3f73f +Author: Nick Clifton +Date: Mon Feb 13 15:19:48 2017 +0000 + + Extend previous patch to cover uncompress_section_contents returning FALSE to other callers. + + PR binutils/21135 + (dump_section_as_bytes, load_specific_debug_section): Likewise. + +commit c12214021dedefcc2320827bcc1751f2d94ca2c6 +Author: Nick Clifton +Date: Mon Feb 13 17:23:10 2017 +0000 + + Fix illegal memory access bug in nm when run on a corrupt binary. + + PR binutils/21150 + * nm.c (file_symbol): Add test of string length before testing + string characters. + +commit d11135f55294d75099ad03f81bacbe8ae93a6b28 +Author: Nick Clifton +Date: Mon Feb 13 17:51:27 2017 +0000 + + Fix invalid memory access in the BFD library's DWARF parser. + + PR binutils/21151 + * dwarf2.c (_bfd_dwarf2_find_nearest_line): Check for an invalid + unit length field. + +commit b32e566ba6ee02687c6def22ade0899076adf7dd +Author: Nick Clifton +Date: Tue Feb 14 13:24:09 2017 +0000 + + Fix illegal memory access problems with readelf processing corrupt RL78 binaries. + + PR binutils/21155 + * readelf.c (IN_RANGE): New macro. Tests for an address + offset + being within a given range. + (target_specific_reloc_handling): Use macro to test for underflow + as well as overflow of reloc offset. + +commit a2dea0b20bc66a4c287c3c50002b8c3b3e9d953a +Author: Nick Clifton +Date: Tue Feb 14 14:07:29 2017 +0000 + + Fix handling of corrupt STABS enum type strings. + + PR binutils/21157 + * stabs.c (parse_stab_enum_type): Check for corrupt NAME:VALUE + pairs. + (parse_number): Exit early if passed an empty string. + +commit 92134dc19b4bf6407a88a306b771c9c6c88658d6 +Author: Nick Clifton +Date: Tue Feb 14 14:17:09 2017 +0000 + + Fix an illegal memory access parsing corrupt STABD debug information. + + PR binutils/21158 + * rddbg.c (read_symbol_stabs_debugging_info): Check for a null or + empty symbol name. + +commit bc303e5d6c2dd33086478f80fd1d3096d4e1bc01 +Author: Nick Clifton +Date: Tue Feb 14 15:10:34 2017 +0000 + + Fix invalid memory access displayiing contents of sections. + + PR binutils/21159 + * readelf.c (dump_section_as_strings): Reset the start address if + no decompression is perfromed. + (dump_section_as_bytes): Likewise. + +commit b814a36d3440de95f2ac6eaa4fc7935c322ea456 +Author: Nick Clifton +Date: Fri Feb 17 15:59:45 2017 +0000 + + Fix illegal memory accesses in readelf when parsing a corrupt binary. + + PR binutils/21156 + * readelf.c (find_section_in_set): Test for invalid section + indicies. + +commit 43a444f9c5bfd44b4304eafd78338e21d54bea14 +Author: Nick Clifton +Date: Mon Feb 20 14:40:39 2017 +0000 + + Fix another memory access error in readelf when parsing a corrupt binary. + + PR binutils/21156 + * dwarf.c (cu_tu_indexes_read): Move into... + (load_cu_tu_indexes): ... here. Change the variable into + tri-state. Change the function into boolean, returning + false if the indicies could not be loaded. + (find_cu_tu_set): Return NULL if the indicies could not be + loaded. + +commit 6438d1be9e9b6802a465c70c76b9cec7e23270f3 +Author: Nick Clifton +Date: Fri Feb 17 11:39:20 2017 +0000 + + Fix potential illegal memory access in ZLIB because of an erroneous declaration of the size of the input buffer. + + * compress.c (bfd_get_full_section_contents): Remember to reduce + compressed size by the sizeof the compression header when + decompressing the contents. + +Index: binutils-2.28/binutils/readelf.c +=================================================================== +--- binutils-2.28.orig/binutils/readelf.c 2017-03-02 09:23:53.000000000 +0100 ++++ binutils-2.28/binutils/readelf.c 2017-03-17 16:24:11.000000000 +0100 +@@ -675,8 +675,14 @@ find_section_in_set (const char * name, + if (set != NULL) + { + while ((i = *set++) > 0) +- if (streq (SECTION_NAME (section_headers + i), name)) +- return section_headers + i; ++ { ++ /* See PR 21156 for a reproducer. */ ++ if (i >= elf_header.e_shnum) ++ continue; /* FIXME: Should we issue an error message ? */ ++ ++ if (streq (SECTION_NAME (section_headers + i), name)) ++ return section_headers + i; ++ } + } + + return find_section (name); +@@ -5708,12 +5714,18 @@ get_elf_section_flags (bfd_vma sh_flags) + } + + static unsigned int +-get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf) ++get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size) + { + if (is_32bit_elf) + { + Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf; + ++ if (size < sizeof (* echdr)) ++ { ++ error (_("Compressed section is too small even for a compression header\n")); ++ return 0; ++ } ++ + chdr->ch_type = BYTE_GET (echdr->ch_type); + chdr->ch_size = BYTE_GET (echdr->ch_size); + chdr->ch_addralign = BYTE_GET (echdr->ch_addralign); +@@ -5723,6 +5735,12 @@ get_compression_header (Elf_Internal_Chd + { + Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf; + ++ if (size < sizeof (* echdr)) ++ { ++ error (_("Compressed section is too small even for a compression header\n")); ++ return 0; ++ } ++ + chdr->ch_type = BYTE_GET (echdr->ch_type); + chdr->ch_size = BYTE_GET (echdr->ch_size); + chdr->ch_addralign = BYTE_GET (echdr->ch_addralign); +@@ -6304,7 +6322,7 @@ process_section_headers (FILE * file) + { + Elf_Internal_Chdr chdr; + +- (void) get_compression_header (&chdr, buf); ++ (void) get_compression_header (&chdr, buf, sizeof (buf)); + + if (chdr.ch_type == ELFCOMPRESS_ZLIB) + printf (" ZLIB, "); +@@ -10012,7 +10030,7 @@ process_version_sections (FILE * file) + ent.vd_ndx, ent.vd_cnt); + + /* Check for overflow. */ +- if (ent.vd_aux > (size_t) (endbuf - vstart)) ++ if (ent.vd_aux + sizeof (* eaux) > (size_t) (endbuf - vstart)) + break; + + vstart += ent.vd_aux; +@@ -11577,16 +11595,32 @@ process_syminfo (FILE * file ATTRIBUTE_U + return 1; + } + ++#define IN_RANGE(START,END,ADDR,OFF) \ ++ (((ADDR) >= (START)) && ((ADDR) + (OFF) < (END))) ++ + /* Check to see if the given reloc needs to be handled in a target specific + manner. If so then process the reloc and return TRUE otherwise return +- FALSE. */ ++ FALSE. ++ ++ If called with reloc == NULL, then this is a signal that reloc processing ++ for the current section has finished, and any saved state should be ++ discarded. */ + + static bfd_boolean + target_specific_reloc_handling (Elf_Internal_Rela * reloc, + unsigned char * start, +- Elf_Internal_Sym * symtab) ++ unsigned char * end, ++ Elf_Internal_Sym * symtab, ++ unsigned long num_syms) + { +- unsigned int reloc_type = get_reloc_type (reloc->r_info); ++ unsigned int reloc_type = 0; ++ unsigned long sym_index = 0; ++ ++ if (reloc) ++ { ++ reloc_type = get_reloc_type (reloc->r_info); ++ sym_index = get_reloc_symindex (reloc->r_info); ++ } + + switch (elf_header.e_machine) + { +@@ -11595,6 +11629,12 @@ target_specific_reloc_handling (Elf_Inte + { + static Elf_Internal_Sym * saved_sym = NULL; + ++ if (reloc == NULL) ++ { ++ saved_sym = NULL; ++ return TRUE; ++ } ++ + switch (reloc_type) + { + case 10: /* R_MSP430_SYM_DIFF */ +@@ -11602,7 +11642,12 @@ target_specific_reloc_handling (Elf_Inte + break; + /* Fall through. */ + case 21: /* R_MSP430X_SYM_DIFF */ +- saved_sym = symtab + get_reloc_symindex (reloc->r_info); ++ /* PR 21139. */ ++ if (sym_index >= num_syms) ++ error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"), ++ sym_index); ++ else ++ saved_sym = symtab + sym_index; + return TRUE; + + case 1: /* R_MSP430_32 or R_MSP430_ABS32 */ +@@ -11624,13 +11669,24 @@ target_specific_reloc_handling (Elf_Inte + handle_sym_diff: + if (saved_sym != NULL) + { ++ int reloc_size = reloc_type == 1 ? 4 : 2; + bfd_vma value; + +- value = reloc->r_addend +- + (symtab[get_reloc_symindex (reloc->r_info)].st_value +- - saved_sym->st_value); ++ if (sym_index >= num_syms) ++ error (_("MSP430 reloc contains invalid symbol index %lu\n"), ++ sym_index); ++ else ++ { ++ value = reloc->r_addend + (symtab[sym_index].st_value ++ - saved_sym->st_value); + +- byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2); ++ if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size)) ++ byte_put (start + reloc->r_offset, value, reloc_size); ++ else ++ /* PR 21137 */ ++ error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"), ++ (long) reloc->r_offset); ++ } + + saved_sym = NULL; + return TRUE; +@@ -11650,24 +11706,45 @@ target_specific_reloc_handling (Elf_Inte + { + static Elf_Internal_Sym * saved_sym = NULL; + ++ if (reloc == NULL) ++ { ++ saved_sym = NULL; ++ return TRUE; ++ } ++ + switch (reloc_type) + { + case 34: /* R_MN10300_ALIGN */ + return TRUE; + case 33: /* R_MN10300_SYM_DIFF */ +- saved_sym = symtab + get_reloc_symindex (reloc->r_info); ++ if (sym_index >= num_syms) ++ error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"), ++ sym_index); ++ else ++ saved_sym = symtab + sym_index; + return TRUE; ++ + case 1: /* R_MN10300_32 */ + case 2: /* R_MN10300_16 */ + if (saved_sym != NULL) + { ++ int reloc_size = reloc_type == 1 ? 4 : 2; + bfd_vma value; + +- value = reloc->r_addend +- + (symtab[get_reloc_symindex (reloc->r_info)].st_value +- - saved_sym->st_value); ++ if (sym_index >= num_syms) ++ error (_("MN10300 reloc contains invalid symbol index %lu\n"), ++ sym_index); ++ else ++ { ++ value = reloc->r_addend + (symtab[sym_index].st_value ++ - saved_sym->st_value); + +- byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2); ++ if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size)) ++ byte_put (start + reloc->r_offset, value, reloc_size); ++ else ++ error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"), ++ (long) reloc->r_offset); ++ } + + saved_sym = NULL; + return TRUE; +@@ -11687,12 +11764,24 @@ target_specific_reloc_handling (Elf_Inte + static bfd_vma saved_sym2 = 0; + static bfd_vma value; + ++ if (reloc == NULL) ++ { ++ saved_sym1 = saved_sym2 = 0; ++ return TRUE; ++ } ++ + switch (reloc_type) + { + case 0x80: /* R_RL78_SYM. */ + saved_sym1 = saved_sym2; +- saved_sym2 = symtab[get_reloc_symindex (reloc->r_info)].st_value; +- saved_sym2 += reloc->r_addend; ++ if (sym_index >= num_syms) ++ error (_("RL78_SYM reloc contains invalid symbol index %lu\n"), ++ sym_index); ++ else ++ { ++ saved_sym2 = symtab[sym_index].st_value; ++ saved_sym2 += reloc->r_addend; ++ } + return TRUE; + + case 0x83: /* R_RL78_OPsub. */ +@@ -11702,12 +11791,20 @@ target_specific_reloc_handling (Elf_Inte + break; + + case 0x41: /* R_RL78_ABS32. */ +- byte_put (start + reloc->r_offset, value, 4); ++ if (IN_RANGE (start, end, start + reloc->r_offset, 4)) ++ byte_put (start + reloc->r_offset, value, 4); ++ else ++ error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"), ++ (long) reloc->r_offset); + value = 0; + return TRUE; + + case 0x43: /* R_RL78_ABS16. */ +- byte_put (start + reloc->r_offset, value, 2); ++ if (IN_RANGE (start, end, start + reloc->r_offset, 2)) ++ byte_put (start + reloc->r_offset, value, 2); ++ else ++ error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"), ++ (long) reloc->r_offset); + value = 0; + return TRUE; + +@@ -12324,7 +12421,7 @@ apply_relocations (void * + + reloc_type = get_reloc_type (rp->r_info); + +- if (target_specific_reloc_handling (rp, start, symtab)) ++ if (target_specific_reloc_handling (rp, start, end, symtab, num_syms)) + continue; + else if (is_none_reloc (reloc_type)) + continue; +@@ -12420,6 +12517,9 @@ apply_relocations (void * + } + + free (symtab); ++ /* Let the target specific reloc processing code know that ++ we have finished with these relocs. */ ++ target_specific_reloc_handling (NULL, NULL, NULL, NULL, 0); + + if (relocs_return) + { +@@ -12548,7 +12648,8 @@ dump_section_as_strings (Elf_Internal_Sh + { + Elf_Internal_Chdr chdr; + unsigned int compression_header_size +- = get_compression_header (& chdr, (unsigned char *) start); ++ = get_compression_header (& chdr, (unsigned char *) start, ++ num_bytes); + + if (chdr.ch_type != ELFCOMPRESS_ZLIB) + { +@@ -12583,10 +12684,20 @@ dump_section_as_strings (Elf_Internal_Sh + new_size -= 12; + } + +- if (uncompressed_size +- && uncompress_section_contents (& start, +- uncompressed_size, & new_size)) +- num_bytes = new_size; ++ if (uncompressed_size) ++ { ++ if (uncompress_section_contents (& start, ++ uncompressed_size, & new_size)) ++ num_bytes = new_size; ++ else ++ { ++ error (_("Unable to decompress section %s\n"), ++ printable_section_name (section)); ++ return; ++ } ++ } ++ else ++ start = real_start; + } + + /* If the section being dumped has relocations against it the user might +@@ -12682,7 +12793,7 @@ dump_section_as_bytes (Elf_Internal_Shdr + { + Elf_Internal_Chdr chdr; + unsigned int compression_header_size +- = get_compression_header (& chdr, start); ++ = get_compression_header (& chdr, start, section_size); + + if (chdr.ch_type != ELFCOMPRESS_ZLIB) + { +@@ -12717,10 +12828,23 @@ dump_section_as_bytes (Elf_Internal_Shdr + new_size -= 12; + } + +- if (uncompressed_size +- && uncompress_section_contents (& start, uncompressed_size, +- & new_size)) +- section_size = new_size; ++ if (uncompressed_size) ++ { ++ if (uncompress_section_contents (& start, uncompressed_size, ++ & new_size)) ++ { ++ section_size = new_size; ++ } ++ else ++ { ++ error (_("Unable to decompress section %s\n"), ++ printable_section_name (section)); ++ /* FIXME: Print the section anyway ? */ ++ return; ++ } ++ } ++ else ++ start = real_start; + } + + if (relocate) +@@ -12835,7 +12959,7 @@ load_specific_debug_section (enum dwarf_ + return 0; + } + +- compression_header_size = get_compression_header (&chdr, start); ++ compression_header_size = get_compression_header (&chdr, start, size); + + if (chdr.ch_type != ELFCOMPRESS_ZLIB) + { +@@ -12870,15 +12994,24 @@ load_specific_debug_section (enum dwarf_ + size -= 12; + } + +- if (uncompressed_size +- && uncompress_section_contents (&start, uncompressed_size, +- &size)) +- { +- /* Free the compressed buffer, update the section buffer +- and the section size if uncompress is successful. */ +- free (section->start); +- section->start = start; ++ if (uncompressed_size) ++ { ++ if (uncompress_section_contents (&start, uncompressed_size, ++ &size)) ++ { ++ /* Free the compressed buffer, update the section buffer ++ and the section size if uncompress is successful. */ ++ free (section->start); ++ section->start = start; ++ } ++ else ++ { ++ error (_("Unable to decompress section %s\n"), ++ printable_section_name (sec)); ++ return 0; ++ } + } ++ + section->size = size; + } + +@@ -13077,9 +13210,12 @@ process_section_contents (FILE * file) + + /* Check to see if the user requested a + dump of a section that does not exist. */ +- while (i++ < num_dump_sects) +- if (dump_sects[i]) +- warn (_("Section %d was not dumped because it does not exist!\n"), i); ++ while (i < num_dump_sects) ++ { ++ if (dump_sects[i]) ++ warn (_("Section %d was not dumped because it does not exist!\n"), i); ++ i++; ++ } + } + + static void +Index: binutils-2.28/binutils/nm.c +=================================================================== +--- binutils-2.28.orig/binutils/nm.c 2017-03-02 09:23:53.000000000 +0100 ++++ binutils-2.28/binutils/nm.c 2017-03-17 16:24:11.000000000 +0100 +@@ -685,7 +685,8 @@ size_forward1 (const void *P_x, const vo + + #define file_symbol(s, sn, snl) \ + (((s)->flags & BSF_FILE) != 0 \ +- || ((sn)[(snl) - 2] == '.' \ ++ || ((snl) > 2 \ ++ && (sn)[(snl) - 2] == '.' \ + && ((sn)[(snl) - 1] == 'o' \ + || (sn)[(snl) - 1] == 'a'))) + +Index: binutils-2.28/bfd/dwarf2.c +=================================================================== +--- binutils-2.28.orig/bfd/dwarf2.c 2017-03-02 09:23:53.000000000 +0100 ++++ binutils-2.28/bfd/dwarf2.c 2017-03-17 16:24:11.000000000 +0100 +@@ -4288,6 +4288,10 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd + { + bfd_byte * new_ptr; + ++ /* PR 21151 */ ++ if (stash->info_ptr + length > stash->info_ptr_end) ++ return FALSE; ++ + each = parse_comp_unit (stash, length, info_ptr_unit, + offset_size); + if (!each) +Index: binutils-2.28/binutils/stabs.c +=================================================================== +--- binutils-2.28.orig/binutils/stabs.c 2017-03-02 09:23:53.000000000 +0100 ++++ binutils-2.28/binutils/stabs.c 2017-03-17 16:24:11.000000000 +0100 +@@ -232,6 +232,10 @@ parse_number (const char **pp, bfd_boole + + orig = *pp; + ++ /* Stop early if we are passed an empty string. */ ++ if (*orig == 0) ++ return (bfd_vma) 0; ++ + errno = 0; + ul = strtoul (*pp, (char **) pp, 0); + if (ul + 1 != 0 || errno == 0) +@@ -1975,9 +1979,17 @@ parse_stab_enum_type (void *dhandle, con + bfd_signed_vma val; + + p = *pp; +- while (*p != ':') ++ while (*p != ':' && *p != 0) + ++p; + ++ if (*p == 0) ++ { ++ bad_stab (orig); ++ free (names); ++ free (values); ++ return DEBUG_TYPE_NULL; ++ } ++ + name = savestring (*pp, p - *pp); + + *pp = p + 1; +Index: binutils-2.28/binutils/rddbg.c +=================================================================== +--- binutils-2.28.orig/binutils/rddbg.c 2017-03-02 09:23:53.000000000 +0100 ++++ binutils-2.28/binutils/rddbg.c 2017-03-17 16:24:11.000000000 +0100 +@@ -299,7 +299,10 @@ read_symbol_stabs_debugging_info (bfd *a + *pfound = TRUE; + + s = i.name; ++ if (s == NULL || strlen (s) < 1) ++ return FALSE; + f = NULL; ++ + while (s[strlen (s) - 1] == '\\' + && ps + 1 < symend) + { +Index: binutils-2.28/binutils/dwarf.c +=================================================================== +--- binutils-2.28.orig/binutils/dwarf.c 2017-03-02 09:23:53.000000000 +0100 ++++ binutils-2.28/binutils/dwarf.c 2017-03-17 16:24:11.000000000 +0100 +@@ -76,7 +76,6 @@ int dwarf_check = 0; + as a zero-terminated list of section indexes comprising one set of debug + sections from a .dwo file. */ + +-static int cu_tu_indexes_read = 0; + static unsigned int *shndx_pool = NULL; + static unsigned int shndx_pool_size = 0; + static unsigned int shndx_pool_used = 0; +@@ -99,7 +98,7 @@ static int tu_count = 0; + static struct cu_tu_set *cu_sets = NULL; + static struct cu_tu_set *tu_sets = NULL; + +-static void load_cu_tu_indexes (void *file); ++static bfd_boolean load_cu_tu_indexes (void *); + + /* Values for do_debug_lines. */ + #define FLAG_DEBUG_LINES_RAW 1 +@@ -2715,7 +2714,7 @@ load_debug_info (void * file) + return num_debug_info_entries; + + /* If this is a DWARF package file, load the CU and TU indexes. */ +- load_cu_tu_indexes (file); ++ (void) load_cu_tu_indexes (file); + + if (load_debug_section (info, file) + && process_debug_info (&debug_displays [info].section, file, abbrev, 1, 0)) +@@ -7378,21 +7377,27 @@ process_cu_tu_index (struct dwarf_sectio + section sets that we can use to associate a .debug_info.dwo section + with its associated .debug_abbrev.dwo section in a .dwp file. */ + +-static void ++static bfd_boolean + load_cu_tu_indexes (void *file) + { ++ static int cu_tu_indexes_read = -1; /* Tri-state variable. */ ++ + /* If we have already loaded (or tried to load) the CU and TU indexes + then do not bother to repeat the task. */ +- if (cu_tu_indexes_read) +- return; +- +- if (load_debug_section (dwp_cu_index, file)) +- process_cu_tu_index (&debug_displays [dwp_cu_index].section, 0); ++ if (cu_tu_indexes_read == -1) ++ { ++ cu_tu_indexes_read = TRUE; ++ ++ if (load_debug_section (dwp_cu_index, file)) ++ if (! process_cu_tu_index (&debug_displays [dwp_cu_index].section, 0)) ++ cu_tu_indexes_read = FALSE; + +- if (load_debug_section (dwp_tu_index, file)) +- process_cu_tu_index (&debug_displays [dwp_tu_index].section, 0); ++ if (load_debug_section (dwp_tu_index, file)) ++ if (! process_cu_tu_index (&debug_displays [dwp_tu_index].section, 0)) ++ cu_tu_indexes_read = FALSE; ++ } + +- cu_tu_indexes_read = 1; ++ return (bfd_boolean) cu_tu_indexes_read; + } + + /* Find the set of sections that includes section SHNDX. */ +@@ -7402,7 +7407,8 @@ find_cu_tu_set (void *file, unsigned int + { + unsigned int i; + +- load_cu_tu_indexes (file); ++ if (! load_cu_tu_indexes (file)) ++ return NULL; + + /* Find SHNDX in the shndx pool. */ + for (i = 0; i < shndx_pool_used; i++) +Index: binutils-2.28/bfd/compress.c +=================================================================== +--- binutils-2.28.orig/bfd/compress.c 2017-03-02 09:23:53.000000000 +0100 ++++ binutils-2.28/bfd/compress.c 2017-03-17 16:24:11.000000000 +0100 +@@ -300,7 +300,7 @@ bfd_get_full_section_contents (bfd *abfd + SHF_COMPRESSED section. */ + compression_header_size = 12; + if (!decompress_contents (compressed_buffer + compression_header_size, +- sec->compressed_size, p, sz)) ++ sec->compressed_size - compression_header_size, p, sz)) + { + bfd_set_error (bfd_error_bad_value); + if (p != *ptr)