Fix for several CVEs found when feeding fuzzed binary files into various
binutils programs like strings, objdump or readelf.

This fixes: bnc #902676, #902677, #903655, #905735, #905736.
This is also: CVE-2014-8485, CVE-2014-8484, CVE-2014-8501, CVE-2014-8502,
CVE-2014-8503, CVE-2014-8504, CVE-2014-8738, CVE-2014-8737 .
And is also upstream bugs, PR17510, PR17512, PR17521, PR17531, PR17533,
PR17552, PR17597, PR17605.

This is essentially generated by backporting the following GIT commits,
ignoring any changes in binutils/dwarf.c binutils/dwarf.h, binutils/readelf.c:

493a33860c71cac998f1a56d6d87d6faa801fbaa 17510
7e1e19887abd24aeb15066b141cdff5541e0ec8e 17512 # not applicable to 2.23 (has hardcoded 16 already)
bf67003b4567600ed3022a439207ac8f26454f91 17512
708d7d0d11f0f2d776171979aa3479e8e12a38a0 17510
5a4b0ccc20ba30caef53b01bee2c0aaa5b855339 17512
e5b470e24ce448a56230137a37d3b17299593041 17512
7e760b06b212f01b3819d5b37e8f5b613e0db34c 17512
0102ea8cec5fc509bba6c91df61b7ce23a799d32 17512
f54498b45795194df671207c6ef3d6cd6d0c0ebb 17512
690725fa0d98ae52c991f4b3ea58b6b47b4fbc80 17512
99b4a5a08507a96f6d014553c9ac4c5e257f37a2 ??? but range test for msp430, not applicable to 2.23
5a3f568b70bdfb91aacdfb66657b56d8c6d242f1 17512
049b0c3a2467c785f9068915d81fdba4985470bf 17531
bb0d867169d7e9743d229804106a8fbcab7f3b3f 17533
e0a31db1b16fe0a010aa46185e4a31a08e7fd97f 17531
79f2a78e76fae1885163027f843e1bafde984b4c 17512
20ad5e2842911039a60b6bdf9880cee895179e43 17512
74e1a04b9787c02ba0fa9b93e3dae691bb44ed96 17531
a6f921c87700c2349cf6fa35fbc8ec9d3e3fb88e 17512
834107255bbefceb445fa733ebc1ea5d9f41ec7f fix some previous stuff
dd9b91de2149ee81d47f708e7b0bbf57da10ad42 17552, 17533 (ar pathnames)
405724050266e30fcc8cbcee416cde41862e8e8f revert problematic size checks
071436c6e94be13904438b6eb70ee79c73354a61 17531
36e9d67b868c85232ab630514260f0d9c9c6b27b 17521
5e186ece2feebb46e63ff6bb2d2490aad0d5a724 17552 (remove temp files)
4082ef846466438ea2cd5b3606f304f6fded152b 17531
fcfa62408aec326a54765a6fd8895349fb41eb7c 17512
0ac2337434968896a6393fdd8c0624bd2945bbea 17512
201159ecec7e17600df4153e5d4e7a145f0c7cfe 17512
6bb3e67958b0ee59f1b69619761e6d5ad1f7544b 17512
541a3cbda9de8ae8888906cfe14887c394a3f772 17531
8b73c35699b4b1da558be29ac3c90aee0e0e1e49 17531
f41e4712a7b7ac60f181e7dfc984ca35c222f0d7 17512
3102e897eeda28961a32826095befef5c4a74097 17531
a5c71af8d3c7c535f27614947f72883233658706 17512
f8521a03584f2451e52cbc90bff5c1050a588c0f 17512
57494d81b631343380888b8a6ca55bf8a6110436 17512
041830e03cca866f12be18198898139e558ad31e 17512
470c009be81f3ac0205d4efb1d16fc4216093b69 17597
0eff716535f3e8f501d6b438f7f796b70a0b9f98 17531
6937bb54a9c3ddc7ba330bc18af76f8dbe856ac3 17512
0593bd3ace3cb64775f4d9e8039da919c26803cd 17605 (invalid time data in archive)
5d921cbd81554867007e903b634acc6bc8281f9f 17531
0a9d414aa114b7b7e609cbcbc285f79031bbe608 17512
bd25671c6f202c4a5108883caa2adb24ff6f361f 17510 (though not explicitely mentioned)

The changes to dwarf.c and readelf.c come in via verbatim copying
the current master versions of them (from the binutils-new-readelf.tar.gz
tarball, together with updated testsuite expect files) into the source
tree, with necessary related changes in ELF headers
from binutils-readelf-header.diff.

It follows the list of all commit messages of these commits (still
showing the readelf.c/dwarf.c parts), and after that the combined diff
as backported.

commit 493a33860c71cac998f1a56d6d87d6faa801fbaa
Author: Nick Clifton <nickc@redhat.com>
Date:   Mon Oct 27 12:43:16 2014 +0000

    This patch closes a potential security hole in applications that use
    the bfd library to parse binaries containing maliciously corrupt section
    group headers.
    
    	PR binutils/17510
    	* elf.c (setup_group): Improve handling of corrupt group
    	sections.

commit 7e1e19887abd24aeb15066b141cdff5541e0ec8e
Author: Nick Clifton <nickc@redhat.com>
Date:   Mon Oct 27 14:45:06 2014 +0000

    Fix a seg-fault in strings and other binutuils when parsing a corrupt PE
    executable with an invalid value in the NumberOfRvaAndSizes field of the
    AOUT header.
    
    	PR binutils/17512
    	* peXXigen.c (_bfd_XXi_swap_aouthdr_in): Handle corrupt binaries
    	with an invalid value for NumberOfRvaAndSizes.

commit bf67003b4567600ed3022a439207ac8f26454f91
Author: Nick Clifton <nickc@redhat.com>
Date:   Mon Oct 27 18:05:37 2014 +0000

    This fixes more seg-faults in tools like "strings" and "objdump" when
    presented with corrupt binaries.
    
    	PR binutils/17512
    	* elf.c (bfd_section_from_shdr): Detect and warn about ELF
    	binaries with a group of sections linked by the string table
    	indicies.
    	* peXXigen.c (pe_print_edata): Detect out of range rvas and
    	entry counts for the Export Address table, Name Pointer table
    	 and Ordinal table.

commit 708d7d0d11f0f2d776171979aa3479e8e12a38a0
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Oct 28 10:48:14 2014 +0000

    This patch fixes a flaw in the SREC parser which could cause a stack overflow
    and potential secuiryt breach.
    
    	PR binutils/17510
    	* srec.c (srec_bad_byte): Increase size of buf to allow for
    	negative values.
    	(srec_scan): Use an unsigned char buffer to hold header bytes.

commit 5a4b0ccc20ba30caef53b01bee2c0aaa5b855339
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Oct 28 15:42:56 2014 +0000

    More fixes for corrupt binaries crashing the binutils.
    
    	PR binutils/17512
    	* elf.c (bfd_section_from_shdr): Allocate and free the recursion
    	detection table on a per-bfd basis.
    	* peXXigen.c (pe_print_edata): Handle binaries with a truncated
    	export table.

commit e5b470e24ce448a56230137a37d3b17299593041
Author: Nick Clifton <nickc@redhat.com>
Date:   Wed Oct 29 20:58:13 2014 +0000

    Fixes another memory corruption bug introduced by patches for PR 17512.
    
    	* elf.c (bfd_section_from_shdr): Fix heap use after free memory
    	leak.

commit 7e760b06b212f01b3819d5b37e8f5b613e0db34c
Author: Nick Clifton <nickc@redhat.com>
Date:   Thu Oct 30 15:52:10 2014 +0000

    Closes another memory corruption, this time due to heap overrun.
    
    	PR binutils/17512
    	* coffgen.c (coff_get_normalized_symtab): Prevent buffer overrun.

commit 0102ea8cec5fc509bba6c91df61b7ce23a799d32
Author: Nick Clifton <nickc@redhat.com>
Date:   Thu Oct 30 17:16:17 2014 +0000

    Fixes a seg-fault in the ihex parser when it encounters a malformed ihex file.
    
    	PR binutils/17512
    	* ihex.c (ihex_scan): Fix typo in invocation of ihex_bad_byte.

part of commit f54498b45795194df671207c6ef3d6cd6d0c0ebb
Author: Nick Clifton <nickc@redhat.com>
Date:   Fri Oct 31 16:36:31 2014 +0000

    Avoid allocating over-large buffers when parsing corrupt binaries.
    
    	PR binutils/17512
    	* coffgen.c (_bfd_coff_get_external_symbols): Do not try to load a
    	symbol table bigger than the file.
    	* elf.c (bfd_elf_get_str_section): Do not try to load a string
    	table bigger than the file.
    
commit 690725fa0d98ae52c991f4b3ea58b6b47b4fbc80
Author: Nick Clifton <nickc@redhat.com>
Date:   Fri Oct 31 18:00:55 2014 +0000

    Fix an (almost) infinite loop in the tekhex parser.
    
    	PR binutils/17512
    	* tekhex.c (first_phase): Check that the section range is sane.

commit 99b4a5a08507a96f6d014553c9ac4c5e257f37a2
Author: Nick Clifton <nickc@redhat.com>
Date:   Mon Nov 3 11:15:53 2014 +0000

    Fixes a snafu checking the size of 20-bit immedaite values.
    
    	* config/tc-msp430.c (msp430_srcoperand): Fix range test for
    	20-bit values.

commit 5a3f568b70bdfb91aacdfb66657b56d8c6d242f1
Author: Nick Clifton <nickc@redhat.com>
Date:   Mon Nov 3 17:44:00 2014 +0000

    More fixes for buffer overruns instigated by corrupt binaries.
    
    	PR binutils/17512
    	* objdump.c (slurp_symtab): Fail gracefully if the table could not
    	be read.
    	(dump_relocs_in_section): Likewise.
    
    	* aoutx.h (slurp_symbol_table): Check that computed table size is
    	not bigger than the file from which is it being read.
    	(slurp_reloc_table): Likewise.
    	* coffcode.h (coff_slurp_line_table): Remove unneeded local
    	'warned'.  Do not try to print the details of a symbol with an
    	* coffgen.c (make_a_sectiobn_from_file): Check computed string
    	(bfd_coff_internal_syment_name): Check read in string offset
    	against length of string table.
    	(build_debug_section): Return a pointer to the section used.
    	(_bfd_coff_read_string_table): Store the length of the string
    	table in the coff_tdata structure.
    	(bfd_coff_free_symbols): Set the length of the string table to
    	zero when it is freed.
    	(coff_get_normalized_symtab): Check offsets against string table
    	or data table lengths as appropriate.
    	* cofflink.c (_bfd_coff_link_input_bfd): Check offset against
    	length of string table.
    	* compress.c (bfd_get_full_section_contents): Check computed size
    	against the size of the file.
    	* libcoff-in.h (obj_coff_strings_len): Define.
    	(struct coff_tdata): Add strings_len field.
    	* libcoff.h: Regenerate.
    	* peXXigen.c (pe_print_debugdata): Do not attempt to print the
    	data if the debug section is too small.
    	* xcofflink.c (xcoff_link_input_bfd):  Check offset against
    	length of string table.

commit 049b0c3a2467c785f9068915d81fdba4985470bf
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Nov 4 11:58:16 2014 +0000

    Fixes for crashes running readelf.
    
    	PR binutils/17531
    	* readelf.c (get_data): If the reason parameter is null, do not
    	print any error messages.
    	(get_32bit_section_headers): Verify section header entry size
    	before reading in the section headers.
    	(get_64bit_section_headers): Likewise.
    	(process_section_headers): Pass FALSE to get_section_headers.
    	(get_file_header): Pass TRUE to get_section_headers.
    	(process_dynamic_section): Change an assert to an error message.
    	(process_symbol_table): Handle corrupt histograms.

commit bb0d867169d7e9743d229804106a8fbcab7f3b3f
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Nov 4 13:15:37 2014 +0000

    Fix a seg-fault triggered by reading a mal-formed archive.
    
    	PR binutils/17533
    	* archive.c (_bfd_slurp_extended_name_table): Handle archives with
    	corrupt extended name tables.

commit e0a31db1b16fe0a010aa46185e4a31a08e7fd97f
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Nov 4 15:29:03 2014 +0000

    More fixes for memory corruption when readelf processes corrupt files.
    
    	PR binutils/17531
    	(get_32bit_program_headers): Verify program header entry size
    	before reading in the program headers.
    	(get_64bit_program_headers): Likewise.
    	(get_unwind_section_word): Do nothing if no section was provided.
    	Fail if the offset is outside of the section.
    	(print_dynamic_symbol): Catch out of range symbol indicies.
    	(process_mips_specific): Likewise.
    	(process_attributes): Make sure that there is enough space left in
    	the section before attempting to read the length of the next
    	attribute.

commit 79f2a78e76fae1885163027f843e1bafde984b4c
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Nov 4 16:00:10 2014 +0000

    Fix problem with linker created sections being mistakenly flagged
    as corrupt by the new error checking code in bfd_get_full_section_contents.
    
    	PR binutils/17512
    	* compress.c (bfd_get_full_section_contents): Improve test for
    	linker created objects.

part of commit 20ad5e2842911039a60b6bdf9880cee895179e43
Author: Nick Clifton <nickc@redhat.com>
Date:   Wed Nov 5 10:13:16 2014 +0000

    More fixes for processing corrupt files.
    
    	PR binutils/17512
    	* peXXigen.c (pe_print_idata): Add range checks.
    	(pe_print_edata): Likewise.
    	(rsrc_print_resource_entries): Likewise.  Avoid printing control
    	characters.  Terminate priniting if corruption is detected.
    	(rsrc_print_resource_directory): Terminate printing if an unknown
    	directory type is encountered.
    	(pe_print_debugdata): Fix off-by-one error.
    	(rsrc_count_entries): Add range checking.
    	(rsrc_parse_entry): Likewise.

part of commit 20ad5e2842911039a60b6bdf9880cee895179e43
Author: Nick Clifton <nickc@redhat.com>
Date:   Wed Nov 5 10:13:16 2014 +0000

    More fixes for processing corrupt files.
    
    	PR binutils/17512
    	* coffcode.h (coff_set_alignment_hook): Warn if the file lies
    	about the number of relocations it contains.
    	(coff_sort_func_alent): Return 0 if the pointers are NULL.
    	(coff_slurp_line_table): Add more range checks.  Do not free new
    	tables created when sorting line numbers.

commit 74e1a04b9787c02ba0fa9b93e3dae691bb44ed96
Author: Nick Clifton <nickc@redhat.com>
Date:   Wed Nov 5 16:19:03 2014 +0000

    More fixes for reading corrupt ELF files.
    
    	PR binutils/15731
    	* readelf.c (printable_section_name): New function.
    	(dump_relocations): Use new function.
    	(process_program_headers, get_32bit_elf_symbols,
    	(get_64bit_elf_symbols, process_section_headers,
    	(process_section_groups, process_relocs, ia64_process_unwind,
    	(hppa_process_unwind, get_unwind_section_word, decode_arm_unwind,
    	(arm_process_unwind, process_version_sections,
    	(process_symbol_table, apply_relocations, get_section_contents,
    	(dump_section_as_strings, dump_section_as_bytes,
    	(display_debug_section, process_attributes, process_mips_specific,
    	(process_mips_specific process_gnu_liblist): Likewise.
    	(get_unwind_section_word): Check for a missing symbol table.
    	Replace aborts with error messages.
    	(arm_process_unwind): Check for a missing string table.
    	(process_attributes): Check for an attribute length that is too
    	small.
    	(process_mips_specific): Check for a corrupt GOT symbol offset.

commit a6f921c87700c2349cf6fa35fbc8ec9d3e3fb88e
Author: Nick Clifton <nickc@redhat.com>
Date:   Wed Nov 5 17:57:54 2014 +0000

    More fixes for memory problems uncovered by file fuzzers.
    
    	PR binutils/17512
    	* coffcode.h (handle_COMDAT): Replace abort with BFD_ASSERT.
    	Replace another abort with an error message.
    	(coff_slurp_line_table): Add more range checking.
    	* peXXigen.c (pe_print_debugdata): Add range checking.

commit 834107255bbefceb445fa733ebc1ea5d9f41ec7f
Author: Nick Clifton <nickc@redhat.com>
Date:   Thu Nov 6 14:39:58 2014 +0000

    Revert changes in previous deltas that introduced new failures into
    the linker testsuite.
    
    	* aoutx.h (slurp_symbol_table): Revert previous delta.
    	(slurp_reloc_table): Likewise.
    	* compress.c (bfd_get_full_section_contents): Remove file size
    	test.
    	* coffgen.c (coff_get_normalized_symtab): Allow zero-sized symtabs
    	and do not complain about linker generated files.

commit 405724050266e30fcc8cbcee416cde41862e8e8f
Author: Alan Modra <amodra@gmail.com>
Date:   Fri Nov 7 09:37:39 2014 +1030

    Revert bfd_get_size checks
    
    	* archive.c (_bfd_slurp_extended_name_table): Revert bfd_get_size check.
    	* coffcode.h (coff_set_alignment_hook): Likewise.
    	(coff_slurp_line_table): Likewise.
    	* coffgen.c (coff_get_normalized_symtab): Likewise.
    	(_bfd_coff_get_external_symbols): Likewise.
    	* elf.c (bfd_elf_get_str_section): Likewise.
    	* tekhex.c (first_phase): Likewise.

commit dd9b91de2149ee81d47f708e7b0bbf57da10ad42
Author: Nick Clifton <nickc@redhat.com>
Date:   Thu Nov 6 14:49:10 2014 +0000

    Prevent archive memebers with illegal pathnames from being extracted from an archive.
    
    	PR binutils/17552, binutils/17533
    	* bucomm.c (is_valid_archive_path): New function.  Returns false
    	for absolute pathnames and pathnames that include /../.
    	* bucomm.h (is_valid_archive_path): Add prototype.
    	* ar.c (extract_file): Use new function to check for valid
    	pathnames when extracting files from an archive.
    	* objcopy.c (copy_archive): Likewise.
    	* doc/binutils.texi: Update documentation to mention the
    	limitation on pathname of archive members.

commit 071436c6e94be13904438b6eb70ee79c73354a61
Author: Nick Clifton <nickc@redhat.com>
Date:   Fri Nov 7 13:39:45 2014 +0000

    Add more fixes for inavlid memory accesses triggered by corrupt files.
    
    	PR binutils/17531
    	* readelf.c (get_data): Avoid allocating memory when we know that
    	the read will fail.
    	(find_section_by_type): New function.
    	(get_unwind_section_word): Check for invalid symbol indicies.
    	Check for invalid reloc types.
    	(get_32bit_dynamic_section): Add range checks.
    	(get_64bit_dynamic_section): Add range checks.
    	(process_dynamic_section): Check for a corrupt time value.
    	(process_symbol_table): Add range checks.
    	(dump_section_as_strings): Add string length range checks.
    	(display_tag_value): Likewise.
    	(display_arm_attribute): Likewise.
    	(display_gnu_attribute): Likewise.
    	(display_tic6x_attribute): Likewise.
    	(display_msp430x_attribute): Likewise.
    	(process_mips_specific): Add range check.

commit 36e9d67b868c85232ab630514260f0d9c9c6b27b
Author: Nick Clifton <nickc@redhat.com>
Date:   Mon Nov 10 14:18:45 2014 +0000

    More fixes for problems exposed by valgrind and the address sanitizer
    when displaying the contents of corrupt files.
    
    	PR binutils/17521
    	* coff-i386.c (NUM_HOWTOS): New define.
    	(RTYPE2HOWTO): Use it.
    	(coff_i386_rtype_to_howto): Likewise.
    	(coff_i386_reloc_name_lookup): Likewise.
    	(CALC_ADDEND): Check that reloc r_type field is valid.
    	* coff-x86_64.c (NUM_HOWTOS): New define.
    	(RTYPE2HOWTO): Use it.
    	(coff_amd64_rtype_to_howto): Likewise.
    	(coff_amd64_reloc_name_lookup): Likewise.
    	(CALC_ADDEND): Check that reloc r_type field is valid.
    	* coffcode.h (coff_slurp_line_table): Check for symbol table
    	(coff_slurp_symbol_table): Use zalloc to ensure that all table
    	entries are initialised.
    	* coffgen.c (_bfd_coff_read_string_table): Initialise unused bits
    	in the string table.  Also ensure that the table is 0 terminated.
    	underflow.
    	* opncls.c (bfd_alloc): Catch the case where a small negative size
    	can result in only 1 byte being allocated.
    	(bfd_alloc2): Use bfd_alloc.
    	* pe-mips.c (NUM_HOWTOS): New define.
    	(coff_mips_reloc_name_lookup): Use it.
    	(CALC_ADDEND): Check that reloc r_type field is valid.
    	* peXXigen.c (_bfd_XXi_swap_aouthdr_in): Initialise unused entries
    	in the DataDirectory.
    	(pe_print_idata): Avoid reading beyond the end of the data block
    	wen printing strings.
    	(pe_print_edata): Likewise.
    	* peicode.h (pe_mkobject): Initialise the pe_opthdr field.
    	(pe_bfd_object_p): Allocate and initialize enough space to hold a
    	PEAOUTHDR, even if the opt_hdr field specified less.

commit 5e186ece2feebb46e63ff6bb2d2490aad0d5a724
Author: Nick Clifton <nickc@redhat.com>
Date:   Mon Nov 10 14:28:43 2014 +0000

    Fix objcopy and strip so that they remove their temporary files even if an error occurs.
    
    	PR binutils/17552
    	* (copy_archive): Clean up temporary files even if an error
    	occurs.

commit fcfa62408aec326a54765a6fd8895349fb41eb7c
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Nov 11 21:36:37 2014 +1030

    Avoid coff OOM
    
    bfd_zalloc/bfd_zmalloc to fix uninitialized memory reads is too big a
    hammer, when the size allocated depends on user input.  A typical
    bfd_alloc, bfd_seek, bfd_bread sequence will give an error or warning
    at the point the file read fails when some enormous item as described
    by headers is not actually present in the file.  Nice operating system
    allow memory overcommit.  But not if you write to the memory.  So
    bfd_zalloc can cause an OOM, thrashing, or system hangs.
    
    The patch also fixes a recently introduced endless loop on bad input.
    
    	PR binutils/17512
    	* coffcode.h (coff_slurp_line_table): Don't bfd_zalloc, just
    	memset the particular bits we need.  Update src after hitting loop
    	"continue".  Don't count lineno omitted due to invalid symbols in
    	nbr_func, and update lineno_count.  Init entire terminating
    	lineno.  Don't both allocating terminator in n_lineno_cache.
    	Redirect sym->lineno pointer to where n_lineno_cache will be
    	copied, and free n_lineno_cache.
    	* pe-mips.c (NUM_HOWTOS): Typo fix.

commit 0ac2337434968896a6393fdd8c0624bd2945bbea
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Nov 11 22:42:03 2014 +1030

    coff coff
    
    I missed this use of the loop induction variable outside the loop.
    
    	PR binutils/17512
    	* coffcode.h (coff_slurp_line_table): Use updated lineno_count
    	when building func_table.

commit 4082ef846466438ea2cd5b3606f304f6fded152b
Author: Nick Clifton <nickc@redhat.com>
Date:   Mon Nov 10 16:32:32 2014 +0000

    More fixes for assertion failures and out-of-bounds reads by readelf.
    
    	PR binutils/17531
    	* (ia64_process_unwind): Replace assertion with an error message.
    	Add range checking for group section indicies.
    	(hppa_process_unwind): Replace assertion with an error message.
    	(process_syminfo): Likewise.
    	(decode_arm_unwind_bytecode): Add range checking.
    	(dump_section_as_strings): Add more string range checking.
    	(display_tag_value): Likewise.
    	(display_arm_attribute): Likewise.
    	(display_gnu_attribute): Likewise.
    	(display_tic6x_attribute): Likewise.
    	(display_msp430x_attribute): Likewise.

commit 6bb3e67958b0ee59f1b69619761e6d5ad1f7544b
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Nov 12 14:51:38 2014 +1030

    Throw away dodgy coff line number info earlier
    
    	PR 17521
    	* coffcode.h (coff_slurp_line_table): Drop line number info
    	not preceded by a valid function entry.  Revert last change.

commit 201159ecec7e17600df4153e5d4e7a145f0c7cfe
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Nov 11 15:34:27 2014 +0000

    More fixes for invalid memory accesses, uncovered by valgrind and binary fuzzers.
    
    	PR binutils/17512
    	* coffcode.h (coff_slurp_line_table): Initialise the parts of the
    	line number cache that would not be initialised by the copy from
    	the new line number table.
    	(coff_classify_symbol): Allow for _bfd_coff_internal_syment_name
    	returning NULL.
    	* coffgen.c (coff_get_normalized_symbols): Get the external
    	symbols before allocating space for the internal symbols, in case
    	the get fails.
    	* elf.c (_bfd_elf_slurp_version_tables): Only allocate a verref
    	array if one is needed.  Likewise with the verdef array.
    	* peXXigen.c (_bfd_XXi_swap_sym_in): Replace abort()'s with error
    	messages.
    	(_bfd_XXi_swap_aux_in): Make sure that all fields of the aux
    	structure are initialised.
    	(pe_print_edata): Avoid reading off the end of the data buffer.

commit 541a3cbda9de8ae8888906cfe14887c394a3f772
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Nov 11 16:15:47 2014 +0000

    Prevent a buffer overrun whilst displaying corrupt ARM tags.
    
    	PR binutils/17531
    	* readelf.c (display_arm_attribute): Avoid reading off the end of
    	the buffer when processing a Tag_nodefaults.

commit 8b73c35699b4b1da558be29ac3c90aee0e0e1e49
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Nov 11 20:50:03 2014 +0000

    Fix invalid memory accesses for more corrupt binary files.
    
    	PR binutils/17531
    	* binutils/readelf.c (dynamic_nent): Change type to size_t.
    	(slurp_rela_relocs): Use size_t type for nrelas.
    	(slurp_rel_relocs): Likewise.
    	(get_program_headers): Improve out of memory error message.
    	(get_32bit_section_headers): Likewise.
    	(get_32bit_section_headers): Likewise.
    	(get_64bit_section_headers): Likewise.
    	(get_32bit_elf_symbols): Likewise.
    	(get_64bit_elf_symbols): Likewise.
    	(process_section_groups): Likewise.
    	(get_32bit_dynamic_section): Likewise.
    	(get_64bit_dynamic_section): Likewise.
    	(process_dynamic_section): Likewise.
    	(process_version_sections): Likewise.
    	(process_mips_specific): Likewise.
    	(process_corefile_note_segment): Likewise.
    	(process_version_sections): Use size_t type for total.
    	(get_dynamic_data): Change type of number parameter to size_t.
    	Improve out of memory error messages.
    	(process_symbol_table): Change type of nbuckets and nchains to
    	size_t.  Skip processing of sections headers if there are none.
    	Improve out of memory error messages.

part of commit f41e4712a7b7ac60f181e7dfc984ca35c222f0d7
Author: Nick Clifton <nickc@redhat.com>
Date:   Wed Nov 12 22:39:58 2014 +0000

    Fix more memory faults uncovered by fuzzing various executables.
    
    	PR binutils/17512
    	* dwarf.c (read_and_display_attr_value): Check that we do not read
    	past end.
    	(display_debug_pubnames_worker): Add range checks.
    	(process_debug_info): Check for invalid pointer sizes.
    	(display_loc_list): Likewise.
    	(display_loc_list_dwo): Likewise.
    	(display_debug_ranges): Likewise.
    	(display_debug_aranges): Check for invalid address size.
    	(read_cie): Add range checks.  Replace call strchr with while loop.

part of commit f41e4712a7b7ac60f181e7dfc984ca35c222f0d7
Author: Nick Clifton <nickc@redhat.com>
Date:   Wed Nov 12 22:39:58 2014 +0000

    Fix more memory faults uncovered by fuzzing various executables.
    
    	PR binutils/17512
    	* objdump.c (dump_dwarf): Replace abort with a warning message.
    	(print_section_stabs): Improve range checks.
    	* rdcoff.c (coff_get_slot): Use long for indx parameter type.
    	* rddbg.c (read_section_stabs_debugging_info): Zero terminate the
    	string table.  Avoid walking off the end of the stabs data.
    	* stabs.c (parse_stab_string): Add check for a NULL name.
    
    	PR binutils/17512
    	* coffcode.h (coff_slurp_line_table): Set the line number of
    	corrupt entries to -1.
    	(coff_slurp_symbol_table): Alway initialise the value of the
    	symbol.
    	* coffgen.c (coff_print_symbol): Check that the combined pointer
    	is valid.
    	(coff_print_symbol): Do not print negative line numbers.
    	* peXXigen.c (pe_print_idata): Add range checking displaying
    	member names.

commit 3102e897eeda28961a32826095befef5c4a74097
Author: Nick Clifton <nickc@redhat.com>
Date:   Thu Nov 13 10:45:50 2014 +0000

    More fixes for readelf problems reading corrupt files.
    
    	PR binutils/17531
    	* readelf.c (process_version_sections): If the read of the version
    	def information fails, make sure that the external verdef data is
    	not used.
    	(get_dynamic_data): Do not attempt to allocate memory for more
    	dynamic data than there is in the file.  If the read fails, free
    	the allocated buffer.
    	(process_symbol_table): Do not print dynamic information if we
    	were unable to read the dynamic symbol table.
    	(print_gnu_note): Do not print the note if the descsz is too
    	small.

commit f8521a03584f2451e52cbc90bff5c1050a588c0f
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Nov 13 12:15:46 2014 -0800

    Rename symbbol to symbol
    
    	* coffcode.h (coff_pointerize_aux_hook): Fix a typo.

commit 57494d81b631343380888b8a6ca55bf8a6110436
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Nov 13 12:56:18 2014 -0800

    Add cast to unsigned int
    
    	* coffcode.h (coff_slurp_line_table): Add cast to unsigned int.

commit a5c71af8d3c7c535f27614947f72883233658706
Author: Nick Clifton <nickc@redhat.com>
Date:   Thu Nov 13 17:46:11 2014 +0000

    More fixes for memory access violations whilst scanning corrupt binaries.
    
    	PR binutils/17512
    	* config/obj-coff.c (coff_obj_symbol_new_hook): Set the is_sym
    	field.
    
    	* coffcode.h (coff_ptr_struct): Add is_sym field.
    	(coff_new_section_hook): Set the is_sym field.
    	(coff_pointerize_aux_hook): Check the is_sym field.
    	(coff_print_aux): Likewise.
    	(coff_compute_section_file_positions): Likewise.
    	(coff_write_object_contents): Likewise.
    	(coff_slurp_line_table): Likewise.
    	(coff_slurp_symbol_table): Likewise.
    	(CALC_ADDEND): Likewise.
    	* coffgen.c (coff_renumber_symbols): Likewise.
    	(coff_mangle_symbols): Likewise.
    	(coff_fix_symbol_name): Likewise.
    	(coff_write_symbol): Likewise.
    	(coff_write_alien_symbol): Likewise.
    	(coff_write_native_symbol): Likewise.
    	(coff_write_symbols): Likewise.
    	(coff_write_linenumbers): Likewise.
    	(coff_pointerize_aux): Likewise.
    	(coff_get_normalized_symtab): Likewise.
    	(coff_get_symbol_info): Likewise.
    	(bfd_coff_get_syment): Likewise.
    	(bfd_coff_get_auxent): Likewise.
    	(coff_print_symbol): Likewise.
    	(coff_find_nearest_line_with_names): Likewise.
    	(bfd_coff_set_symbol_class): Likewise.
    	(coff_make_empty_symbol): Set the is_sym field.
    	(coff_bfd_make_debug_symbol): Likewise.
    	* peicode.h (pe_ILF_make_a_symbol): Likewise.
    	* libcoff.h: Regenerate.
    	* libcoff-in.h: Regenerate.

part of commit 041830e03cca866f12be18198898139e558ad31e
Author: Nick Clifton <nickc@redhat.com>
Date:   Fri Nov 14 12:30:00 2014 +0000

    More fixes for invalid memory accesses triggered by corrupt binaries.
    
    	PR binutils/17512
    	* dwarf.c (get_encoded_value): Add an 'end' parameter.  Change the
    	'data' parameter to a double pointer and return the updated value.
    	(decode_location_expression): Update call to get_encoded_value.
    	(frame_need_space): Handle the case where one or both of the
    	mallocs fails.
    	(read_cie): Initialise the cie pointer, even if the read fails.
    	(display_debug_frames): Warn if the calculated block_end is before
    	the start of the block.  Break the loop if the CIE could not be
    	read.  Update call to get_encoded_value.  Warn if the read CFA
    	expressions are too big.
    
part of commit 041830e03cca866f12be18198898139e558ad31e
Author: Nick Clifton <nickc@redhat.com>
Date:   Fri Nov 14 12:30:00 2014 +0000

    More fixes for invalid memory accesses triggered by corrupt binaries.
    
    	PR binutils/17512
    	* ieee.c (ieee_archive_p) Skip processing if no bytes are read at
    	all.
    	(ieee_object_p): Likewise.

commit 470c009be81f3ac0205d4efb1d16fc4216093b69
Author: Nick Clifton <nickc@redhat.com>
Date:   Fri Nov 14 13:39:29 2014 +0000

    Fix a null pointer dereference when reading the debug link info from a corrupt file.
    
    	PR binutils/17597
    	* opncls.c (bfd_get_debug_link_info): Avoid reading off the end of
    	the section.
    	(bfd_get_alt_debug_link_info): Likewise.

commit 0eff716535f3e8f501d6b438f7f796b70a0b9f98
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Nov 18 10:07:11 2014 +0000

    Fix memort access problems exposed by fuzzed binaries.
    
    	PR binutils/17531
    	* readelf.c (get_unwind_section_word): Skip reloc processing if
    	there are no relocs associated with the section.
    	(decode_tic6x_unwind_bytecode): Warn and return if the stack
    	pointer adjustment falls off the end of the buffer.

part of commit 6937bb54a9c3ddc7ba330bc18af76f8dbe856ac3
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Nov 18 14:40:05 2014 +0000

    More fixes for illegal memory accesses exposed by fuzzed binaries.
    
    	PR binutils/17512
    	* dwarf.c (get_encoded_value): Warn and return if the encoded
    	value is more than 64-bits long.
    	(SAFE_BYTE_GET): Do not attempt to read more than 64-bits.
    	(process_extended_line_op): Add more range checks.
    	(decode_location_expression): Use the return value from
    	display_block.  Add more range checks.
    	(read_debug_line_header): Add range check.
    	(display_debug_lines_raw): Add range checks.
    	(display_debug_frames): Silently skip multiple zero terminators.
    	Add range checks.
    	Use SAFE_BYTE_GET instead of byte_get.

part of commit 6937bb54a9c3ddc7ba330bc18af76f8dbe856ac3
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Nov 18 14:40:05 2014 +0000

    More fixes for illegal memory accesses exposed by fuzzed binaries.
    
    	PR binutils/17512
    	* peXXIgen.c (pe_print_pdata): Fail if the section's virtual size
    	is larger than its real size.
    	(rsrc_print_section): Fix off-by-one error checking for overflow.
    	* pei-x86_64.c (pex64_bfd_print_pdata): Handle empty unwind
    	sections.
    
commit 0593bd3ace3cb64775f4d9e8039da919c26803cd
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Nov 18 17:35:39 2014 +0000

    Fixes a seg-fault when displaying the time data for a corrupt archive.
    
    	PR binutuls/17605
    	* bucomm.c (print_arelt_descr): Check for ctime returning NULL.

commit 5d921cbd81554867007e903b634acc6bc8281f9f
Author: Nick Clifton <nickc@redhat.com>
Date:   Fri Nov 21 13:37:39 2014 +0000

    Resolve more problems with readelf uncovered by fuzzing binary files.
    
    	PR binutils/17531
    	* readelf.c (process_version_sections): Prevent an infinite loop
    	processing corrupt version need data.
    	(process_corefile_note_segment): Handle corrupt notes.

part of commit 0a9d414aa114b7b7e609cbcbc285f79031bbe608
Author: Nick Clifton <nickc@redhat.com>
Date:   Fri Nov 21 21:44:04 2014 +0000

    Fixes for memory access violations exposed by fuzzinf various binaries.
    
    	PR binutils/17512
    	* dwarf.c (get_encoded_value): Check for an encoded size of 0.
    	(display_debug_lines_raw): Check for an invalid line range value.
    	(display_debug_frames): Check for corrupt augmentation data.
    
part of commit 0a9d414aa114b7b7e609cbcbc285f79031bbe608
Author: Nick Clifton <nickc@redhat.com>
Date:   Fri Nov 21 21:44:04 2014 +0000

    Fixes for memory access violations exposed by fuzzinf various binaries.
    
    	PR binutils/17512
    	* coffgen.c (coff_get_normalized_symtab): Check for an excessive
    	number of auxillary entries.
    	* ieee.c (next_byte): Convert to a function.  Return FALSE if the
    	next byte is beyond the end of the buffer.
    	(parse_int): Test the return value of next_byte.
    	(parse_expression): Convert to boolean.  Return FALSE if the
    	parsing failed.  Test the return value of next_byte.
    	(ieee_seek): Convert to a function.  Return FALSE if the seek goes
    	beyond the end of the buffer.
    	(ieee_slurp_external_symbols): Test the return value of ieee_seek
    	and next_byte.
    	(ieee_slurp_sections): Convert to boolean.  Return FALSE if the
    	operation failed.  Test the return value of ieee_seek and
    	next_byte.
    	(ieee_archive_p): Test the return value of ieee_seek and
    	next_byte.
    	(do_one): Likewise.
    	(ieee_slurp_section_data): Likewise.
    	(ieee_object_p): Likewise.  Store the size of the buffer in the
    	total_amt field in the header.
    	* libieee.h (common_header_type): Add amt field.
    	* mach-o.c (bfd_mach_o_canonicalize_one_reloc): Check that the
    	reloc's value is within range.
    	(bfd_mach_o_read_symtab_symbols): Nullify the symbols field if the
    	operation fails.
    	* pei-x86_64.c (pex64_xdata_print_uwd_codes): Replace abort with
    	an error message.
    	(pex64_dump_xdata): Check for buffer overflows.
    	* versados.c (process_otr): Check that the section exists before
    	taking its size.
    	(versados_object_p): Make sure that enough data was read for the
    	header to be checked.
    	* vms-alpha.c (vms_get_remaining_object_record): Change
    	read_so_far parameter to an unsigned int.  Check that the amount
    	read is in range.

commit bd25671c6f202c4a5108883caa2adb24ff6f361f
Author: Alan Modra <amodra@gmail.com>
Date:   Fri Aug 29 10:36:29 2014 +0930

    Report an error for S-records with less than the miniumum size
    
        * srec.c (srec_scan): Revert last change.  Report an error for
        S-records with less than the miniumum byte count.

Index: binutils-2.23.1/bfd/elf.c
===================================================================
--- binutils-2.23.1.orig/bfd/elf.c	2012-07-24 23:06:57.000000000 +0200
+++ binutils-2.23.1/bfd/elf.c	2015-01-16 18:20:55.000000000 +0100
@@ -599,9 +599,10 @@ setup_group (bfd *abfd, Elf_Internal_Shd
 		  if (shdr->contents == NULL)
 		    {
 		      _bfd_error_handler
-			(_("%B: Corrupt size field in group section header: 0x%lx"), abfd, shdr->sh_size);
+			(_("%B: corrupt size field in group section header: 0x%lx"), abfd, shdr->sh_size);
 		      bfd_set_error (bfd_error_bad_value);
-		      return FALSE;
+		      -- num_group;
+		      continue;
 		    }
 
 		  memset (shdr->contents, 0, amt);
@@ -609,8 +610,17 @@ setup_group (bfd *abfd, Elf_Internal_Shd
 		  if (bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0
 		      || (bfd_bread (shdr->contents, shdr->sh_size, abfd)
 			  != shdr->sh_size))
-		    return FALSE;
-
+		    {
+		      _bfd_error_handler
+			(_("%B: invalid size field in group section header: 0x%lx"), abfd, shdr->sh_size);
+		      bfd_set_error (bfd_error_bad_value);
+		      -- num_group;
+		      /* PR 17510: If the group contents are even partially
+			 corrupt, do not allow any of the contents to be used.  */
+		      memset (shdr->contents, 0, amt);
+		      continue;
+		    }
+		  
 		  /* Translate raw contents, a flag word followed by an
 		     array of elf section indices all in target byte order,
 		     to the flag word followed by an array of elf section
@@ -642,6 +652,21 @@ setup_group (bfd *abfd, Elf_Internal_Shd
 		    }
 		}
 	    }
+
+	  /* PR 17510: Corrupt binaries might contain invalid groups.  */
+	  if (num_group != (unsigned) elf_tdata (abfd)->num_group)
+	    {
+	      elf_tdata (abfd)->num_group = num_group;
+
+	      /* If all groups are invalid then fail.  */
+	      if (num_group == 0)
+		{
+		  elf_tdata (abfd)->group_sect_ptr = NULL;
+		  elf_tdata (abfd)->num_group = num_group = -1;
+		  (*_bfd_error_handler) (_("%B: no valid group sections found"), abfd);
+		  bfd_set_error (bfd_error_bad_value);
+		}
+	    }
 	}
     }
 
@@ -707,6 +732,7 @@ setup_group (bfd *abfd, Elf_Internal_Shd
     {
       (*_bfd_error_handler) (_("%B: no group info for section %A"),
 			     abfd, newsect);
+      return FALSE;
     }
   return TRUE;
 }
@@ -1559,38 +1585,74 @@ bfd_section_from_shdr (bfd *abfd, unsign
   Elf_Internal_Ehdr *ehdr;
   const struct elf_backend_data *bed;
   const char *name;
+  bfd_boolean ret = TRUE;
+  static bfd_boolean * sections_being_created = NULL;
+  static bfd * sections_being_created_abfd = NULL;
+  static unsigned int nesting = 0;
 
   if (shindex >= elf_numsections (abfd))
     return FALSE;
 
+  if (++ nesting > 3)
+    {
+      /* PR17512: A corrupt ELF binary might contain a recursive group of
+	 sections, each the string indicies pointing to the next in the
+	 loop.  Detect this here, by refusing to load a section that we are
+	 already in the process of loading.  We only trigger this test if
+	 we have nested at least three sections deep as normal ELF binaries
+	 can expect to recurse at least once.
+
+	 FIXME: It would be better if this array was attached to the bfd,
+	 rather than being held in a static pointer.  */
+
+      if (sections_being_created_abfd != abfd)
+	sections_being_created = NULL;
+      if (sections_being_created == NULL)
+	{
+	  /* FIXME: It would be more efficient to attach this array to the bfd somehow.  */
+	  sections_being_created = (bfd_boolean *)
+	    bfd_zalloc (abfd, elf_numsections (abfd) * sizeof (bfd_boolean));
+	  sections_being_created_abfd = abfd;
+	}
+      if (sections_being_created [shindex])
+	{
+	  (*_bfd_error_handler)
+	    (_("%B: warning: loop in section dependencies detected"), abfd);
+	  return FALSE;
+	}
+      sections_being_created [shindex] = TRUE;
+    }
+
   hdr = elf_elfsections (abfd)[shindex];
   ehdr = elf_elfheader (abfd);
   name = bfd_elf_string_from_elf_section (abfd, ehdr->e_shstrndx,
 					  hdr->sh_name);
   if (name == NULL)
-    return FALSE;
+    goto fail;
 
   bed = get_elf_backend_data (abfd);
   switch (hdr->sh_type)
     {
     case SHT_NULL:
       /* Inactive section. Throw it away.  */
-      return TRUE;
+      goto success;
 
-    case SHT_PROGBITS:	/* Normal section with contents.  */
-    case SHT_NOBITS:	/* .bss section.  */
-    case SHT_HASH:	/* .hash section.  */
-    case SHT_NOTE:	/* .note section.  */
+    case SHT_PROGBITS:		/* Normal section with contents.  */
+    case SHT_NOBITS:		/* .bss section.  */
+    case SHT_HASH:		/* .hash section.  */
+    case SHT_NOTE:		/* .note section.  */
     case SHT_INIT_ARRAY:	/* .init_array section.  */
     case SHT_FINI_ARRAY:	/* .fini_array section.  */
     case SHT_PREINIT_ARRAY:	/* .preinit_array section.  */
     case SHT_GNU_LIBLIST:	/* .gnu.liblist section.  */
     case SHT_GNU_HASH:		/* .gnu.hash section.  */
-      return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+      ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+      goto success;
 
     case SHT_DYNAMIC:	/* Dynamic linking information.  */
       if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
-	return FALSE;
+	goto fail;
+
       if (hdr->sh_link > elf_numsections (abfd))
 	{
 	  /* PR 10478: Accept Solaris binaries with a sh_link
@@ -1604,11 +1666,11 @@ bfd_section_from_shdr (bfd *abfd, unsign
 		break;
 	      /* Otherwise fall through.  */
 	    default:
-	      return FALSE;
+	      goto fail;
 	    }
 	}
       else if (elf_elfsections (abfd)[hdr->sh_link] == NULL)
-	return FALSE;
+	goto fail;
       else if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB)
 	{
 	  Elf_Internal_Shdr *dynsymhdr;
@@ -1637,24 +1699,26 @@ bfd_section_from_shdr (bfd *abfd, unsign
 		}
 	    }
 	}
-      break;
+      goto success;
 
-    case SHT_SYMTAB:		/* A symbol table */
+    case SHT_SYMTAB:		/* A symbol table.  */
       if (elf_onesymtab (abfd) == shindex)
-	return TRUE;
+	goto success;
 
       if (hdr->sh_entsize != bed->s->sizeof_sym)
-	return FALSE;
+	goto fail;
+
       if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size)
 	{
 	  if (hdr->sh_size != 0)
-	    return FALSE;
+	    goto fail;
 	  /* Some assemblers erroneously set sh_info to one with a
 	     zero sh_size.  ld sees this as a global symbol count
 	     of (unsigned) -1.  Fix it here.  */
 	  hdr->sh_info = 0;
-	  return TRUE;
+	  goto success;
 	}
+
       BFD_ASSERT (elf_onesymtab (abfd) == 0);
       elf_onesymtab (abfd) = shindex;
       elf_tdata (abfd)->symtab_hdr = *hdr;
@@ -1671,7 +1735,7 @@ bfd_section_from_shdr (bfd *abfd, unsign
 	  && (abfd->flags & DYNAMIC) != 0
 	  && ! _bfd_elf_make_section_from_shdr (abfd, hdr, name,
 						shindex))
-	return FALSE;
+	goto fail;
 
       /* Go looking for SHT_SYMTAB_SHNDX too, since if there is one we
 	 can't read symbols without that section loaded as well.  It
@@ -1697,26 +1761,29 @@ bfd_section_from_shdr (bfd *abfd, unsign
 		  break;
 	      }
 	  if (i != shindex)
-	    return bfd_section_from_shdr (abfd, i);
+	    ret = bfd_section_from_shdr (abfd, i);
 	}
-      return TRUE;
+      goto success;
 
-    case SHT_DYNSYM:		/* A dynamic symbol table */
+    case SHT_DYNSYM:		/* A dynamic symbol table.  */
       if (elf_dynsymtab (abfd) == shindex)
-	return TRUE;
+	goto success;
 
       if (hdr->sh_entsize != bed->s->sizeof_sym)
-	return FALSE;
+	goto fail;
+
       if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size)
 	{
 	  if (hdr->sh_size != 0)
-	    return FALSE;
+	    goto fail;
+
 	  /* Some linkers erroneously set sh_info to one with a
 	     zero sh_size.  ld sees this as a global symbol count
 	     of (unsigned) -1.  Fix it here.  */
 	  hdr->sh_info = 0;
-	  return TRUE;
+	  goto success;
 	}
+
       BFD_ASSERT (elf_dynsymtab (abfd) == 0);
       elf_dynsymtab (abfd) = shindex;
       elf_tdata (abfd)->dynsymtab_hdr = *hdr;
@@ -1725,34 +1792,38 @@ bfd_section_from_shdr (bfd *abfd, unsign
 
       /* Besides being a symbol table, we also treat this as a regular
 	 section, so that objcopy can handle it.  */
-      return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+      ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+      goto success;
 
-    case SHT_SYMTAB_SHNDX:	/* Symbol section indices when >64k sections */
+    case SHT_SYMTAB_SHNDX:	/* Symbol section indices when >64k sections.  */
       if (elf_symtab_shndx (abfd) == shindex)
-	return TRUE;
+	goto success;
 
       BFD_ASSERT (elf_symtab_shndx (abfd) == 0);
       elf_symtab_shndx (abfd) = shindex;
       elf_tdata (abfd)->symtab_shndx_hdr = *hdr;
       elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->symtab_shndx_hdr;
-      return TRUE;
+      goto success;
 
-    case SHT_STRTAB:		/* A string table */
+    case SHT_STRTAB:		/* A string table.  */
       if (hdr->bfd_section != NULL)
-	return TRUE;
+	goto success;
+
       if (ehdr->e_shstrndx == shindex)
 	{
 	  elf_tdata (abfd)->shstrtab_hdr = *hdr;
 	  elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->shstrtab_hdr;
-	  return TRUE;
+	  goto success;
 	}
+
       if (elf_elfsections (abfd)[elf_onesymtab (abfd)]->sh_link == shindex)
 	{
 	symtab_strtab:
 	  elf_tdata (abfd)->strtab_hdr = *hdr;
 	  elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->strtab_hdr;
-	  return TRUE;
+	  goto success;
 	}
+
       if (elf_elfsections (abfd)[elf_dynsymtab (abfd)]->sh_link == shindex)
 	{
 	dynsymtab_strtab:
@@ -1761,8 +1832,9 @@ bfd_section_from_shdr (bfd *abfd, unsign
 	  elf_elfsections (abfd)[shindex] = hdr;
 	  /* We also treat this as a regular section, so that objcopy
 	     can handle it.  */
-	  return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
-						  shindex);
+	  ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name,
+						 shindex);
+	  goto success;
 	}
 
       /* If the string table isn't one of the above, then treat it as a
@@ -1780,9 +1852,9 @@ bfd_section_from_shdr (bfd *abfd, unsign
 		{
 		  /* Prevent endless recursion on broken objects.  */
 		  if (i == shindex)
-		    return FALSE;
+		    goto fail;
 		  if (! bfd_section_from_shdr (abfd, i))
-		    return FALSE;
+		    goto fail;
 		  if (elf_onesymtab (abfd) == i)
 		    goto symtab_strtab;
 		  if (elf_dynsymtab (abfd) == i)
@@ -1790,7 +1862,8 @@ bfd_section_from_shdr (bfd *abfd, unsign
 		}
 	    }
 	}
-      return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+      ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+      goto success;
 
     case SHT_REL:
     case SHT_RELA:
@@ -1805,7 +1878,7 @@ bfd_section_from_shdr (bfd *abfd, unsign
 	if (hdr->sh_entsize
 	    != (bfd_size_type) (hdr->sh_type == SHT_REL
 				? bed->s->sizeof_rel : bed->s->sizeof_rela))
-	  return FALSE;
+	  goto fail;
 
 	/* Check for a bogus link to avoid crashing.  */
 	if (hdr->sh_link >= num_sec)
@@ -1813,8 +1886,9 @@ bfd_section_from_shdr (bfd *abfd, unsign
 	    ((*_bfd_error_handler)
 	     (_("%B: invalid link %lu for reloc section %s (index %u)"),
 	      abfd, hdr->sh_link, name, shindex));
-	    return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
-						    shindex);
+	    ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name,
+						   shindex);
+	    goto success;
 	  }
 
 	/* For some incomprehensible reason Oracle distributes
@@ -1855,7 +1929,7 @@ bfd_section_from_shdr (bfd *abfd, unsign
 	if ((elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_SYMTAB
 	     || elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_DYNSYM)
 	    && ! bfd_section_from_shdr (abfd, hdr->sh_link))
-	  return FALSE;
+	  goto fail;
 
 	/* If this reloc section does not use the main symbol table we
 	   don't treat it as a reloc section.  BFD can't adequately
@@ -1870,14 +1944,18 @@ bfd_section_from_shdr (bfd *abfd, unsign
 	    || hdr->sh_info >= num_sec
 	    || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL
 	    || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA)
-	  return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
-						  shindex);
+	  {
+	    ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name,
+						   shindex);
+	    goto success;
+	  }
 
 	if (! bfd_section_from_shdr (abfd, hdr->sh_info))
-	  return FALSE;
+	  goto fail;
+
 	target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info);
 	if (target_sect == NULL)
-	  return FALSE;
+	  goto fail;
 
 	esdt = elf_section_data (target_sect);
 	if (hdr->sh_type == SHT_RELA)
@@ -1889,7 +1967,7 @@ bfd_section_from_shdr (bfd *abfd, unsign
 	amt = sizeof (*hdr2);
 	hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
 	if (hdr2 == NULL)
-	  return FALSE;
+	  goto fail;
 	*hdr2 = *hdr;
 	*p_hdr = hdr2;
 	elf_elfsections (abfd)[shindex] = hdr2;
@@ -1905,34 +1983,40 @@ bfd_section_from_shdr (bfd *abfd, unsign
 	      target_sect->use_rela_p = 1;
 	  }
 	abfd->flags |= HAS_RELOC;
-	return TRUE;
+	goto success;
       }
 
     case SHT_GNU_verdef:
       elf_dynverdef (abfd) = shindex;
       elf_tdata (abfd)->dynverdef_hdr = *hdr;
-      return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+      ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+      goto success;
 
     case SHT_GNU_versym:
       if (hdr->sh_entsize != sizeof (Elf_External_Versym))
-	return FALSE;
+	goto fail;
+
       elf_dynversym (abfd) = shindex;
       elf_tdata (abfd)->dynversym_hdr = *hdr;
-      return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+      ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+      goto success;
 
     case SHT_GNU_verneed:
       elf_dynverref (abfd) = shindex;
       elf_tdata (abfd)->dynverref_hdr = *hdr;
-      return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+      ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+      goto success;
 
     case SHT_SHLIB:
-      return TRUE;
+      goto success;
 
     case SHT_GROUP:
       if (! IS_VALID_GROUP_SECTION_HEADER (hdr))
-	return FALSE;
+	goto fail;
+
       if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
-	return FALSE;
+	goto fail;
+
       if (hdr->contents != NULL)
 	{
 	  Elf_Internal_Group *idx = (Elf_Internal_Group *) hdr->contents;
@@ -1958,7 +2042,7 @@ bfd_section_from_shdr (bfd *abfd, unsign
 		}
 	    }
 	}
-      break;
+      goto success;
 
     default:
       /* Possibly an attributes section.  */
@@ -1966,14 +2050,14 @@ bfd_section_from_shdr (bfd *abfd, unsign
 	  || hdr->sh_type == bed->obj_attrs_section_type)
 	{
 	  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
-	    return FALSE;
+	    goto fail;
 	  _bfd_elf_parse_attributes (abfd, hdr);
-	  return TRUE;
+	  goto success;
 	}
 
       /* Check for any processor-specific section types.  */
       if (bed->elf_backend_section_from_shdr (abfd, hdr, name, shindex))
-	return TRUE;
+	goto success;
 
       if (hdr->sh_type >= SHT_LOUSER && hdr->sh_type <= SHT_HIUSER)
 	{
@@ -1985,9 +2069,12 @@ bfd_section_from_shdr (bfd *abfd, unsign
 		 "specific section `%s' [0x%8x]"),
 	       abfd, name, hdr->sh_type);
 	  else
-	    /* Allow sections reserved for applications.  */
-	    return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
-						    shindex);
+	    {
+	      /* Allow sections reserved for applications.  */
+	      ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name,
+						     shindex);
+	      goto success;
+	    }
 	}
       else if (hdr->sh_type >= SHT_LOPROC
 	       && hdr->sh_type <= SHT_HIPROC)
@@ -2008,8 +2095,11 @@ bfd_section_from_shdr (bfd *abfd, unsign
 		 "`%s' [0x%8x]"),
 	       abfd, name, hdr->sh_type);
 	  else
-	    /* Otherwise it should be processed.  */
-	    return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+	    {
+	      /* Otherwise it should be processed.  */
+	      ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+	      goto success;
+	    }
 	}
       else
 	/* FIXME: We should handle this section.  */
@@ -2017,10 +2107,20 @@ bfd_section_from_shdr (bfd *abfd, unsign
 	  (_("%B: don't know how to handle section `%s' [0x%8x]"),
 	   abfd, name, hdr->sh_type);
 
-      return FALSE;
+      goto fail;
     }
 
-  return TRUE;
+ fail:
+  ret = FALSE;
+ success:
+  if (sections_being_created && sections_being_created_abfd == abfd)
+    sections_being_created [shindex] = FALSE;
+  if (-- nesting == 0)
+    {
+      sections_being_created = NULL;
+      sections_being_created_abfd = abfd;
+    }
+  return ret;
 }
 
 /* Return the local symbol specified by ABFD, R_SYMNDX.  */
@@ -7088,8 +7188,12 @@ _bfd_elf_slurp_version_tables (bfd *abfd
 
       hdr = &elf_tdata (abfd)->dynverref_hdr;
 
-      elf_tdata (abfd)->verref = (Elf_Internal_Verneed *)
+      if (hdr->sh_info)
+	elf_tdata (abfd)->verref = (Elf_Internal_Verneed *)
           bfd_zalloc2 (abfd, hdr->sh_info, sizeof (Elf_Internal_Verneed));
+      else
+	elf_tdata (abfd)->verref = NULL;
+	
       if (elf_tdata (abfd)->verref == NULL)
 	goto error_return;
 
@@ -7249,8 +7353,12 @@ error_return_verref:
 	  else
 	    freeidx = ++maxidx;
 	}
-      elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *)
+      if (maxidx)
+	elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *)
           bfd_zalloc2 (abfd, maxidx, sizeof (Elf_Internal_Verdef));
+      else
+	elf_tdata (abfd)->verdef = NULL;
+
       if (elf_tdata (abfd)->verdef == NULL)
 	goto error_return;
 
@@ -7391,16 +7499,12 @@ asymbol *
 _bfd_elf_make_empty_symbol (bfd *abfd)
 {
   elf_symbol_type *newsym;
-  bfd_size_type amt = sizeof (elf_symbol_type);
 
-  newsym = (elf_symbol_type *) bfd_zalloc (abfd, amt);
+  newsym = (elf_symbol_type *) bfd_zalloc (abfd, sizeof * newsym);
   if (!newsym)
     return NULL;
-  else
-    {
-      newsym->symbol.the_bfd = abfd;
-      return &newsym->symbol;
-    }
+  newsym->symbol.the_bfd = abfd;
+  return &newsym->symbol;
 }
 
 void
Index: binutils-2.23.1/bfd/peXXigen.c
===================================================================
--- binutils-2.23.1.orig/bfd/peXXigen.c	2011-04-09 18:06:00.000000000 +0200
+++ binutils-2.23.1/bfd/peXXigen.c	2015-01-16 18:20:55.000000000 +0100
@@ -142,8 +142,13 @@ _bfd_XXi_swap_sym_in (bfd * abfd, void *
 
 	  name = _bfd_coff_internal_syment_name (abfd, in, namebuf);
 	  if (name == NULL)
-	    /* FIXME: Return error.  */
-	    abort ();
+	    {
+	      _bfd_error_handler (_("%B: unable to find name for empty section"),
+				  abfd);
+	      bfd_set_error (bfd_error_invalid_target);
+	      return;
+	    }
+
 	  sec = bfd_get_section_by_name (abfd, name);
 	  if (sec != NULL)
 	    in->n_scnum = sec->target_index;
@@ -163,15 +168,22 @@ _bfd_XXi_swap_sym_in (bfd * abfd, void *
 	    {
 	      name = (const char *) bfd_alloc (abfd, strlen (namebuf) + 1);
 	      if (name == NULL)
-		/* FIXME: Return error.  */
-		abort ();
+		{
+		  _bfd_error_handler (_("%B: out of memory creating name for empty section"),
+				      abfd);
+		  return;
+		}
 	      strcpy ((char *) name, namebuf);
 	    }
+
 	  flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
 	  sec = bfd_make_section_anyway_with_flags (abfd, name, flags);
 	  if (sec == NULL)
-	    /* FIXME: Return error.  */
-	    abort ();
+	    {
+	      _bfd_error_handler (_("%B: unable to create fake empty section"),
+				  abfd);
+	      return;
+	    }
 
 	  sec->vma = 0;
 	  sec->lma = 0;
@@ -240,6 +252,9 @@ _bfd_XXi_swap_aux_in (bfd *	abfd,
   AUXENT *ext = (AUXENT *) ext1;
   union internal_auxent *in = (union internal_auxent *) in1;
 
+  /* PR 17521: Make sure that all fields in the aux structure
+     are initialised.  */
+  memset (in, 0, sizeof * in);
   switch (in_class)
     {
     case C_FILE:
@@ -415,6 +430,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
   aouthdr_int->entry = GET_AOUTHDR_ENTRY (abfd, aouthdr_ext->entry);
   aouthdr_int->text_start =
     GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start);
+
 #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
   /* PE32+ does not have data_start member!  */
   aouthdr_int->data_start =
@@ -475,6 +491,13 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
 	else
 	  a->DataDirectory[idx].VirtualAddress = 0;
       }
+
+    while (idx < IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
+      {
+	a->DataDirectory[idx].Size = 0;
+	a->DataDirectory[idx].VirtualAddress = 0;
+	idx ++;
+      }
   }
 
   if (aouthdr_int->entry)
@@ -721,7 +744,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, v
   {
     int idx;
 
-    for (idx = 0; idx < 16; idx++)
+    for (idx = 0; idx < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; idx++)
       {
 	H_PUT_32 (abfd, extra->DataDirectory[idx].VirtualAddress,
 		  aouthdr_out->DataDirectory[idx][0]);
@@ -1215,7 +1238,9 @@ pe_print_idata (bfd * abfd, void * vfile
         break;
 
       dll = (char *) data + dll_name - adj;
-      fprintf (file, _("\n\tDLL Name: %s\n"), dll);
+      /* PR 17512 file: 078-12277-0.004.  */
+      bfd_size_type maxlen = (char *)(data + datasize) - dll - 1;
+      fprintf (file, _("\n\tDLL Name: %.*s\n"), (int) maxlen, dll);
 
       if (hint_addr != 0)
 	{
@@ -1280,23 +1305,30 @@ pe_print_idata (bfd * abfd, void * vfile
 #ifdef COFF_WITH_pex64
 	  for (j = 0; idx + j + 8 <= datasize; j += 8)
 	    {
+	      bfd_size_type amt;
 	      unsigned long member = bfd_get_32 (abfd, data + idx + j);
 	      unsigned long member_high = bfd_get_32 (abfd, data + idx + j + 4);
 
 	      if (!member && !member_high)
 		break;
 
+	      amt = member - adj;
+
 	      if (member_high & 0x80000000)
 		fprintf (file, "\t%lx%08lx\t %4lx%08lx  <none>",
 			 member_high,member, member_high & 0x7fffffff, member);
+ 	      /* PR binutils/17512: Handle corrupt PE data.  */
+	      else if (amt + 2 >= datasize)
+ 		fprintf (file, _("\t<corrupt: 0x%04lx>"), member);
 	      else
 		{
 		  int ordinal;
 		  char *member_name;
 
-		  ordinal = bfd_get_16 (abfd, data + member - adj);
-		  member_name = (char *) data + member - adj + 2;
-		  fprintf (file, "\t%04lx\t %4d  %s",member, ordinal, member_name);
+		  ordinal = bfd_get_16 (abfd, data + amt);
+		  member_name = (char *) data + amt + 2;
+		  fprintf (file, "\t%04lx\t %4d  %.*s",member, ordinal,
+			   (int) (datasize - (amt + 2)), member_name);
 		}
 
 	      /* If the time stamp is not zero, the import address
@@ -1312,24 +1344,30 @@ pe_print_idata (bfd * abfd, void * vfile
 #else
 	  for (j = 0; idx + j + 4 <= datasize; j += 4)
 	    {
+	      bfd_size_type amt;
 	      unsigned long member = bfd_get_32 (abfd, data + idx + j);
 
 	      /* Print single IMAGE_IMPORT_BY_NAME vector.  */
 	      if (member == 0)
 		break;
 
+	      amt = member - adj;
 	      if (member & 0x80000000)
 		fprintf (file, "\t%04lx\t %4lu  <none>",
 			 member, member & 0x7fffffff);
+ 	      /* PR binutils/17512: Handle corrupt PE data.  */
+	      else if (amt + 2 >= datasize)
+ 		fprintf (file, _("\t<corrupt: 0x%04lx>"), member);
 	      else
 		{
 		  int ordinal;
 		  char *member_name;
 
-		  ordinal = bfd_get_16 (abfd, data + member - adj);
-		  member_name = (char *) data + member - adj + 2;
-		  fprintf (file, "\t%04lx\t %4d  %s",
-			   member, ordinal, member_name);
+		  ordinal = bfd_get_16 (abfd, data + amt);
+		  member_name = (char *) data + amt + 2;
+		  fprintf (file, "\t%04lx\t %4d  %.*s",
+			   member, ordinal,
+			   (int) (datasize - (amt + 2)), member_name);
 		}
 
 	      /* If the time stamp is not zero, the import address
@@ -1365,7 +1403,7 @@ pe_print_edata (bfd * abfd, void * vfile
   bfd_size_type datasize = 0;
   bfd_size_type dataoff;
   bfd_size_type i;
-  bfd_signed_vma adj;
+  bfd_vma adj;
   struct EDT_type
   {
     long export_flags;          /* Reserved - should be zero.  */
@@ -1427,6 +1465,15 @@ pe_print_edata (bfd * abfd, void * vfile
 	}
     }
 
+  /* PR 17512: Handle corrupt PE binaries.  */
+  if (datasize < 36)
+    {
+      fprintf (file,
+	       _("\nThere is an export table in %s, but it is too small (%d)\n"),
+	       section->name, (int) datasize);
+      return TRUE;
+    }
+
   fprintf (file, _("\nThere is an export table in %s at 0x%lx\n"),
 	   section->name, (unsigned long) addr);
 
@@ -1470,8 +1517,13 @@ pe_print_edata (bfd * abfd, void * vfile
   fprintf (file,
 	   _("Name \t\t\t\t"));
   bfd_fprintf_vma (abfd, file, edt.name);
-  fprintf (file,
-	   " %s\n", data + edt.name - adj);
+
+  if ((edt.name >= adj) && (edt.name < adj + datasize))
+    fprintf (file, " %.*s\n",
+	     (int) (datasize - (edt.name - adj)),
+	     data + edt.name - adj);
+  else
+    fprintf (file, "(outside .edata section)\n");
 
   fprintf (file,
 	   _("Ordinal Base \t\t\t%ld\n"), edt.base);
@@ -1517,7 +1569,14 @@ pe_print_edata (bfd * abfd, void * vfile
 	  _("\nExport Address Table -- Ordinal Base %ld\n"),
 	  edt.base);
 
-  for (i = 0; i < edt.num_functions; ++i)
+  /* PR 17512: Handle corrupt PE binaries.  */
+  if (edt.eat_addr + (edt.num_functions * 4) - adj >= datasize
+      /* PR 17512 file: 140-165018-0.004.  */
+      || data + edt.eat_addr - adj < data)
+    fprintf (file, _("\tInvalid Export Address Table rva (0x%lx) or entry count (0x%lx)\n"),
+	     (long) edt.eat_addr,
+	     (long) edt.num_functions);
+  else for (i = 0; i < edt.num_functions; ++i)
     {
       bfd_vma eat_member = bfd_get_32 (abfd,
 				       data + edt.eat_addr + (i * 4) - adj);
@@ -1529,11 +1588,12 @@ pe_print_edata (bfd * abfd, void * vfile
 	  /* This rva is to a name (forwarding function) in our section.  */
 	  /* Should locate a function descriptor.  */
 	  fprintf (file,
-		   "\t[%4ld] +base[%4ld] %04lx %s -- %s\n",
+		   "\t[%4ld] +base[%4ld] %04lx %s -- %.*s\n",
 		   (long) i,
 		   (long) (i + edt.base),
 		   (unsigned long) eat_member,
 		   _("Forwarder RVA"),
+		   (int)(datasize - (eat_member - adj)),
 		   data + eat_member - adj);
 	}
       else
@@ -1553,7 +1613,19 @@ pe_print_edata (bfd * abfd, void * vfile
   fprintf (file,
 	   _("\n[Ordinal/Name Pointer] Table\n"));
 
-  for (i = 0; i < edt.num_names; ++i)
+  /* PR 17512: Handle corrupt PE binaries.  */
+  if (edt.npt_addr + (edt.num_names * 4) - adj >= datasize
+      || (data + edt.npt_addr - adj) < data)
+    fprintf (file, _("\tInvalid Name Pointer Table rva (0x%lx) or entry count (0x%lx)\n"),
+	     (long) edt.npt_addr,
+	     (long) edt.num_names);
+  /* PR 17512: file: 140-147171-0.004.  */
+  else if (edt.ot_addr + (edt.num_names * 2) - adj >= datasize
+	   || data + edt.ot_addr - adj < data)
+    fprintf (file, _("\tInvalid Ordinal Table rva (0x%lx) or entry count (0x%lx)\n"),
+	     (long) edt.ot_addr,
+	     (long) edt.num_names);
+  else for (i = 0; i < edt.num_names; ++i)
     {
       bfd_vma name_ptr = bfd_get_32 (abfd,
 				    data +
@@ -1566,8 +1638,8 @@ pe_print_edata (bfd * abfd, void * vfile
 				    data +
 				    edt.ot_addr
 				    + (i*2) - adj);
-      fprintf (file,
-	      "\t[%4ld] %s\n", (long) ord, name);
+      fprintf (file, "\t[%4ld] %.*s\n", (long) ord,
+	       (int)((char *)(data + datasize) - name), name);
     }
 
   free (data);
@@ -1808,6 +1880,14 @@ _bfd_XX_print_ce_compressed_pdata (bfd *
   if (datasize == 0)
     return TRUE;
 
+  /* PR 17512: file: 002-193900-0.004.  */
+  if (datasize < stop)
+    {
+      fprintf (file, _("Virtual size of .pdata section (%ld) larger than real size (%ld)\n"),
+	       (long) stop, (long) datasize);
+      return FALSE;
+    }
+
   if (! bfd_malloc_and_get_section (abfd, section, &data))
     {
       if (data != NULL)
Index: binutils-2.23.1/bfd/srec.c
===================================================================
--- binutils-2.23.1.orig/bfd/srec.c	2011-07-11 17:03:07.000000000 +0200
+++ binutils-2.23.1/bfd/srec.c	2015-01-16 18:30:50.000000000 +0100
@@ -248,7 +248,7 @@ srec_bad_byte (bfd *abfd,
     }
   else
     {
-      char buf[10];
+      char buf[40];
 
       if (! ISPRINT (c))
 	sprintf (buf, "\\%03o", (unsigned int) c);
@@ -454,8 +454,8 @@ srec_scan (bfd *abfd)
 	case 'S':
 	  {
 	    file_ptr pos;
-	    char hdr[3];
-	    unsigned int bytes;
+	    unsigned char hdr[3];
+	    unsigned int bytes, min_bytes;
 	    bfd_vma address;
 	    bfd_byte *data;
 	    unsigned char check_sum;
@@ -478,6 +478,19 @@ srec_scan (bfd *abfd)
 	      }
 
 	    check_sum = bytes = HEX (hdr + 1);
+	    min_bytes = 3;
+	    if (hdr[0] == '2' || hdr[0] == '8')
+	      min_bytes = 4;
+	    else if (hdr[0] == '3' || hdr[0] == '7')
+	      min_bytes = 5;
+	    if (bytes < min_bytes)
+	      {
+		(*_bfd_error_handler) (_("%B:%d: byte count %d too small\n"),
+				       abfd, lineno, bytes);
+		bfd_set_error (bfd_error_bad_value);
+		goto error_return;
+	      }
+
 	    if (bytes * 2 > bufsize)
 	      {
 		if (buf != NULL)
Index: binutils-2.23.1/bfd/coffgen.c
===================================================================
--- binutils-2.23.1.orig/bfd/coffgen.c	2012-07-24 23:06:57.000000000 +0200
+++ binutils-2.23.1/bfd/coffgen.c	2015-01-16 18:20:55.000000000 +0100
@@ -86,9 +86,8 @@ make_a_section_from_file (bfd *abfd,
 	  strings = _bfd_coff_read_string_table (abfd);
 	  if (strings == NULL)
 	    return FALSE;
-	  /* FIXME: For extra safety, we should make sure that
-             strindex does not run us past the end, but right now we
-             don't know the length of the string table.  */
+	  if ((bfd_size_type)(strindex + 2) >= obj_coff_strings_len (abfd))
+	    return FALSE;
 	  strings += strindex;
 	  name = (char *) bfd_alloc (abfd,
                                      (bfd_size_type) strlen (strings) + 1);
@@ -392,6 +391,8 @@ _bfd_coff_internal_syment_name (bfd *abf
 	  if (strings == NULL)
 	    return NULL;
 	}
+      if (sym->_n._n_n._n_offset >= obj_coff_strings_len (abfd))
+	return NULL;
       return strings + sym->_n._n_n._n_offset;
     }
 }
@@ -688,12 +689,14 @@ coff_renumber_symbols (bfd *bfd_ptr, int
   for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
     {
       coff_symbol_type *coff_symbol_ptr = coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]);
+
       symbol_ptr_ptr[symbol_index]->udata.i = symbol_index;
       if (coff_symbol_ptr && coff_symbol_ptr->native)
 	{
 	  combined_entry_type *s = coff_symbol_ptr->native;
 	  int i;
 
+	  BFD_ASSERT (s->is_sym);
 	  if (s->u.syment.n_sclass == C_FILE)
 	    {
 	      if (last_file != NULL)
@@ -738,6 +741,7 @@ coff_mangle_symbols (bfd *bfd_ptr)
 	  int i;
 	  combined_entry_type *s = coff_symbol_ptr->native;
 
+	  BFD_ASSERT (s->is_sym);
 	  if (s->fix_value)
 	    {
 	      /* FIXME: We should use a union here.  */
@@ -761,6 +765,8 @@ coff_mangle_symbols (bfd *bfd_ptr)
 	  for (i = 0; i < s->u.syment.n_numaux; i++)
 	    {
 	      combined_entry_type *a = s + i + 1;
+
+	      BFD_ASSERT (! a->is_sym);
 	      if (a->fix_tag)
 		{
 		  a->u.auxent.x_sym.x_tagndx.l =
@@ -804,6 +810,7 @@ coff_fix_symbol_name (bfd *abfd,
     }
   name_length = strlen (name);
 
+  BFD_ASSERT (native->is_sym);
   if (native->u.syment.n_sclass == C_FILE
       && native->u.syment.n_numaux > 0)
     {
@@ -819,6 +826,7 @@ coff_fix_symbol_name (bfd *abfd,
       else
   	strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN);
 
+      BFD_ASSERT (! (native + 1)->is_sym);
       auxent = &(native + 1)->u.auxent;
 
       filnmlen = bfd_coff_filnmlen (abfd);
@@ -921,6 +929,8 @@ coff_write_symbol (bfd *abfd,
   void * buf;
   bfd_size_type symesz;
 
+  BFD_ASSERT (native->is_sym);
+
   if (native->u.syment.n_sclass == C_FILE)
     symbol->flags |= BSF_DEBUGGING;
 
@@ -961,6 +971,7 @@ coff_write_symbol (bfd *abfd,
 	return FALSE;
       for (j = 0; j < native->u.syment.n_numaux; j++)
 	{
+	  BFD_ASSERT (! (native + j + 1)->is_sym);
 	  bfd_coff_swap_aux_out (abfd,
 				 &((native + j + 1)->u.auxent),
 				 type, n_sclass, (int) j,
@@ -1006,10 +1017,12 @@ coff_write_alien_symbol (bfd *abfd,
     {
       symbol->name = "";
       if (isym != NULL)
-        memset (isym, 0, sizeof(*isym));
+        memset (isym, 0, sizeof (*isym));
       return TRUE;
     }
   native = dummy;
+  native->is_sym = TRUE;
+  native[1].is_sym = FALSE;
   native->u.syment.n_type = T_NULL;
   native->u.syment.n_flags = 0;
   native->u.syment.n_numaux = 0;
@@ -1036,7 +1049,7 @@ coff_write_alien_symbol (bfd *abfd,
          name to keep it from being put in the string table.  */
       symbol->name = "";
       if (isym != NULL)
-        memset (isym, 0, sizeof(*isym));
+        memset (isym, 0, sizeof (*isym));
       return TRUE;
     }
   else
@@ -1095,6 +1108,7 @@ coff_write_native_symbol (bfd *abfd,
       return TRUE;
     }
 
+  BFD_ASSERT (native->is_sym);
   /* If this symbol has an associated line number, we must store the
      symbol index in the line number field.  We also tag the auxent to
      point to the right place in the lineno table.  */
@@ -1204,8 +1218,9 @@ coff_write_symbols (bfd *abfd)
 		 symbol which has no associated section and we do not have to
 		 worry about this, all we need to know is that it is local.  */
 	      current_error_handler = bfd_set_error_handler (null_error_handler);
+	      BFD_ASSERT (c_symbol->native->is_sym);
 	      sym_class = bfd_coff_classify_symbol (abfd,
-                                                   &c_symbol->native->u.syment);
+						    &c_symbol->native->u.syment);
 	      (void) bfd_set_error_handler (current_error_handler);
 
 	      n_sclass = &c_symbol->native->u.syment.n_sclass;
@@ -1296,6 +1311,9 @@ coff_write_symbols (bfd *abfd)
 	       file name, nor does it go in the .debug section.  */
 	    maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN;
 
+	  else if (! c_symbol->native->is_sym)
+	    maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN;
+	    
 	  else if (bfd_coff_symname_in_debug (abfd,
 					      &c_symbol->native->u.syment))
 	    /* This symbol name is in the XCOFF .debug section.
@@ -1386,6 +1404,7 @@ coff_write_linenumbers (bfd *abfd)
 		    {
 		      /* Found a linenumber entry, output.  */
 		      struct internal_lineno out;
+
 		      memset ((void *) & out, 0, sizeof (out));
 		      out.l_lnno = 0;
 		      out.l_addr.l_symndx = l->u.offset;
@@ -1433,6 +1452,7 @@ coff_pointerize_aux (bfd *abfd,
   unsigned int type = symbol->u.syment.n_type;
   unsigned int n_sclass = symbol->u.syment.n_sclass;
 
+  BFD_ASSERT (symbol->is_sym);
   if (coff_backend_info (abfd)->_bfd_coff_pointerize_aux_hook)
     {
       if ((*coff_backend_info (abfd)->_bfd_coff_pointerize_aux_hook)
@@ -1446,6 +1466,7 @@ coff_pointerize_aux (bfd *abfd,
   if (n_sclass == C_FILE)
     return;
 
+  BFD_ASSERT (! auxent->is_sym);
   /* Otherwise patch up.  */
 #define N_TMASK coff_data  (abfd)->local_n_tmask
 #define N_BTSHFT coff_data (abfd)->local_n_btshft
@@ -1473,7 +1494,7 @@ coff_pointerize_aux (bfd *abfd,
    we didn't want to go to the trouble until someone needed it.  */
 
 static char *
-build_debug_section (bfd *abfd)
+build_debug_section (bfd *abfd, asection ** sect_return)
 {
   char *debug_section;
   file_ptr position;
@@ -1501,6 +1522,8 @@ build_debug_section (bfd *abfd)
       || bfd_bread (debug_section, sec_size, abfd) != sec_size
       || bfd_seek (abfd, position, SEEK_SET) != 0)
     return NULL;
+
+  * sect_return = sect;
   return debug_section;
 }
 
@@ -1563,7 +1586,9 @@ _bfd_coff_get_external_symbols (bfd *abf
 
 /* Read in the external strings.  The strings are not loaded until
    they are needed.  This is because we have no simple way of
-   detecting a missing string table in an archive.  */
+   detecting a missing string table in an archive.  If the strings
+   are loaded then the STRINGS and STRINGS_LEN fields in the
+   coff_tdata structure will be set.  */
 
 const char *
 _bfd_coff_read_string_table (bfd *abfd)
@@ -1613,7 +1638,13 @@ _bfd_coff_read_string_table (bfd *abfd)
       return NULL;
     }
 
-  strings = (char *) bfd_malloc (strsize);
+  strings = (char *) bfd_malloc (strsize + 1);
+  /* PR 17521 file: 079-54929-0.004.
+     A corrupt file could contain an index that points into the first
+     STRING_SIZE_SIZE bytes of the string table, so make sure that
+     they are zero.  */
+  memset (strings, 0, STRING_SIZE_SIZE);
+
   if (strings == NULL)
     return NULL;
 
@@ -1625,7 +1656,9 @@ _bfd_coff_read_string_table (bfd *abfd)
     }
 
   obj_coff_strings (abfd) = strings;
-
+  obj_coff_strings_len (abfd) = strsize;
+  /* Terminate the string table, just in case.  */
+  strings[strsize] = 0;
   return strings;
 }
 
@@ -1645,6 +1678,7 @@ _bfd_coff_free_symbols (bfd *abfd)
     {
       free (obj_coff_strings (abfd));
       obj_coff_strings (abfd) = NULL;
+      obj_coff_strings_len (abfd) = 0;
     }
   return TRUE;
 }
@@ -1665,21 +1699,22 @@ coff_get_normalized_symtab (bfd *abfd)
   char *raw_src;
   char *raw_end;
   const char *string_table = NULL;
-  char *debug_section = NULL;
+  asection * debug_sec = NULL;
+  char *debug_sec_data = NULL;
   bfd_size_type size;
 
   if (obj_raw_syments (abfd) != NULL)
     return obj_raw_syments (abfd);
 
+  if (! _bfd_coff_get_external_symbols (abfd))
+    return NULL;
+
   size = obj_raw_syment_count (abfd) * sizeof (combined_entry_type);
   internal = (combined_entry_type *) bfd_zalloc (abfd, size);
   if (internal == NULL && size != 0)
     return NULL;
   internal_end = internal + obj_raw_syment_count (abfd);
-
-  if (! _bfd_coff_get_external_symbols (abfd))
-    return NULL;
-
+  
   raw_src = (char *) obj_coff_external_syms (abfd);
 
   /* Mark the end of the symbols.  */
@@ -1694,23 +1729,44 @@ coff_get_normalized_symtab (bfd *abfd)
        raw_src < raw_end;
        raw_src += symesz, internal_ptr++)
     {
-
       unsigned int i;
+
       bfd_coff_swap_sym_in (abfd, (void *) raw_src,
 			    (void *) & internal_ptr->u.syment);
       symbol_ptr = internal_ptr;
+      internal_ptr->is_sym = TRUE;
+
+      /* PR 17512: file: 1353-1166-0.004.  */
+      if (symbol_ptr->u.syment.n_sclass == C_FILE
+	  && symbol_ptr->u.syment.n_numaux > 0
+	  && raw_src + symesz + symbol_ptr->u.syment.n_numaux
+	  * sizeof (union internal_auxent) >= raw_end)
+	{
+	  bfd_release (abfd, internal);
+	  return NULL;
+	}
 
       for (i = 0;
 	   i < symbol_ptr->u.syment.n_numaux;
 	   i++)
 	{
 	  internal_ptr++;
+	  /* PR 17512: Prevent buffer overrun.  */
+	  if (internal_ptr >= internal_end)
+	    {
+	      bfd_release (abfd, internal);
+	      return NULL;
+	    }
+
 	  raw_src += symesz;
+
 	  bfd_coff_swap_aux_in (abfd, (void *) raw_src,
 				symbol_ptr->u.syment.n_type,
 				symbol_ptr->u.syment.n_sclass,
 				(int) i, symbol_ptr->u.syment.n_numaux,
 				&(internal_ptr->u.auxent));
+
+	  internal_ptr->is_sym = FALSE;
 	  coff_pointerize_aux (abfd, internal, symbol_ptr, i,
 			       internal_ptr);
 	}
@@ -1724,12 +1780,18 @@ coff_get_normalized_symtab (bfd *abfd)
   for (internal_ptr = internal; internal_ptr < internal_end;
        internal_ptr++)
     {
+      BFD_ASSERT (internal_ptr->is_sym);
+
       if (internal_ptr->u.syment.n_sclass == C_FILE
 	  && internal_ptr->u.syment.n_numaux > 0)
 	{
+	  combined_entry_type * aux = internal_ptr + 1;
+
 	  /* Make a file symbol point to the name in the auxent, since
 	     the text ".file" is redundant.  */
-	  if ((internal_ptr + 1)->u.auxent.x_file.x_n.x_zeroes == 0)
+	  BFD_ASSERT (! aux->is_sym);
+
+	  if (aux->u.auxent.x_file.x_n.x_zeroes == 0)
 	    {
 	      /* The filename is a long one, point into the string table.  */
 	      if (string_table == NULL)
@@ -1739,10 +1801,12 @@ coff_get_normalized_symtab (bfd *abfd)
 		    return NULL;
 		}
 
-	      internal_ptr->u.syment._n._n_n._n_offset =
-		((bfd_hostptr_t)
-		 (string_table
-		  + (internal_ptr + 1)->u.auxent.x_file.x_n.x_offset));
+	      if ((bfd_size_type)(aux->u.auxent.x_file.x_n.x_offset)
+		  >= obj_coff_strings_len (abfd))
+		internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) _("<corrupt>");
+	      else
+		internal_ptr->u.syment._n._n_n._n_offset =
+		  (bfd_hostptr_t) (string_table + (aux->u.auxent.x_file.x_n.x_offset));
 	    }
 	  else
 	    {
@@ -1752,15 +1816,15 @@ coff_get_normalized_symtab (bfd *abfd)
 	      if (internal_ptr->u.syment.n_numaux > 1
 		  && coff_data (abfd)->pe)
 		internal_ptr->u.syment._n._n_n._n_offset =
-		  ((bfd_hostptr_t)
-		   copy_name (abfd,
-			      (internal_ptr + 1)->u.auxent.x_file.x_fname,
-			      internal_ptr->u.syment.n_numaux * symesz));
+		  (bfd_hostptr_t)
+		  copy_name (abfd,
+			     aux->u.auxent.x_file.x_fname,
+			     internal_ptr->u.syment.n_numaux * symesz);
 	      else
 		internal_ptr->u.syment._n._n_n._n_offset =
 		  ((bfd_hostptr_t)
 		   copy_name (abfd,
-			      (internal_ptr + 1)->u.auxent.x_file.x_fname,
+			      aux->u.auxent.x_file.x_fname,
 			      (size_t) bfd_coff_filnmlen (abfd)));
 	    }
 	}
@@ -1797,18 +1861,33 @@ coff_get_normalized_symtab (bfd *abfd)
 		  if (string_table == NULL)
 		    return NULL;
 		}
-	      internal_ptr->u.syment._n._n_n._n_offset =
-		((bfd_hostptr_t)
-		 (string_table
-		  + internal_ptr->u.syment._n._n_n._n_offset));
+	      if (internal_ptr->u.syment._n._n_n._n_offset >= obj_coff_strings_len (abfd)
+		  || string_table + internal_ptr->u.syment._n._n_n._n_offset < string_table)
+		internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) _("<corrupt>");
+	      else
+		internal_ptr->u.syment._n._n_n._n_offset =
+		  ((bfd_hostptr_t)
+		   (string_table
+		    + internal_ptr->u.syment._n._n_n._n_offset));
 	    }
 	  else
 	    {
 	      /* Long name in debug section.  Very similar.  */
-	      if (debug_section == NULL)
-		debug_section = build_debug_section (abfd);
-	      internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t)
-		(debug_section + internal_ptr->u.syment._n._n_n._n_offset);
+	      if (debug_sec_data == NULL)
+		debug_sec_data = build_debug_section (abfd, & debug_sec);
+	      if (debug_sec_data != NULL)
+		{
+		  BFD_ASSERT (debug_sec != NULL);
+		  /* PR binutils/17512: Catch out of range offsets into the debug data.  */
+		  if (internal_ptr->u.syment._n._n_n._n_offset > debug_sec->size
+		      || debug_sec_data + internal_ptr->u.syment._n._n_n._n_offset < debug_sec_data)
+		    internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) _("<corrupt>");
+		  else
+		    internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t)
+		      (debug_sec_data + internal_ptr->u.syment._n._n_n._n_offset);
+		}
+	      else
+		internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) "";
 	    }
 	}
       internal_ptr += internal_ptr->u.syment.n_numaux;
@@ -1841,7 +1920,7 @@ coff_make_empty_symbol (bfd *abfd)
   if (new_symbol == NULL)
     return NULL;
   new_symbol->symbol.section = 0;
-  new_symbol->native = 0;
+  new_symbol->native = NULL;
   new_symbol->lineno = NULL;
   new_symbol->done_lineno = FALSE;
   new_symbol->symbol.the_bfd = abfd;
@@ -1867,6 +1946,7 @@ coff_bfd_make_debug_symbol (bfd *abfd,
   new_symbol->native = (combined_entry_type *) bfd_zalloc (abfd, amt);
   if (!new_symbol->native)
     return NULL;
+  new_symbol->native->is_sym = TRUE;
   new_symbol->symbol.section = bfd_abs_section_ptr;
   new_symbol->symbol.flags = BSF_DEBUGGING;
   new_symbol->lineno = NULL;
@@ -1882,7 +1962,8 @@ coff_get_symbol_info (bfd *abfd, asymbol
   bfd_symbol_info (symbol, ret);
 
   if (coffsymbol (symbol)->native != NULL
-      && coffsymbol (symbol)->native->fix_value)
+      && coffsymbol (symbol)->native->fix_value
+      && coffsymbol (symbol)->native->is_sym)
     ret->value = coffsymbol (symbol)->native->u.syment.n_value -
       (bfd_hostptr_t) obj_raw_syments (abfd);
 }
@@ -1897,7 +1978,8 @@ bfd_coff_get_syment (bfd *abfd,
   coff_symbol_type *csym;
 
   csym = coff_symbol_from (abfd, symbol);
-  if (csym == NULL || csym->native == NULL)
+  if (csym == NULL || csym->native == NULL
+      || ! csym->native->is_sym)
     {
       bfd_set_error (bfd_error_invalid_operation);
       return FALSE;
@@ -1929,6 +2011,7 @@ bfd_coff_get_auxent (bfd *abfd,
 
   if (csym == NULL
       || csym->native == NULL
+      || ! csym->native->is_sym
       || indx >= csym->native->u.syment.n_numaux)
     {
       bfd_set_error (bfd_error_invalid_operation);
@@ -1937,6 +2020,7 @@ bfd_coff_get_auxent (bfd *abfd,
 
   ent = csym->native + indx + 1;
 
+  BFD_ASSERT (! ent->is_sym);
   *pauxent = ent->u.auxent;
 
   if (ent->fix_tag)
@@ -1990,6 +2074,15 @@ coff_print_symbol (bfd *abfd,
 
 	  fprintf (file, "[%3ld]", (long) (combined - root));
 
+	  /* PR 17512: file: 079-33786-0.001:0.1.  */
+	  if (combined < obj_raw_syments (abfd)
+	      || combined >= obj_raw_syments (abfd) + obj_raw_syment_count (abfd))
+	    {
+	      fprintf (file, _("<corrupt info> %s"), symbol->name);
+	      break;
+	    }
+
+	  BFD_ASSERT (combined->is_sym);
 	  if (! combined->fix_value)
 	    val = (bfd_vma) combined->u.syment.n_value;
 	  else
@@ -2009,6 +2102,7 @@ coff_print_symbol (bfd *abfd,
 	      combined_entry_type *auxp = combined + aux + 1;
 	      long tagndx;
 
+	      BFD_ASSERT (! auxp->is_sym);
 	      if (auxp->fix_tag)
 		tagndx = auxp->u.auxent.x_sym.x_tagndx.p - root;
 	      else
@@ -2083,8 +2177,11 @@ coff_print_symbol (bfd *abfd,
 	      l++;
 	      while (l->line_number)
 		{
-		  fprintf (file, "\n%4d : ", l->line_number);
-		  bfd_fprintf_vma (abfd, file, l->u.offset + symbol->section->vma);
+		  if (l->line_number > 0)
+		    {
+		      fprintf (file, "\n%4d : ", l->line_number);
+		      bfd_fprintf_vma (abfd, file, l->u.offset + symbol->section->vma);
+		    }
 		  l++;
 		}
 	    }
@@ -2176,6 +2273,7 @@ coff_find_nearest_line_with_names (bfd *
   pend = p + cof->raw_syment_count;
   while (p < pend)
     {
+      BFD_ASSERT (p->is_sym);
       if (p->u.syment.n_sclass == C_FILE)
 	break;
       p += 1 + p->u.syment.n_numaux;
@@ -2199,6 +2297,7 @@ coff_find_nearest_line_with_names (bfd *
 	       p2 < pend;
 	       p2 += 1 + p2->u.syment.n_numaux)
 	    {
+	      BFD_ASSERT (p2->is_sym);
 	      if (p2->u.syment.n_scnum > 0
 		  && (section
 		      == coff_section_from_bfd_index (abfd,
@@ -2210,6 +2309,8 @@ coff_find_nearest_line_with_names (bfd *
 		  break;
 		}
 	    }
+	  if (p2 >= pend)
+	    break;
 
 	  file_addr = (bfd_vma) p2->u.syment.n_value;
 	  /* PR 11512: Include the section address of the function name symbol.  */
@@ -2274,6 +2375,8 @@ coff_find_nearest_line_with_names (bfd *
 	      if (coff->native)
 		{
 		  combined_entry_type *s = coff->native;
+
+		  BFD_ASSERT (s->is_sym);
 		  s = s + 1 + s->u.syment.n_numaux;
 
 		  /* In XCOFF a debugging symbol can follow the
@@ -2286,6 +2389,7 @@ coff_find_nearest_line_with_names (bfd *
 		    {
 		      /* The linenumber is stored in the auxent.  */
 		      union internal_auxent *a = &((s + 1)->u.auxent);
+
 		      line_base = a->x_sym.x_misc.x_lnsz.x_lnno;
 		      *line_ptr = line_base;
 		    }
@@ -2405,6 +2509,7 @@ bfd_coff_set_symbol_class (bfd *
       if (native == NULL)
 	return FALSE;
 
+      native->is_sym = TRUE;
       native->u.syment.n_type   = T_NULL;
       native->u.syment.n_sclass = symbol_class;
 
Index: binutils-2.23.1/bfd/ihex.c
===================================================================
--- binutils-2.23.1.orig/bfd/ihex.c	2011-07-11 17:03:06.000000000 +0200
+++ binutils-2.23.1/bfd/ihex.c	2015-01-16 18:20:55.000000000 +0100
@@ -322,7 +322,7 @@ ihex_scan (bfd *abfd)
 	    {
 	      if (! ISHEX (buf[i]))
 		{
-		  ihex_bad_byte (abfd, lineno, hdr[i], error);
+		  ihex_bad_byte (abfd, lineno, buf[i], error);
 		  goto error_return;
 		}
 	    }
Index: binutils-2.23.1/bfd/coffcode.h
===================================================================
--- binutils-2.23.1.orig/bfd/coffcode.h	2011-09-27 18:03:49.000000000 +0200
+++ binutils-2.23.1/bfd/coffcode.h	2015-01-16 18:20:55.000000000 +0100
@@ -309,7 +309,7 @@ CODE_FRAGMENT
 .typedef struct coff_ptr_struct
 .{
 .  {* Remembers the offset from the first symbol in the file for
-.     this symbol. Generated by coff_renumber_symbols. *}
+.     this symbol. Generated by coff_renumber_symbols.  *}
 .  unsigned int offset;
 .
 .  {* Should the value of this symbol be renumbered.  Used for
@@ -317,15 +317,15 @@ CODE_FRAGMENT
 .  unsigned int fix_value : 1;
 .
 .  {* Should the tag field of this symbol be renumbered.
-.     Created by coff_pointerize_aux. *}
+.     Created by coff_pointerize_aux.  *}
 .  unsigned int fix_tag : 1;
 .
 .  {* Should the endidx field of this symbol be renumbered.
-.     Created by coff_pointerize_aux. *}
+.     Created by coff_pointerize_aux.  *}
 .  unsigned int fix_end : 1;
 .
 .  {* Should the x_csect.x_scnlen field be renumbered.
-.     Created by coff_pointerize_aux. *}
+.     Created by coff_pointerize_aux.  *}
 .  unsigned int fix_scnlen : 1;
 .
 .  {* Fix up an XCOFF C_BINCL/C_EINCL symbol.  The value is the
@@ -333,12 +333,15 @@ CODE_FRAGMENT
 .  unsigned int fix_line : 1;
 .
 .  {* The container for the symbol structure as read and translated
-.     from the file. *}
+.     from the file.  *}
 .  union
 .  {
 .    union internal_auxent auxent;
 .    struct internal_syment syment;
 .  } u;
+.
+. {* Selector for the union above.  *}
+. bfd_boolean is_sym;
 .} combined_entry_type;
 .
 .
@@ -920,12 +923,7 @@ handle_COMDAT (bfd * abfd,
 
       bfd_coff_swap_sym_in (abfd, esym, & isym);
 
-      if (sizeof (internal_s->s_name) > SYMNMLEN)
-	{
-	  /* This case implies that the matching
-	     symbol name will be in the string table.  */
-	  abort ();
-	}
+      BFD_ASSERT (sizeof (internal_s->s_name) <= SYMNMLEN);
 
       if (isym.n_scnum == section->target_index)
 	{
@@ -956,8 +954,12 @@ handle_COMDAT (bfd * abfd,
 	  /* All 3 branches use this.  */
 	  symname = _bfd_coff_internal_syment_name (abfd, &isym, buf);
 
+	  /* PR 17512 file: 078-11867-0.004  */ 
 	  if (symname == NULL)
-	    abort ();
+	    {
+	      _bfd_error_handler (_("%B: unable to load COMDAT section name"), abfd);
+	      break;
+	    }
 
 	  switch (seen_state)
 	    {
@@ -1784,6 +1786,7 @@ coff_new_section_hook (bfd * abfd, asect
      in case this symbol winds up getting written out.  The value 0
      for n_numaux is already correct.  */
 
+  native->is_sym = TRUE;
   native->u.syment.n_type = T_NULL;
   native->u.syment.n_sclass = sclass;
 
@@ -2491,11 +2494,13 @@ coff_pointerize_aux_hook (bfd *abfd ATTR
 			  unsigned int indaux,
 			  combined_entry_type *aux)
 {
+  BFD_ASSERT (symbol->is_sym);
   int n_sclass = symbol->u.syment.n_sclass;
 
   if (CSECT_SYM_P (n_sclass)
       && indaux + 1 == symbol->u.syment.n_numaux)
     {
+      BFD_ASSERT (! aux->is_sym);
       if (SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp) == XTY_LD)
 	{
 	  aux->u.auxent.x_csect.x_scnlen.p =
@@ -2528,6 +2533,7 @@ coff_pointerize_aux_hook (bfd *abfd ATTR
   /* Return TRUE if we don't want to pointerize this aux entry, which
      is the case for the lastfirst aux entry for a C_LEAFPROC symbol.  */
   return (indaux == 1
+	  && symbol->is_sym
 	  && (symbol->u.syment.n_sclass == C_LEAFPROC
 	      || symbol->u.syment.n_sclass == C_LEAFSTAT
 	      || symbol->u.syment.n_sclass == C_LEAFEXT));
@@ -2550,6 +2556,8 @@ coff_print_aux (bfd *abfd ATTRIBUTE_UNUS
 		combined_entry_type *aux ATTRIBUTE_UNUSED,
 		unsigned int indaux ATTRIBUTE_UNUSED)
 {
+  BFD_ASSERT (symbol->is_sym);
+  BFD_ASSERT (! aux->is_sym);
 #ifdef RS6000COFF_C
   if (CSECT_SYM_P (symbol->u.syment.n_sclass)
       && indaux + 1 == symbol->u.syment.n_numaux)
@@ -3170,6 +3178,7 @@ coff_compute_section_file_positions (bfd
 	  cf = coff_symbol_from (abfd, *symp);
 	  if (cf != NULL
 	      && cf->native != NULL
+	      && cf->native->is_sym
 	      && SYMNAME_IN_DEBUG (&cf->native->u.syment))
 	    {
 	      size_t len;
@@ -3865,6 +3874,7 @@ coff_write_object_contents (bfd * abfd)
 		  csym = coff_symbol_from (abfd, *psym);
 		  if (csym == NULL
 		      || csym->native == NULL
+		      || ! csym->native->is_sym
 		      || csym->native->u.syment.n_numaux < 1
 		      || csym->native->u.syment.n_sclass != C_STAT
 		      || csym->native->u.syment.n_type != T_NULL)
@@ -3887,6 +3897,7 @@ coff_write_object_contents (bfd * abfd)
 		 x_associated field is not currently supported.  */
 
 	      aux = csym->native + 1;
+	      BFD_ASSERT (! aux->is_sym);
 	      switch (current->flags & SEC_LINK_DUPLICATES)
 		{
 		case SEC_LINK_DUPLICATES_DISCARD:
@@ -4032,8 +4043,6 @@ coff_write_object_contents (bfd * abfd)
     internal_f.f_flags |= F_DYNLOAD;
 #endif
 
-  memset (&internal_a, 0, sizeof internal_a);
-
   /* Set up architecture-dependent stuff.  */
   {
     unsigned int magic = 0;
@@ -4449,11 +4458,11 @@ buy_and_read (bfd *abfd, file_ptr where,
   void * area = bfd_alloc (abfd, size);
 
   if (!area)
-    return (NULL);
+    return NULL;
   if (bfd_seek (abfd, where, SEEK_SET) != 0
       || bfd_bread (area, size, abfd) != size)
-    return (NULL);
-  return (area);
+    return NULL;
+  return area;
 }
 
 /*
@@ -4487,6 +4496,8 @@ coff_sort_func_alent (const void * arg1,
   const coff_symbol_type *s1 = (const coff_symbol_type *) (al1->u.sym);
   const coff_symbol_type *s2 = (const coff_symbol_type *) (al2->u.sym);
 
+  if (s1 == NULL || s2 == NULL)
+    return 0;
   if (s1->symbol.value < s2->symbol.value)
     return -1;
   else if (s1->symbol.value > s2->symbol.value)
@@ -4504,9 +4515,10 @@ coff_slurp_line_table (bfd *abfd, asecti
   unsigned int counter;
   alent *cache_ptr;
   bfd_vma prev_offset = 0;
-  int ordered = 1;
+  bfd_boolean ordered = TRUE;
   unsigned int nbr_func;
   LINENO *src;
+  bfd_boolean have_func;
 
   BFD_ASSERT (asect->lineno == NULL);
 
@@ -4529,57 +4541,85 @@ coff_slurp_line_table (bfd *abfd, asecti
   asect->lineno = lineno_cache;
   src = native_lineno;
   nbr_func = 0;
+  have_func = FALSE;
 
-  for (counter = 0; counter < asect->lineno_count; counter++)
+  for (counter = 0; counter < asect->lineno_count; counter++, src++)
     {
       struct internal_lineno dst;
 
       bfd_coff_swap_lineno_in (abfd, src, &dst);
       cache_ptr->line_number = dst.l_lnno;
+      /* Appease memory checkers that get all excited about
+	 uninitialised memory when copying alents if u.offset is
+	 larger than u.sym.  (64-bit BFD on 32-bit host.)  */
+      memset (&cache_ptr->u, 0, sizeof (cache_ptr->u));
 
       if (cache_ptr->line_number == 0)
 	{
-	  bfd_boolean warned;
-	  bfd_signed_vma symndx;
+	  combined_entry_type * ent;
+	  bfd_vma symndx;
 	  coff_symbol_type *sym;
 
-	  nbr_func++;
-	  warned = FALSE;
+	  have_func = FALSE;
 	  symndx = dst.l_addr.l_symndx;
-	  if (symndx < 0
-	      || (bfd_vma) symndx >= obj_raw_syment_count (abfd))
+	  if (symndx >= obj_raw_syment_count (abfd))
 	    {
 	      (*_bfd_error_handler)
-		(_("%B: warning: illegal symbol index %ld in line numbers"),
-		 abfd, (long) symndx);
-	      symndx = 0;
-	      warned = TRUE;
+		(_("%B: warning: illegal symbol index 0x%lx in line number entry %d"),
+		 abfd, (long) symndx, counter);
+	      cache_ptr->line_number = -1;
+	      continue;
 	    }
 
+	  ent = obj_raw_syments (abfd) + symndx;
 	  /* FIXME: We should not be casting between ints and
 	     pointers like this.  */
-	  sym = ((coff_symbol_type *)
-		 ((symndx + obj_raw_syments (abfd))
-		  ->u.syment._n._n_n._n_zeroes));
+	  if (! ent->is_sym)
+	    {
+	      (*_bfd_error_handler)
+		(_("%B: warning: illegal symbol index 0x%lx in line number entry %d"),
+		 abfd, (long) symndx, counter);
+	      cache_ptr->line_number = -1;
+	      continue;
+	    }
+	  sym = (coff_symbol_type *) (ent->u.syment._n._n_n._n_zeroes);
+
+	  /* PR 17512 file: 078-10659-0.004  */
+	  if (sym < obj_symbols (abfd)
+	      || sym >= obj_symbols (abfd) + bfd_get_symcount (abfd))
+	    {
+	      (*_bfd_error_handler)
+		(_("%B: warning: illegal symbol in line number entry %d"),
+		 abfd, counter);
+	      cache_ptr->line_number = -1;
+	      continue;
+	    }
+
+	  have_func = TRUE;
+	  nbr_func++;
 	  cache_ptr->u.sym = (asymbol *) sym;
-	  if (sym->lineno != NULL && ! warned)
+	  if (sym->lineno != NULL)
 	    (*_bfd_error_handler)
 	      (_("%B: warning: duplicate line number information for `%s'"),
 	       abfd, bfd_asymbol_name (&sym->symbol));
 
 	  sym->lineno = cache_ptr;
 	  if (sym->symbol.value < prev_offset)
-	    ordered = 0;
+	    ordered = FALSE;
 	  prev_offset = sym->symbol.value;
 	}
+      else if (!have_func)
+	/* Drop line information that has no associated function.
+	   PR 17521: file: 078-10659-0.004.  */
+	continue;
       else
-	cache_ptr->u.offset = dst.l_addr.l_paddr
-	  - bfd_section_vma (abfd, asect);
-
+	cache_ptr->u.offset = (dst.l_addr.l_paddr
+			       - bfd_section_vma (abfd, asect));
       cache_ptr++;
-      src++;
     }
-  cache_ptr->line_number = 0;
+
+  asect->lineno_count = cache_ptr - lineno_cache;
+  memset (cache_ptr, 0, sizeof (*cache_ptr));
   bfd_release (abfd, native_lineno);
 
   /* On some systems (eg AIX5.3) the lineno table may not be sorted.  */
@@ -4596,15 +4636,17 @@ coff_slurp_line_table (bfd *abfd, asecti
 	  alent **p = func_table;
 	  unsigned int i;
 
-	  for (i = 0; i < counter; i++)
+	  for (i = 0; i < asect->lineno_count; i++)
 	    if (lineno_cache[i].line_number == 0)
 	      *p++ = &lineno_cache[i];
 
+	  BFD_ASSERT ((unsigned int) (p - func_table) == nbr_func);
+	  
 	  /* Sort by functions.  */
 	  qsort (func_table, nbr_func, sizeof (alent *), coff_sort_func_alent);
 
 	  /* Create the new sorted table.  */
-	  amt = ((bfd_size_type) asect->lineno_count + 1) * sizeof (alent);
+	  amt = (bfd_size_type) asect->lineno_count * sizeof (alent);
 	  n_lineno_cache = (alent *) bfd_alloc (abfd, amt);
 	  if (n_lineno_cache != NULL)
 	    {
@@ -4615,18 +4657,18 @@ coff_slurp_line_table (bfd *abfd, asecti
 		  coff_symbol_type *sym;
 		  alent *old_ptr = func_table[i];
 
-		  /* Copy the function entry and update it.  */
-		  *n_cache_ptr = *old_ptr;
-		  sym = (coff_symbol_type *)n_cache_ptr->u.sym;
-		  sym->lineno = n_cache_ptr;
-		  n_cache_ptr++;
-		  old_ptr++;
-
-		  /* Copy the line number entries.  */
-		  while (old_ptr->line_number != 0)
+		  /* Update the function entry.  */
+		  sym = (coff_symbol_type *) old_ptr->u.sym;
+		  /* PR binutils/17512: Point the lineno to where
+		     this entry will be after the memcpy below.  */
+		  sym->lineno = lineno_cache + (n_cache_ptr - n_lineno_cache);
+		  /* Copy the function and line number entries.  */
+		  do
 		    *n_cache_ptr++ = *old_ptr++;
+		  while (old_ptr->line_number != 0);
 		}
-	      n_cache_ptr->line_number = 0;
+	      BFD_ASSERT ((bfd_size_type) (n_cache_ptr - n_lineno_cache) == (amt / sizeof (alent)));
+
 	      memcpy (lineno_cache, n_lineno_cache, amt);
 	    }
 	  bfd_release (abfd, func_table);
@@ -4665,7 +4707,7 @@ coff_slurp_symbol_table (bfd * abfd)
 
   amt = obj_raw_syment_count (abfd);
   amt *= sizeof (unsigned int);
-  table_ptr = (unsigned int *) bfd_alloc (abfd, amt);
+  table_ptr = (unsigned int *) bfd_zalloc (abfd, amt);
 
   if (table_ptr == NULL)
     return FALSE;
@@ -4679,14 +4721,17 @@ coff_slurp_symbol_table (bfd * abfd)
 	{
 	  combined_entry_type *src = native_symbols + this_index;
 	  table_ptr[this_index] = number_of_symbols;
-	  dst->symbol.the_bfd = abfd;
 
+	  dst->symbol.the_bfd = abfd;
+	  BFD_ASSERT (src->is_sym);
 	  dst->symbol.name = (char *) (src->u.syment._n._n_n._n_offset);
 	  /* We use the native name field to point to the cached field.  */
 	  src->u.syment._n._n_n._n_zeroes = (bfd_hostptr_t) dst;
 	  dst->symbol.section = coff_section_from_bfd_index (abfd,
 						     src->u.syment.n_scnum);
 	  dst->symbol.flags = 0;
+	  /* PR 17512: file: 079-7098-0.001:0.1.  */
+	  dst->symbol.value = 0;
 	  dst->done_lineno = FALSE;
 
 	  switch (src->u.syment.n_sclass)
@@ -4973,9 +5018,9 @@ coff_slurp_symbol_table (bfd * abfd)
 	    }
 
 	  dst->native = src;
-
 	  dst->symbol.udata.i = 0;
 	  dst->lineno = NULL;
+
 	  this_index += (src->u.syment.n_numaux) + 1;
 	  dst++;
 	  number_of_symbols++;
@@ -5058,13 +5103,13 @@ coff_classify_symbol (bfd *abfd,
       if (syment->n_value == 0)
 	{
 	  asection *sec;
-	  char buf[SYMNMLEN + 1];
-
-	  sec = coff_section_from_bfd_index (abfd, syment->n_scnum);
-	  if (sec != NULL
-	      && (strcmp (bfd_get_section_name (abfd, sec),
-			  _bfd_coff_internal_syment_name (abfd, syment, buf))
-		  == 0))
+	  char * name;
+ 	  char buf[SYMNMLEN + 1];
+ 
+	  name = _bfd_coff_internal_syment_name (abfd, syment, buf)
+ 	  sec = coff_section_from_bfd_index (abfd, syment->n_scnum);
+	  if (sec != NULL && name != NULL
+	      && (strcmp (bfd_get_section_name (abfd, sec), name) == 0))
 	    return COFF_SYMBOL_PE_SECTION;
 	}
 #endif
@@ -5135,6 +5180,7 @@ SUBSUBSECTION
     else if (ptr)						\
       coffsym = coff_symbol_from (abfd, ptr);			\
     if (coffsym != NULL						\
+	&& coffsym->native->is_sym				\
 	&& coffsym->native->u.syment.n_scnum == 0)		\
       cache_ptr->addend = 0;					\
     else if (ptr && bfd_asymbol_bfd (ptr) == abfd		\
Index: binutils-2.23.1/bfd/cofflink.c
===================================================================
--- binutils-2.23.1.orig/bfd/cofflink.c	2012-07-13 16:22:45.000000000 +0200
+++ binutils-2.23.1/bfd/cofflink.c	2015-01-16 18:20:55.000000000 +0100
@@ -2087,7 +2087,10 @@ _bfd_coff_link_input_bfd (struct coff_fi
 			  if (strings == NULL)
 			    return FALSE;
 			}
-		      filename = strings + auxp->x_file.x_n.x_offset;
+		      if ((bfd_size_type) auxp->x_file.x_n.x_offset >= obj_coff_strings_len (input_bfd))
+			filename = _("<corrupt>");
+		      else
+			filename = strings + auxp->x_file.x_n.x_offset;
 		      indx = _bfd_stringtab_add (flaginfo->strtab, filename,
 						 hash, copy);
 		      if (indx == (bfd_size_type) -1)
Index: binutils-2.23.1/bfd/libcoff-in.h
===================================================================
--- binutils-2.23.1.orig/bfd/libcoff-in.h	2011-11-02 15:53:04.000000000 +0100
+++ binutils-2.23.1/bfd/libcoff-in.h	2015-01-16 18:20:55.000000000 +0100
@@ -37,6 +37,7 @@
 #define obj_coff_external_syms(bfd)   (coff_data (bfd)->external_syms)
 #define obj_coff_keep_syms(bfd)	      (coff_data (bfd)->keep_syms)
 #define obj_coff_strings(bfd)	      (coff_data (bfd)->strings)
+#define obj_coff_strings_len(bfd)     (coff_data (bfd)->strings_len)
 #define obj_coff_keep_strings(bfd)    (coff_data (bfd)->keep_strings)
 #define obj_coff_sym_hashes(bfd)      (coff_data (bfd)->sym_hashes)
 #define obj_coff_strings_written(bfd) (coff_data (bfd)->strings_written)
@@ -77,6 +78,8 @@ typedef struct coff_tdata
   /* The string table.  May be NULL.  Read by
      _bfd_coff_read_string_table.  */
   char *strings;
+  /* The length of the strings table.  For error checking.  */
+  bfd_size_type strings_len;
   /* If this is TRUE, the strings may not be freed.  */
   bfd_boolean keep_strings;
   /* If this is TRUE, the strings have been written out already.  */
Index: binutils-2.23.1/bfd/libcoff.h
===================================================================
--- binutils-2.23.1.orig/bfd/libcoff.h	2011-11-02 15:53:04.000000000 +0100
+++ binutils-2.23.1/bfd/libcoff.h	2015-01-16 18:20:55.000000000 +0100
@@ -41,6 +41,7 @@
 #define obj_coff_external_syms(bfd)   (coff_data (bfd)->external_syms)
 #define obj_coff_keep_syms(bfd)	      (coff_data (bfd)->keep_syms)
 #define obj_coff_strings(bfd)	      (coff_data (bfd)->strings)
+#define obj_coff_strings_len(bfd)     (coff_data (bfd)->strings_len)
 #define obj_coff_keep_strings(bfd)    (coff_data (bfd)->keep_strings)
 #define obj_coff_sym_hashes(bfd)      (coff_data (bfd)->sym_hashes)
 #define obj_coff_strings_written(bfd) (coff_data (bfd)->strings_written)
@@ -81,6 +82,8 @@ typedef struct coff_tdata
   /* The string table.  May be NULL.  Read by
      _bfd_coff_read_string_table.  */
   char *strings;
+  /* The length of the strings table.  For error checking.  */
+  bfd_size_type strings_len;
   /* If this is TRUE, the strings may not be freed.  */
   bfd_boolean keep_strings;
   /* If this is TRUE, the strings have been written out already.  */
@@ -620,7 +623,7 @@ extern bfd_boolean ppc_process_before_al
 typedef struct coff_ptr_struct
 {
   /* Remembers the offset from the first symbol in the file for
-     this symbol. Generated by coff_renumber_symbols. */
+     this symbol. Generated by coff_renumber_symbols.  */
   unsigned int offset;
 
   /* Should the value of this symbol be renumbered.  Used for
@@ -628,15 +631,15 @@ typedef struct coff_ptr_struct
   unsigned int fix_value : 1;
 
   /* Should the tag field of this symbol be renumbered.
-     Created by coff_pointerize_aux. */
+     Created by coff_pointerize_aux.  */
   unsigned int fix_tag : 1;
 
   /* Should the endidx field of this symbol be renumbered.
-     Created by coff_pointerize_aux. */
+     Created by coff_pointerize_aux.  */
   unsigned int fix_end : 1;
 
   /* Should the x_csect.x_scnlen field be renumbered.
-     Created by coff_pointerize_aux. */
+     Created by coff_pointerize_aux.  */
   unsigned int fix_scnlen : 1;
 
   /* Fix up an XCOFF C_BINCL/C_EINCL symbol.  The value is the
@@ -644,12 +647,15 @@ typedef struct coff_ptr_struct
   unsigned int fix_line : 1;
 
   /* The container for the symbol structure as read and translated
-     from the file. */
+     from the file.  */
   union
   {
     union internal_auxent auxent;
     struct internal_syment syment;
   } u;
+
+ /* Selector for the union above.  */
+ bfd_boolean is_sym;
 } combined_entry_type;
 
 
Index: binutils-2.23.1/bfd/xcofflink.c
===================================================================
--- binutils-2.23.1.orig/bfd/xcofflink.c	2011-06-13 02:59:15.000000000 +0200
+++ binutils-2.23.1/bfd/xcofflink.c	2015-01-16 18:20:55.000000000 +0100
@@ -4496,7 +4496,10 @@ xcoff_link_input_bfd (struct xcoff_final
 			  if (strings == NULL)
 			    return FALSE;
 			}
-		      filename = strings + aux.x_file.x_n.x_offset;
+		      if ((bfd_size_type) aux.x_file.x_n.x_offset >= obj_coff_strings_len (input_bfd))
+			filename = _("<corrupt>");
+		      else
+			filename = strings + aux.x_file.x_n.x_offset;
 		      indx = _bfd_stringtab_add (flinfo->strtab, filename,
 						 hash, copy);
 		      if (indx == (bfd_size_type) -1)
Index: binutils-2.23.1/binutils/objdump.c
===================================================================
--- binutils-2.23.1.orig/binutils/objdump.c	2012-10-22 12:25:11.000000000 +0200
+++ binutils-2.23.1/binutils/objdump.c	2015-01-16 18:20:55.000000000 +0100
@@ -562,7 +562,10 @@ slurp_symtab (bfd *abfd)
 
   storage = bfd_get_symtab_upper_bound (abfd);
   if (storage < 0)
-    bfd_fatal (bfd_get_filename (abfd));
+    {
+      non_fatal (_("failed to read symbol table from: %s"), bfd_get_filename (abfd));
+      bfd_fatal (_("error message was"));
+    }
   if (storage)
     sy = (asymbol **) xmalloc (storage);
 
@@ -2389,7 +2392,12 @@ dump_dwarf (bfd *abfd)
   else if (bfd_little_endian (abfd))
     byte_get = byte_get_little_endian;
   else
-    abort ();
+    /* PR 17512: file: objdump-s-endless-loop.tekhex.  */
+    {
+      warn (_("File %s does not contain any dwarf debug information\n"),
+	    bfd_get_filename (abfd));
+      return;
+    }
 
   switch (bfd_get_arch (abfd))
     {
@@ -2491,7 +2499,7 @@ print_section_stabs (bfd *abfd,
 
      We start the index at -1 because there is a dummy symbol on
      the front of stabs-in-{coff,elf} sections that supplies sizes.  */
-  for (i = -1; stabp < stabs_end; stabp += STABSIZE, i++)
+  for (i = -1; stabp <= stabs_end - STABSIZE; stabp += STABSIZE, i++)
     {
       const char *name;
       unsigned long strx;
@@ -2529,10 +2537,13 @@ print_section_stabs (bfd *abfd,
 	}
       else
 	{
+	  bfd_size_type amt = strx + file_string_table_offset;
+
 	  /* Using the (possibly updated) string table offset, print the
 	     string (if any) associated with this symbol.  */
-	  if ((strx + file_string_table_offset) < stabstr_size)
-	    printf (" %s", &strtab[strx + file_string_table_offset]);
+	  if (amt < stabstr_size)
+	    /* PR 17512: file: 079-79389-0.001:0.1.  */
+	    printf (" %.*s", (int)(stabstr_size - amt), strtab + amt);
 	  else
 	    printf (" *");
 	}
@@ -3107,7 +3118,11 @@ dump_relocs_in_section (bfd *abfd,
   relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms);
 
   if (relcount < 0)
-    bfd_fatal (bfd_get_filename (abfd));
+    {
+      printf ("\n");
+      non_fatal (_("failed to read relocs in: %s"), bfd_get_filename (abfd));
+      bfd_fatal (_("error message was"));
+    }
   else if (relcount == 0)
     printf (" (none)\n\n");
   else
Index: binutils-2.23.1/bfd/archive.c
===================================================================
--- binutils-2.23.1.orig/bfd/archive.c	2012-07-13 16:22:42.000000000 +0200
+++ binutils-2.23.1/bfd/archive.c	2015-01-16 18:20:55.000000000 +0100
@@ -1281,6 +1281,8 @@ _bfd_slurp_extended_name_table (bfd *abf
 	{
 	byebye:
 	  bfd_release (abfd, namedata);
+	  bfd_ardata (abfd)->extended_names = NULL;
+	  bfd_ardata (abfd)->extended_names_size = 0;
 	  return FALSE;
 	}
 
@@ -1297,11 +1299,12 @@ _bfd_slurp_extended_name_table (bfd *abf
 	 text, the entries in the list are newline-padded, not null
 	 padded. In SVR4-style archives, the names also have a
 	 trailing '/'.  DOS/NT created archive often have \ in them
-	 We'll fix all problems here..  */
+	 We'll fix all problems here.  */
       {
 	char *ext_names = bfd_ardata (abfd)->extended_names;
 	char *temp = ext_names;
 	char *limit = temp + namedata->parsed_size;
+
 	for (; temp < limit; ++temp)
 	  {
 	    if (*temp == ARFMAG[1])
Index: binutils-2.23.1/binutils/ar.c
===================================================================
--- binutils-2.23.1.orig/binutils/ar.c	2012-06-29 14:59:49.000000000 +0200
+++ binutils-2.23.1/binutils/ar.c	2015-01-16 18:20:55.000000000 +0100
@@ -996,6 +996,15 @@ extract_file (bfd *abfd)
   bfd_size_type size;
   struct stat buf;
 
+  /* PR binutils/17533: Do not allow directory traversal
+     outside of the current directory tree.  */
+  if (! is_valid_archive_path (bfd_get_filename (abfd)))
+    {
+      non_fatal (_("illegal pathname found in archive member: %s"),
+		 bfd_get_filename (abfd));
+      return;
+    }
+
   if (bfd_stat_arch_elt (abfd, &buf) != 0)
     /* xgettext:c-format */
     fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
Index: binutils-2.23.1/binutils/bucomm.c
===================================================================
--- binutils-2.23.1.orig/binutils/bucomm.c	2012-06-29 14:59:49.000000000 +0200
+++ binutils-2.23.1/binutils/bucomm.c	2015-01-16 18:20:55.000000000 +0100
@@ -429,8 +429,12 @@ print_arelt_descr (FILE *file, bfd *abfd
 	  const char *ctime_result = (const char *) ctime (&when);
 	  bfd_size_type size;
 
-	  /* POSIX format:  skip weekday and seconds from ctime output.  */
-	  sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
+	  /* PR binutils/17605: Check for corrupt time values.  */
+	  if (ctime_result == NULL)
+	    sprintf (timebuf, _("<time data corrupt>"));
+	  else
+	    /* POSIX format:  skip weekday and seconds from ctime output.  */
+	    sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
 
 	  mode_string (buf.st_mode, modebuf);
 	  modebuf[10] = '\0';
@@ -624,3 +628,29 @@ bfd_get_archive_filename (const bfd *abf
 	   bfd_get_filename (abfd));
   return buf;
 }
+
+/* Returns TRUE iff PATHNAME, a filename of an archive member,
+   is valid for writing.  For security reasons absolute paths
+   and paths containing /../ are not allowed.  See PR 17533.  */
+
+bfd_boolean
+is_valid_archive_path (char const * pathname)
+{
+  const char * n = pathname;
+
+  if (IS_ABSOLUTE_PATH (n))
+    return FALSE;
+
+  while (*n)
+    {
+      if (*n == '.' && *++n == '.' && ( ! *++n || IS_DIR_SEPARATOR (*n)))
+	return FALSE;
+
+      while (*n && ! IS_DIR_SEPARATOR (*n))
+	n++;
+      while (IS_DIR_SEPARATOR (*n))
+	n++;
+    }
+
+  return TRUE;
+}
Index: binutils-2.23.1/binutils/bucomm.h
===================================================================
--- binutils-2.23.1.orig/binutils/bucomm.h	2009-09-02 09:22:31.000000000 +0200
+++ binutils-2.23.1/binutils/bucomm.h	2015-01-16 18:20:55.000000000 +0100
@@ -23,6 +23,8 @@
 #ifndef _BUCOMM_H
 #define _BUCOMM_H
 
+/* In bucomm.c.  */
+
 /* Return the filename in a static buffer.  */
 const char *bfd_get_archive_filename (const bfd *);
 
@@ -58,20 +60,22 @@ bfd_vma parse_vma (const char *, const c
 
 off_t get_file_size (const char *);
 
+bfd_boolean is_valid_archive_path (char const *);
+
 extern char *program_name;
 
-/* filemode.c */
+/* In filemode.c.  */
 void mode_string (unsigned long, char *);
 
-/* version.c */
+/* In version.c.  */
 extern void print_version (const char *);
 
-/* rename.c */
+/* In rename.c.  */
 extern void set_times (const char *, const struct stat *);
 
 extern int smart_rename (const char *, const char *, int);
 
-/* libiberty.  */
+/* In libiberty.  */
 void *xmalloc (size_t);
 
 void *xrealloc (void *, size_t);
Index: binutils-2.23.1/binutils/doc/binutils.texi
===================================================================
--- binutils-2.23.1.orig/binutils/doc/binutils.texi	2012-05-11 20:18:34.000000000 +0200
+++ binutils-2.23.1/binutils/doc/binutils.texi	2015-01-16 18:20:55.000000000 +0100
@@ -228,7 +228,8 @@ contents of each object would only waste
 are also @emph{flattened}, so that adding one or more archives to a
 thin archive will add the elements of the nested archive individually.
 The paths to the elements of the archive are stored relative to the
-archive itself.
+archive itself.  For security reasons absolute paths and paths with a
+@code{/../} component are not allowed.
 
 @cindex compatibility, @command{ar}
 @cindex @command{ar} compatibility
Index: binutils-2.23.1/binutils/objcopy.c
===================================================================
--- binutils-2.23.1.orig/binutils/objcopy.c	2012-05-08 19:49:36.000000000 +0200
+++ binutils-2.23.1/binutils/objcopy.c	2015-01-16 18:20:55.000000000 +0100
@@ -2096,6 +2096,16 @@ copy_archive (bfd *ibfd, bfd *obfd, cons
       bfd_boolean del = TRUE;
       bfd_boolean ok_object;
 
+      /* PR binutils/17533: Do not allow directory traversal
+	 outside of the current directory tree by archive members.  */
+      if (! is_valid_archive_path (bfd_get_filename (this_element)))
+	{
+	  non_fatal (_("illegal pathname found in archive member: %s"),
+		     bfd_get_filename (this_element));
+	  status = 1;
+	  goto cleanup_and_exit;
+	}
+
       /* Create an output file for this member.  */
       output_name = concat (dir, "/",
 			    bfd_get_filename (this_element), (char *) 0);
@@ -2105,8 +2115,12 @@ copy_archive (bfd *ibfd, bfd *obfd, cons
 	{
 	  output_name = make_tempdir (output_name);
 	  if (output_name == NULL)
-	    fatal (_("cannot create tempdir for archive copying (error: %s)"),
-		   strerror (errno));
+	    {
+	      non_fatal (_("cannot create tempdir for archive copying (error: %s)"),
+			 strerror (errno));
+	      status = 1;
+	      goto cleanup_and_exit;
+	    }
 
 	  l = (struct name_list *) xmalloc (sizeof (struct name_list));
 	  l->name = output_name;
@@ -2148,7 +2162,7 @@ copy_archive (bfd *ibfd, bfd *obfd, cons
 	{
 	  bfd_nonfatal_message (output_name, NULL, NULL, NULL);
 	  status = 1;
-	  return;
+	  goto cleanup_and_exit;
 	}
 
       if (ok_object)
@@ -2209,7 +2223,6 @@ copy_archive (bfd *ibfd, bfd *obfd, cons
     {
       status = 1;
       bfd_nonfatal_message (filename, NULL, NULL, NULL);
-      return;
     }
 
   filename = bfd_get_filename (ibfd);
@@ -2217,9 +2230,9 @@ copy_archive (bfd *ibfd, bfd *obfd, cons
     {
       status = 1;
       bfd_nonfatal_message (filename, NULL, NULL, NULL);
-      return;
     }
 
+ cleanup_and_exit:
   /* Delete all the files that we opened.  */
   for (l = list; l != NULL; l = l->next)
     {
Index: binutils-2.23.1/bfd/coff-i386.c
===================================================================
--- binutils-2.23.1.orig/bfd/coff-i386.c	2012-07-13 16:22:43.000000000 +0200
+++ binutils-2.23.1/bfd/coff-i386.c	2015-01-16 18:20:55.000000000 +0100
@@ -342,16 +342,18 @@ static reloc_howto_type howto_table[] =
 	 PCRELOFFSET)		/* pcrel_offset */
 };
 
+#define NUM_HOWTOS (sizeof (howto_table) / sizeof (howto_table[0]))
+
 /* Turn a howto into a reloc  nunmber */
 
 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
 #define BADMAG(x) I386BADMAG(x)
 #define I386 1			/* Customize coffcode.h */
 
-#define RTYPE2HOWTO(cache_ptr, dst)					\
-  ((cache_ptr)->howto =							\
-   ((dst)->r_type < sizeof (howto_table) / sizeof (howto_table[0])	\
-    ? howto_table + (dst)->r_type					\
+#define RTYPE2HOWTO(cache_ptr, dst)				\
+  ((cache_ptr)->howto =						\
+   ((dst)->r_type < NUM_HOWTOS					\
+    ? howto_table + (dst)->r_type				\
     : NULL))
 
 /* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
@@ -388,7 +390,8 @@ static reloc_howto_type howto_table[] =
       cache_ptr->addend = - (ptr->section->vma + ptr->value);	\
     else							\
       cache_ptr->addend = 0;					\
-    if (ptr && howto_table[reloc.r_type].pc_relative)		\
+    if (ptr && reloc.r_type < NUM_HOWTOS			\
+	&& howto_table[reloc.r_type].pc_relative)		\
       cache_ptr->addend += asect->vma;				\
   }
 
@@ -440,7 +443,7 @@ coff_i386_rtype_to_howto (bfd *abfd ATTR
 {
   reloc_howto_type *howto;
 
-  if (rel->r_type >= sizeof (howto_table) / sizeof (howto_table[0]))
+  if (rel->r_type >= NUM_HOWTOS)
     {
       bfd_set_error (bfd_error_bad_value);
       return NULL;
@@ -576,7 +579,7 @@ coff_i386_reloc_name_lookup (bfd *abfd A
 {
   unsigned int i;
 
-  for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++)
+  for (i = 0; i < NUM_HOWTOS; i++)
     if (howto_table[i].name != NULL
 	&& strcasecmp (howto_table[i].name, r_name) == 0)
       return &howto_table[i];
Index: binutils-2.23.1/bfd/coff-x86_64.c
===================================================================
--- binutils-2.23.1.orig/bfd/coff-x86_64.c	2012-01-16 09:30:18.000000000 +0100
+++ binutils-2.23.1/bfd/coff-x86_64.c	2015-01-16 18:20:55.000000000 +0100
@@ -449,6 +449,8 @@ static reloc_howto_type howto_table[] =
 	 PCRELOFFSET)		/* pcrel_offset */
 };
 
+#define NUM_HOWTOS ARRAY_SIZE (howto_table)
+
 /* Turn a howto into a reloc  nunmber */
 
 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
@@ -457,7 +459,7 @@ static reloc_howto_type howto_table[] =
 
 #define RTYPE2HOWTO(cache_ptr, dst)		\
   ((cache_ptr)->howto =				\
-   ((dst)->r_type < ARRAY_SIZE (howto_table))	\
+   ((dst)->r_type < NUM_HOWTOS)			\
     ? howto_table + (dst)->r_type		\
     : NULL)
 
@@ -497,7 +499,8 @@ static reloc_howto_type howto_table[] =
       cache_ptr->addend = - (ptr->section->vma + ptr->value);	\
     else							\
       cache_ptr->addend = 0;					\
-    if (ptr && howto_table[reloc.r_type].pc_relative)		\
+    if (ptr && reloc.r_type < NUM_HOWTOS			\
+	&& howto_table[reloc.r_type].pc_relative)		\
       cache_ptr->addend += asect->vma;				\
   }
 
@@ -547,7 +550,7 @@ coff_amd64_rtype_to_howto (bfd *abfd ATT
 {
   reloc_howto_type *howto;
 
-  if (rel->r_type >= ARRAY_SIZE (howto_table))
+  if (rel->r_type >= NUM_HOWTOS)
     {
       bfd_set_error (bfd_error_bad_value);
       return NULL;
@@ -690,7 +693,7 @@ coff_amd64_reloc_name_lookup (bfd *abfd
 {
   unsigned int i;
 
-  for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++)
+  for (i = 0; i < NUM_HOWTOS; i++)
     if (howto_table[i].name != NULL
 	&& strcasecmp (howto_table[i].name, r_name) == 0)
       return &howto_table[i];
Index: binutils-2.23.1/bfd/opncls.c
===================================================================
--- binutils-2.23.1.orig/bfd/opncls.c	2012-05-29 16:23:33.000000000 +0200
+++ binutils-2.23.1/bfd/opncls.c	2015-01-16 18:20:55.000000000 +0100
@@ -923,14 +923,19 @@ void *
 bfd_alloc (bfd *abfd, bfd_size_type size)
 {
   void *ret;
+  unsigned long ul_size = (unsigned long) size;
 
-  if (size != (unsigned long) size)
+  if (size != ul_size
+      /* A small negative size can result in objalloc_alloc allocating just
+	 1 byte of memory, but the caller will be expecting more.  So catch
+	 this case here.  */
+      || (size != 0 && (((ul_size + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1)) == 0)))
     {
       bfd_set_error (bfd_error_no_memory);
       return NULL;
     }
-
-  ret = objalloc_alloc ((struct objalloc *) abfd->memory, (unsigned long) size);
+							
+  ret = objalloc_alloc ((struct objalloc *) abfd->memory, ul_size);
   if (ret == NULL)
     bfd_set_error (bfd_error_no_memory);
   return ret;
@@ -951,8 +956,6 @@ DESCRIPTION
 void *
 bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size)
 {
-  void *ret;
-
   if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
       && size != 0
       && nmemb > ~(bfd_size_type) 0 / size)
@@ -961,18 +964,7 @@ bfd_alloc2 (bfd *abfd, bfd_size_type nme
       return NULL;
     }
 
-  size *= nmemb;
-
-  if (size != (unsigned long) size)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return NULL;
-    }
-
-  ret = objalloc_alloc ((struct objalloc *) abfd->memory, (unsigned long) size);
-  if (ret == NULL)
-    bfd_set_error (bfd_error_no_memory);
-  return ret;
+  return bfd_alloc (abfd, size * nmemb);
 }
 
 /*
@@ -1161,7 +1153,7 @@ get_debug_link_info (bfd *abfd, unsigned
   asection *sect;
   unsigned long crc32;
   bfd_byte *contents;
-  int crc_offset;
+  unsigned int crc_offset;
   char *name;
 
   BFD_ASSERT (abfd);
@@ -1179,10 +1171,13 @@ get_debug_link_info (bfd *abfd, unsigned
       return NULL;
     }
 
-  /* Crc value is stored after the filename, aligned up to 4 bytes.  */
+  /* CRC value is stored after the filename, aligned up to 4 bytes.  */
   name = (char *) contents;
-  crc_offset = strlen (name) + 1;
+  /* PR 17597: avoid reading off the end of the buffer.  */
+  crc_offset = strnlen (name, bfd_get_section_size (sect)) + 1;
   crc_offset = (crc_offset + 3) & ~3;
+  if (crc_offset >= bfd_get_section_size (sect))
+    return NULL;
 
   crc32 = bfd_get_32 (abfd, contents + crc_offset);
 
Index: binutils-2.23.1/bfd/pe-mips.c
===================================================================
--- binutils-2.23.1.orig/bfd/pe-mips.c	2011-06-06 03:26:03.000000000 +0200
+++ binutils-2.23.1/bfd/pe-mips.c	2015-01-16 18:20:55.000000000 +0100
@@ -341,6 +341,8 @@ static reloc_howto_type howto_table[] =
 	 FALSE),                /* Pcrel_offset. */
 };
 
+#define NUM_HOWTOS (sizeof (howto_table) / sizeof (howto_table[0]))
+
 /* Turn a howto into a reloc nunmber.  */
 
 #define SELECT_RELOC(x, howto) { x.r_type = howto->type; }
@@ -381,7 +383,8 @@ static reloc_howto_type howto_table[] =
       cache_ptr->addend = - (ptr->section->vma + ptr->value);	\
     else							\
       cache_ptr->addend = 0;					\
-    if (ptr && howto_table[reloc.r_type].pc_relative)		\
+    if (ptr && reloc.r_type < NUM_HOWTOS			\
+	&& howto_table[reloc.r_type].pc_relative)		\
       cache_ptr->addend += asect->vma;				\
   }
 
@@ -511,9 +514,7 @@ coff_mips_reloc_name_lookup (bfd *abfd A
 {
   unsigned int i;
 
-  for (i = 0;
-       i < sizeof (howto_table) / sizeof (howto_table[0]);
-       i++)
+  for (i = 0; i < NUM_HOWTOS; i++)
     if (howto_table[i].name != NULL
 	&& strcasecmp (howto_table[i].name, r_name) == 0)
       return &howto_table[i];
Index: binutils-2.23.1/bfd/peicode.h
===================================================================
--- binutils-2.23.1.orig/bfd/peicode.h	2012-05-05 05:05:25.000000000 +0200
+++ binutils-2.23.1/bfd/peicode.h	2015-01-16 18:20:55.000000000 +0100
@@ -265,6 +265,7 @@ pe_mkobject (bfd * abfd)
   /* in_reloc_p is architecture dependent.  */
   pe->in_reloc_p = in_reloc_p;
 
+  memset (& pe->pe_opthdr, 0, sizeof pe->pe_opthdr);
   return TRUE;
 }
 
@@ -561,6 +562,7 @@ pe_ILF_make_a_symbol (pe_ILF_vars *  var
   ent->u.syment.n_sclass          = sclass;
   ent->u.syment.n_scnum           = section->target_index;
   ent->u.syment._n._n_n._n_offset = (bfd_hostptr_t) sym;
+  ent->is_sym = TRUE;
 
   sym->symbol.the_bfd = vars->abfd;
   sym->symbol.name    = vars->string_ptr;
Index: binutils-2.23.1/binutils/rdcoff.c
===================================================================
--- binutils-2.23.1.orig/binutils/rdcoff.c	2009-09-02 09:22:32.000000000 +0200
+++ binutils-2.23.1/binutils/rdcoff.c	2015-01-16 18:20:55.000000000 +0100
@@ -84,7 +84,7 @@ struct coff_types
   debug_type basic[T_MAX + 1];
 };
 
-static debug_type *coff_get_slot (struct coff_types *, int);
+static debug_type *coff_get_slot (struct coff_types *, long);
 static debug_type parse_coff_type
   (bfd *, struct coff_symbols *, struct coff_types *, long, int,
    union internal_auxent *, bfd_boolean, void *);
@@ -105,12 +105,17 @@ static bfd_boolean external_coff_symbol_
 /* Return the slot for a type.  */
 
 static debug_type *
-coff_get_slot (struct coff_types *types, int indx)
+coff_get_slot (struct coff_types *types, long indx)
 {
   struct coff_slots **pps;
 
   pps = &types->slots;
 
+  /* PR 17512: file: 078-18333-0.001:0.1.
+     FIXME: The value of 1000 is a guess.  Maybe a better heuristic is needed.  */
+  if (indx / COFF_SLOTS > 1000)
+    fatal (_("Excessively large slot index: %lx"), indx);
+
   while (indx >= COFF_SLOTS)
     {
       if (*pps == NULL)
Index: binutils-2.23.1/binutils/rddbg.c
===================================================================
--- binutils-2.23.1.orig/binutils/rddbg.c	2010-04-09 16:40:13.000000000 +0200
+++ binutils-2.23.1/binutils/rddbg.c	2015-01-16 18:20:55.000000000 +0100
@@ -140,7 +140,7 @@ read_section_stabs_debugging_info (bfd *
 	    }
 
 	  strsize = bfd_section_size (abfd, strsec);
-	  strings = (bfd_byte *) xmalloc (strsize);
+	  strings = (bfd_byte *) xmalloc (strsize + 1);
 	  if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize))
 	    {
 	      fprintf (stderr, "%s: %s: %s\n",
@@ -148,7 +148,8 @@ read_section_stabs_debugging_info (bfd *
 		       bfd_errmsg (bfd_get_error ()));
 	      return FALSE;
 	    }
-
+	  /* Zero terminate the strings table, just in case.  */
+	  strings [strsize] = 0;
 	  if (shandle == NULL)
 	    {
 	      shandle = start_stab (dhandle, abfd, TRUE, syms, symcount);
@@ -160,7 +161,8 @@ read_section_stabs_debugging_info (bfd *
 
 	  stroff = 0;
 	  next_stroff = 0;
-	  for (stab = stabs; stab < stabs + stabsize; stab += 12)
+	  /* PR 17512: file: 078-60391-0.001:0.1.  */
+	  for (stab = stabs; stab <= (stabs + stabsize) - 12; stab += 12)
 	    {
 	      unsigned int strx;
 	      int type;
@@ -185,33 +187,43 @@ read_section_stabs_debugging_info (bfd *
 		}
 	      else
 		{
+		  size_t len;
 		  char *f, *s;
 
-		  f = NULL;
-
-		  if (stroff + strx > strsize)
+		  if (stroff + strx >= strsize)
 		    {
-		      fprintf (stderr, "%s: %s: stab entry %ld is corrupt, strx = 0x%x, type = %d\n",
+		      fprintf (stderr, _("%s: %s: stab entry %ld is corrupt, strx = 0x%x, type = %d\n"),
 			       bfd_get_filename (abfd), names[i].secname,
 			       (long) (stab - stabs) / 12, strx, type);
 		      continue;
 		    }
 
 		  s = (char *) strings + stroff + strx;
+		  f = NULL;
 
-		  while (s[strlen (s) - 1] == '\\'
+		  /* PR 17512: file: 002-87578-0.001:0.1.
+		     It is possible to craft a file where, without the 'strlen (s) > 0',
+		     an attempt to read the byte before 'strings' would occur.  */
+		  while ((len = strlen (s)) > 0
+			 && s[len  - 1] == '\\'
 			 && stab + 12 < stabs + stabsize)
 		    {
 		      char *p;
 
 		      stab += 12;
-		      p = s + strlen (s) - 1;
+		      p = s + len - 1;
 		      *p = '\0';
-		      s = concat (s,
-				  ((char *) strings
-				   + stroff
-				   + bfd_get_32 (abfd, stab)),
-				  (const char *) NULL);
+		      strx = stroff + bfd_get_32 (abfd, stab);
+		      if (strx >= strsize)
+			{
+			  fprintf (stderr, _("%s: %s: stab entry %ld is corrupt\n"),
+				   bfd_get_filename (abfd), names[i].secname,
+				   (long) (stab - stabs) / 12);
+			  break;
+			}
+		      else
+			s = concat (s, (char *) strings + strx,
+				    (const char *) NULL);
 
 		      /* We have to restore the backslash, because, if
 			 the linker is hashing stabs strings, we may
Index: binutils-2.23.1/binutils/stabs.c
===================================================================
--- binutils-2.23.1.orig/binutils/stabs.c	2012-03-30 14:51:07.000000000 +0200
+++ binutils-2.23.1/binutils/stabs.c	2015-01-16 18:20:55.000000000 +0100
@@ -837,8 +837,6 @@ parse_stab_string (void *dhandle, struct
 
     case 'G':
       {
-	char leading;
-	long c;
 	asymbol **ps;
 
 	/* A global symbol.  The value must be extracted from the
@@ -847,19 +845,27 @@ parse_stab_string (void *dhandle, struct
 				 (debug_type **) NULL);
 	if (dtype == DEBUG_TYPE_NULL)
 	  return FALSE;
-	leading = bfd_get_symbol_leading_char (info->abfd);
-	for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps)
+	if (name != NULL)
 	  {
-	    const char *n;
+	    char leading;
+	    long c;
 
-	    n = bfd_asymbol_name (*ps);
-	    if (leading != '\0' && *n == leading)
-	      ++n;
-	    if (*n == *name && strcmp (n, name) == 0)
-	      break;
+	    leading = bfd_get_symbol_leading_char (info->abfd);
+	    for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps)
+	      {
+		const char *n;
+
+		n = bfd_asymbol_name (*ps);
+		if (leading != '\0' && *n == leading)
+		  ++n;
+		if (*n == *name && strcmp (n, name) == 0)
+		  break;
+	      }
+
+	    if (c > 0)
+	      value = bfd_asymbol_value (*ps);
 	  }
-	if (c > 0)
-	  value = bfd_asymbol_value (*ps);
+
 	if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_GLOBAL,
 				    value))
 	  return FALSE;
Index: binutils-2.23.1/gas/config/obj-coff.c
===================================================================
--- binutils-2.23.1.orig/gas/config/obj-coff.c	2011-09-27 20:57:22.000000000 +0200
+++ binutils-2.23.1/gas/config/obj-coff.c	2015-01-16 18:20:55.000000000 +0100
@@ -389,6 +389,7 @@ coff_obj_symbol_new_hook (symbolS *symbo
 
   memset (s, 0, sz);
   coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s;
+  coffsymbol (symbol_get_bfdsym (symbolP))->native->is_sym = TRUE;
 
   S_SET_DATA_TYPE (symbolP, T_NULL);
   S_SET_STORAGE_CLASS (symbolP, 0);
Index: binutils-2.23.1/bfd/ieee.c
===================================================================
--- binutils-2.23.1.orig/bfd/ieee.c	2011-07-11 17:03:06.000000000 +0200
+++ binutils-2.23.1/bfd/ieee.c	2015-01-16 18:20:55.000000000 +0100
@@ -171,9 +171,16 @@ ieee_write_id (bfd *abfd, const char *id
    standard requires.  */
 
 #define this_byte(ieee)           *((ieee)->input_p)
-#define next_byte(ieee)            ((ieee)->input_p++)
 #define this_byte_and_next(ieee) (*((ieee)->input_p++))
 
+static bfd_boolean
+next_byte (common_header_type * ieee)
+{
+  ieee->input_p++;
+
+  return ieee->input_p < ieee->last_byte;
+}
+
 static unsigned short
 read_2bytes (common_header_type *ieee)
 {
@@ -349,15 +356,15 @@ parse_int (common_header_type *ieee, bfd
   if (value >= 0 && value <= 127)
     {
       *value_ptr = value;
-      next_byte (ieee);
-      return TRUE;
+      return next_byte (ieee);
     }
   else if (value >= 0x80 && value <= 0x88)
     {
       unsigned int count = value & 0xf;
 
       result = 0;
-      next_byte (ieee);
+      if (! next_byte (ieee))
+	return FALSE;
       while (count)
 	{
 	  result = (result << 8) | this_byte_and_next (ieee);
@@ -497,7 +504,7 @@ static reloc_howto_type rel8_howto =
 
 static ieee_symbol_index_type NOSYMBOL = {0, 0};
 
-static void
+static bfd_boolean
 parse_expression (ieee_data_type *ieee,
 		  bfd_vma *value,
 		  ieee_symbol_index_type *symbol,
@@ -530,68 +537,83 @@ parse_expression (ieee_data_type *ieee,
 	  {
 	    int section_n;
 
-	    next_byte (&(ieee->h));
+	    if (! next_byte (&(ieee->h)))
+	      return FALSE;
 	    *pcrel = TRUE;
 	    section_n = must_parse_int (&(ieee->h));
 	    (void) section_n;
 	    PUSH (NOSYMBOL, bfd_abs_section_ptr, 0);
 	    break;
 	  }
+
 	case ieee_variable_L_enum:
 	  /* L variable  address of section N.  */
-	  next_byte (&(ieee->h));
+	  if (! next_byte (&(ieee->h)))
+	    return FALSE;
 	  PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0);
 	  break;
+
 	case ieee_variable_R_enum:
 	  /* R variable, logical address of section module.  */
 	  /* FIXME, this should be different to L.  */
-	  next_byte (&(ieee->h));
+	  if (! next_byte (&(ieee->h)))
+	    return FALSE;
 	  PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0);
 	  break;
+
 	case ieee_variable_S_enum:
 	  /* S variable, size in MAUS of section module.  */
-	  next_byte (&(ieee->h));
+	  if (! next_byte (&(ieee->h)))
+	    return FALSE;
 	  PUSH (NOSYMBOL,
 		0,
 		ieee->section_table[must_parse_int (&(ieee->h))]->size);
 	  break;
+
 	case ieee_variable_I_enum:
 	  /* Push the address of variable n.  */
 	  {
 	    ieee_symbol_index_type sy;
 
-	    next_byte (&(ieee->h));
+	    if (! next_byte (&(ieee->h)))
+	      return FALSE;
 	    sy.index = (int) must_parse_int (&(ieee->h));
 	    sy.letter = 'I';
 
 	    PUSH (sy, bfd_abs_section_ptr, 0);
 	  }
 	  break;
+
 	case ieee_variable_X_enum:
 	  /* Push the address of external variable n.  */
 	  {
 	    ieee_symbol_index_type sy;
 
-	    next_byte (&(ieee->h));
+	    if (! next_byte (&(ieee->h)))
+	      return FALSE;
+
 	    sy.index = (int) (must_parse_int (&(ieee->h)));
 	    sy.letter = 'X';
 
 	    PUSH (sy, bfd_und_section_ptr, 0);
 	  }
 	  break;
+
 	case ieee_function_minus_enum:
 	  {
 	    bfd_vma value1, value2;
 	    asection *section1, *section_dummy;
 	    ieee_symbol_index_type sy;
 
-	    next_byte (&(ieee->h));
+	    if (! next_byte (&(ieee->h)))
+	      return FALSE;
 
 	    POP (sy, section1, value1);
 	    POP (sy, section_dummy, value2);
 	    PUSH (sy, section1 ? section1 : section_dummy, value2 - value1);
 	  }
 	  break;
+
 	case ieee_function_plus_enum:
 	  {
 	    bfd_vma value1, value2;
@@ -600,7 +622,8 @@ parse_expression (ieee_data_type *ieee,
 	    ieee_symbol_index_type sy1;
 	    ieee_symbol_index_type sy2;
 
-	    next_byte (&(ieee->h));
+	    if (! next_byte (&(ieee->h)))
+	      return FALSE;
 
 	    POP (sy1, section1, value1);
 	    POP (sy2, section2, value2);
@@ -609,6 +632,7 @@ parse_expression (ieee_data_type *ieee,
 		  value1 + value2);
 	  }
 	  break;
+
 	default:
 	  {
 	    bfd_vma va;
@@ -645,17 +669,9 @@ parse_expression (ieee_data_type *ieee,
   POP (*symbol, dummy, *value);
   if (section)
     *section = dummy;
-}
-
 
-#define ieee_seek(ieee, offset) \
-  do								\
-    {								\
-      ieee->h.input_p = ieee->h.first_byte + offset;		\
-      ieee->h.last_byte = (ieee->h.first_byte			\
-			   + ieee_part_after (ieee, offset));	\
-    }								\
-  while (0)
+  return TRUE;
+}
 
 #define ieee_pos(ieee) \
   (ieee->h.input_p - ieee->h.first_byte)
@@ -677,6 +693,22 @@ ieee_part_after (ieee_data_type *ieee, f
   return after;
 }
 
+static bfd_boolean
+ieee_seek (ieee_data_type * ieee, file_ptr offset)
+{
+  /* PR 17512: file:  017-1157-0.004.  */
+  if (offset < 0 || (bfd_size_type) offset >= ieee->h.total_amt)
+    {
+      ieee->h.input_p = ieee->h.first_byte + ieee->h.total_amt;
+      ieee->h.last_byte = ieee->h.input_p;
+      return FALSE;
+    }
+
+  ieee->h.input_p = ieee->h.first_byte + offset;
+  ieee->h.last_byte = (ieee->h.first_byte + ieee_part_after (ieee, offset));
+  return TRUE;
+}
+
 static unsigned int last_index;
 static char last_type;		/* Is the index for an X or a D.  */
 
@@ -731,14 +763,16 @@ ieee_slurp_external_symbols (bfd *abfd)
   last_index = 0xffffff;
   ieee->symbol_table_full = TRUE;
 
-  ieee_seek (ieee, offset);
+  if (! ieee_seek (ieee, offset))
+    return FALSE;
 
   while (loop)
     {
       switch (this_byte (&(ieee->h)))
 	{
 	case ieee_nn_record:
-	  next_byte (&(ieee->h));
+	  if (! next_byte (&(ieee->h)))
+	    return FALSE;
 
 	  symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
 			       & prev_symbols_ptr,
@@ -751,8 +785,10 @@ ieee_slurp_external_symbols (bfd *abfd)
 	  symbol->symbol.udata.p = NULL;
 	  symbol->symbol.flags = BSF_NO_FLAGS;
 	  break;
+
 	case ieee_external_symbol_enum:
-	  next_byte (&(ieee->h));
+	  if (! next_byte (&(ieee->h)))
+	    return FALSE;
 
 	  symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
 			       &prev_symbols_ptr,
@@ -843,6 +879,7 @@ ieee_slurp_external_symbols (bfd *abfd)
 	      }
 	  }
 	  break;
+
 	case ieee_value_record_enum >> 8:
 	  {
 	    unsigned int symbol_name_index;
@@ -850,17 +887,20 @@ ieee_slurp_external_symbols (bfd *abfd)
 	    bfd_boolean pcrel_ignore;
 	    unsigned int extra;
 
-	    next_byte (&(ieee->h));
-	    next_byte (&(ieee->h));
+	    if (! next_byte (&(ieee->h)))
+	      return FALSE;
+	    if (! next_byte (&(ieee->h)))
+	      return FALSE;
 
 	    symbol_name_index = must_parse_int (&(ieee->h));
 	    (void) symbol_name_index;
-	    parse_expression (ieee,
-			      &symbol->symbol.value,
-			      &symbol_ignore,
-			      &pcrel_ignore,
-			      &extra,
-			      &symbol->symbol.section);
+	    if (! parse_expression (ieee,
+				    &symbol->symbol.value,
+				    &symbol_ignore,
+				    &pcrel_ignore,
+				    &extra,
+				    &symbol->symbol.section))
+	      return FALSE;
 
 	    /* Fully linked IEEE-695 files tend to give every symbol
                an absolute value.  Try to convert that back into a
@@ -893,7 +933,9 @@ ieee_slurp_external_symbols (bfd *abfd)
 	    bfd_vma size;
 	    bfd_vma value;
 
-	    next_byte (&(ieee->h));
+	    if (! next_byte (&(ieee->h)))
+	      return FALSE;
+
 	    /* Throw away the external reference index.  */
 	    (void) must_parse_int (&(ieee->h));
 	    /* Fetch the default size if not resolved.  */
@@ -908,7 +950,8 @@ ieee_slurp_external_symbols (bfd *abfd)
 	  break;
 
 	case ieee_external_reference_enum:
-	  next_byte (&(ieee->h));
+	  if (! next_byte (&(ieee->h)))
+	    return FALSE;
 
 	  symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
 			       &prev_reference_ptr,
@@ -1093,7 +1136,7 @@ get_section_entry (bfd *abfd, ieee_data_
   return ieee->section_table[sindex];
 }
 
-static void
+static bfd_boolean
 ieee_slurp_sections (bfd *abfd)
 {
   ieee_data_type *ieee = IEEE_DATA (abfd);
@@ -1104,7 +1147,9 @@ ieee_slurp_sections (bfd *abfd)
     {
       bfd_byte section_type[3];
 
-      ieee_seek (ieee, offset);
+      if (! ieee_seek (ieee, offset))
+	return FALSE;
+
       while (TRUE)
 	{
 	  switch (this_byte (&(ieee->h)))
@@ -1114,7 +1159,8 @@ ieee_slurp_sections (bfd *abfd)
 		asection *section;
 		unsigned int section_index;
 
-		next_byte (&(ieee->h));
+		if (! next_byte (&(ieee->h)))
+		  return FALSE;
 		section_index = must_parse_int (&(ieee->h));
 
 		section = get_section_entry (abfd, ieee, section_index);
@@ -1133,22 +1179,26 @@ ieee_slurp_sections (bfd *abfd)
 		      {
 			/* AS Absolute section attributes.  */
 		      case 0xD3:
-			next_byte (&(ieee->h));
+			if (! next_byte (&(ieee->h)))
+			  return FALSE;
 			section_type[2] = this_byte (&(ieee->h));
 			switch (section_type[2])
 			  {
 			  case 0xD0:
 			    /* Normal code.  */
-			    next_byte (&(ieee->h));
+			    if (! next_byte (&(ieee->h)))
+			      return FALSE;
 			    section->flags |= SEC_CODE;
 			    break;
 			  case 0xC4:
 			    /* Normal data.  */
-			    next_byte (&(ieee->h));
+			    if (! next_byte (&(ieee->h)))
+			      return FALSE;
 			    section->flags |= SEC_DATA;
 			    break;
 			  case 0xD2:
-			    next_byte (&(ieee->h));
+			    if (! next_byte (&(ieee->h)))
+			      return FALSE;
 			    /* Normal rom data.  */
 			    section->flags |= SEC_ROM | SEC_DATA;
 			    break;
@@ -1165,15 +1215,18 @@ ieee_slurp_sections (bfd *abfd)
 		    switch (section_type[1])
 		      {
 		      case 0xD0:	/* Normal code (CP).  */
-			next_byte (&(ieee->h));
+			if (! next_byte (&(ieee->h)))
+			  return FALSE;
 			section->flags |= SEC_CODE;
 			break;
 		      case 0xC4:	/* Normal data (CD).  */
-			next_byte (&(ieee->h));
+			if (! next_byte (&(ieee->h)))
+			  return FALSE;
 			section->flags |= SEC_DATA;
 			break;
 		      case 0xD2:	/* Normal rom data (CR).  */
-			next_byte (&(ieee->h));
+			if (! next_byte (&(ieee->h)))
+			  return FALSE;
 			section->flags |= SEC_ROM | SEC_DATA;
 			break;
 		      default:
@@ -1202,7 +1255,8 @@ ieee_slurp_sections (bfd *abfd)
 		bfd_vma value;
 		asection *section;
 
-		next_byte (&(ieee->h));
+		if (! next_byte (&(ieee->h)))
+		  return FALSE;
 		section_index = must_parse_int (&ieee->h);
 		section = get_section_entry (abfd, ieee, section_index);
 		if (section_index > ieee->section_count)
@@ -1252,15 +1306,17 @@ ieee_slurp_sections (bfd *abfd)
 		    (void) must_parse_int (&(ieee->h));
 		    break;
 		  default:
-		    return;
+		    return TRUE;
 		  }
 	      }
 	      break;
 	    default:
-	      return;
+	      return TRUE;
 	    }
 	}
     }
+
+  return TRUE;
 }
 
 /* Make a section for the debugging information, if any.  We don't try
@@ -1313,7 +1369,8 @@ ieee_archive_p (bfd *abfd)
 
   /* Ignore the return value here.  It doesn't matter if we don't read
      the entire buffer.  We might have a very small ieee file.  */
-  bfd_bread ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd);
+  if (bfd_bread ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd) <= 0)
+    goto got_wrong_format_error;
 
   ieee->h.first_byte = buffer;
   ieee->h.input_p = buffer;
@@ -1323,7 +1380,8 @@ ieee_archive_p (bfd *abfd)
   if (this_byte (&(ieee->h)) != Module_Beginning)
     goto got_wrong_format_error;
 
-  next_byte (&(ieee->h));
+  (void) next_byte (&(ieee->h));
+
   library = read_id (&(ieee->h));
   if (strcmp (library, "LIBRARY") != 0)
     goto got_wrong_format_error;
@@ -1334,7 +1392,7 @@ ieee_archive_p (bfd *abfd)
   ieee->element_count = 0;
   ieee->element_index = 0;
 
-  next_byte (&(ieee->h));	/* Drop the ad part.  */
+  (void) next_byte (&(ieee->h));	/* Drop the ad part.  */
   must_parse_int (&(ieee->h));	/* And the two dummy numbers.  */
   must_parse_int (&(ieee->h));
 
@@ -1407,8 +1465,9 @@ ieee_archive_p (bfd *abfd)
       ieee->h.first_byte = buffer;
       ieee->h.input_p = buffer;
 
-      next_byte (&(ieee->h));		/* Drop F8.  */
-      next_byte (&(ieee->h));		/* Drop 14.  */
+      (void) next_byte (&(ieee->h));	/* Drop F8.  */
+      if (! next_byte (&(ieee->h)))	/* Drop 14.  */
+	goto error_return;
       must_parse_int (&(ieee->h));	/* Drop size of block.  */
 
       if (must_parse_int (&(ieee->h)) != 0)
@@ -1467,7 +1526,8 @@ do_one (ieee_data_type *ieee,
 	unsigned int number_of_maus;
 	unsigned int i;
 
-	next_byte (&(ieee->h));
+	if (! next_byte (&(ieee->h)))
+	  return FALSE;
 	number_of_maus = must_parse_int (&(ieee->h));
 
 	for (i = 0; i < number_of_maus; i++)
@@ -1482,7 +1542,8 @@ do_one (ieee_data_type *ieee,
       {
 	bfd_boolean loop = TRUE;
 
-	next_byte (&(ieee->h));
+	if (! next_byte (&(ieee->h)))
+	  return FALSE;
 	while (loop)
 	  {
 	    switch (this_byte (&(ieee->h)))
@@ -1505,13 +1566,16 @@ do_one (ieee_data_type *ieee,
 		  *(current_map->reloc_tail_ptr) = r;
 		  current_map->reloc_tail_ptr = &r->next;
 		  r->next = (ieee_reloc_type *) NULL;
-		  next_byte (&(ieee->h));
-/*			    abort();*/
+		  if (! next_byte (&(ieee->h)))
+		    return FALSE;
+
 		  r->relent.sym_ptr_ptr = 0;
-		  parse_expression (ieee,
-				    &r->relent.addend,
-				    &r->symbol,
-				    &pcrel, &extra, &section);
+		  if (! parse_expression (ieee,
+					  &r->relent.addend,
+					  &r->symbol,
+					  &pcrel, &extra, &section))
+		    return FALSE;
+
 		  r->relent.address = current_map->pc;
 		  s->flags |= SEC_RELOC;
 		  s->owner->flags |= HAS_RELOC;
@@ -1521,7 +1585,8 @@ do_one (ieee_data_type *ieee,
 
 		  if (this_byte (&(ieee->h)) == (int) ieee_comma)
 		    {
-		      next_byte (&(ieee->h));
+		      if (! next_byte (&(ieee->h)))
+			return FALSE;
 		      /* Fetch number of bytes to pad.  */
 		      extra = must_parse_int (&(ieee->h));
 		    };
@@ -1529,13 +1594,16 @@ do_one (ieee_data_type *ieee,
 		  switch (this_byte (&(ieee->h)))
 		    {
 		    case ieee_function_signed_close_b_enum:
-		      next_byte (&(ieee->h));
+		      if (! next_byte (&(ieee->h)))
+			return FALSE;
 		      break;
 		    case ieee_function_unsigned_close_b_enum:
-		      next_byte (&(ieee->h));
+		      if (! next_byte (&(ieee->h)))
+			return FALSE;
 		      break;
 		    case ieee_function_either_close_b_enum:
-		      next_byte (&(ieee->h));
+		      if (! next_byte (&(ieee->h)))
+			return FALSE;
 		      break;
 		    default:
 		      break;
@@ -1634,7 +1702,8 @@ do_one (ieee_data_type *ieee,
 		      for (i = 0; i < this_size; i++)
 			{
 			  location_ptr[current_map->pc++] = this_byte (&(ieee->h));
-			  next_byte (&(ieee->h));
+			  if (! next_byte (&(ieee->h)))
+			    return FALSE;
 			}
 		    }
 		  else
@@ -1667,7 +1736,9 @@ ieee_slurp_section_data (bfd *abfd)
   if (ieee->read_data)
     return TRUE;
   ieee->read_data = TRUE;
-  ieee_seek (ieee, ieee->w.r.data_part);
+
+  if (! ieee_seek (ieee, ieee->w.r.data_part))
+    return FALSE;
 
   /* Allocate enough space for all the section contents.  */
   for (s = abfd->sections; s != (asection *) NULL; s = s->next)
@@ -1693,7 +1764,8 @@ ieee_slurp_section_data (bfd *abfd)
 	  return TRUE;
 
 	case ieee_set_current_section_enum:
-	  next_byte (&(ieee->h));
+	  if (! next_byte (&(ieee->h)))
+	    return FALSE;
 	  section_number = must_parse_int (&(ieee->h));
 	  s = ieee->section_table[section_number];
 	  s->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
@@ -1706,7 +1778,8 @@ ieee_slurp_section_data (bfd *abfd)
 	  break;
 
 	case ieee_e2_first_byte_enum:
-	  next_byte (&(ieee->h));
+	  if (! next_byte (&(ieee->h)))
+	    return FALSE;
 	  switch (this_byte (&(ieee->h)))
 	    {
 	    case ieee_set_current_pc_enum & 0xff:
@@ -1716,21 +1789,28 @@ ieee_slurp_section_data (bfd *abfd)
 		unsigned int extra;
 		bfd_boolean pcrel;
 
-		next_byte (&(ieee->h));
+		if (! next_byte (&(ieee->h)))
+		  return FALSE;
 		must_parse_int (&(ieee->h));	/* Throw away section #.  */
-		parse_expression (ieee, &value,
-				  &symbol,
-				  &pcrel, &extra,
-				  0);
+		if (! parse_expression (ieee, &value,
+					&symbol,
+					&pcrel, &extra,
+					0))
+		  return FALSE;
+
 		current_map->pc = value;
 		BFD_ASSERT ((unsigned) (value - s->vma) <= s->size);
 	      }
 	      break;
 
 	    case ieee_value_starting_address_enum & 0xff:
-	      next_byte (&(ieee->h));
+	      if (! next_byte (&(ieee->h)))
+		return FALSE;
 	      if (this_byte (&(ieee->h)) == ieee_function_either_open_b_enum)
-		next_byte (&(ieee->h));
+		{
+		  if (! next_byte (&(ieee->h)))
+		    return FALSE;
+		}
 	      abfd->start_address = must_parse_int (&(ieee->h));
 	      /* We've got to the end of the data now -  */
 	      return TRUE;
@@ -1748,7 +1828,8 @@ ieee_slurp_section_data (bfd *abfd)
 	    unsigned int iterations;
 	    unsigned char *start;
 
-	    next_byte (&(ieee->h));
+	    if (! next_byte (&(ieee->h)))
+	      return FALSE;
 	    iterations = must_parse_int (&(ieee->h));
 	    start = ieee->h.input_p;
 	    if (start[0] == (int) ieee_load_constant_bytes_enum
@@ -1759,9 +1840,10 @@ ieee_slurp_section_data (bfd *abfd)
 		    location_ptr[current_map->pc++] = start[2];
 		    iterations--;
 		  }
-		next_byte (&(ieee->h));
-		next_byte (&(ieee->h));
-		next_byte (&(ieee->h));
+		(void) next_byte (&(ieee->h));
+		(void) next_byte (&(ieee->h));
+		if (! next_byte (&(ieee->h)))
+		  return FALSE;
 	      }
 	    else
 	      {
@@ -1802,9 +1884,11 @@ ieee_object_p (bfd *abfd)
     goto fail;
   /* Read the first few bytes in to see if it makes sense.  Ignore
      bfd_bread return value;  The file might be very small.  */
-  bfd_bread ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd);
+  if (bfd_bread ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd) <= 0)
+    goto got_wrong_format;
 
   ieee->h.input_p = buffer;
+  ieee->h.total_amt = sizeof (buffer);
   if (this_byte_and_next (&(ieee->h)) != Module_Beginning)
     goto got_wrong_format;
 
@@ -1900,7 +1984,8 @@ ieee_object_p (bfd *abfd)
   if (this_byte (&(ieee->h)) != (int) ieee_address_descriptor_enum)
     goto fail;
 
-  next_byte (&(ieee->h));
+  if (! next_byte (&(ieee->h)))
+    goto fail;
 
   if (! parse_int (&(ieee->h), &ieee->ad.number_of_bits_mau))
     goto fail;
@@ -1911,7 +1996,10 @@ ieee_object_p (bfd *abfd)
   /* If there is a byte order info, take it.  */
   if (this_byte (&(ieee->h)) == (int) ieee_variable_L_enum
       || this_byte (&(ieee->h)) == (int) ieee_variable_M_enum)
-    next_byte (&(ieee->h));
+    {
+      if (! next_byte (&(ieee->h)))
+	goto fail;
+    }
 
   for (part = 0; part < N_W_VARIABLES; part++)
     {
@@ -1942,12 +2030,17 @@ ieee_object_p (bfd *abfd)
     goto fail;
   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
     goto fail;
+
   /* FIXME: Check return value.  I'm not sure whether it needs to read
      the entire buffer or not.  */
-  bfd_bread ((void *) (IEEE_DATA (abfd)->h.first_byte),
-	    (bfd_size_type) ieee->w.r.me_record + 1, abfd);
+  amt = bfd_bread ((void *) (IEEE_DATA (abfd)->h.first_byte),
+		   (bfd_size_type) ieee->w.r.me_record + 1, abfd);
+  if (amt <= 0)
+    goto fail;
 
-  ieee_slurp_sections (abfd);
+  IEEE_DATA (abfd)->h.total_amt = amt;
+  if (ieee_slurp_sections (abfd))
+    goto fail;
 
   if (! ieee_slurp_debug (abfd))
     goto fail;
Index: binutils-2.23.1/bfd/pei-x86_64.c
===================================================================
--- binutils-2.23.1.orig/bfd/pei-x86_64.c	2010-10-08 17:54:18.000000000 +0200
+++ binutils-2.23.1/bfd/pei-x86_64.c	2015-01-16 18:20:55.000000000 +0100
@@ -311,6 +311,7 @@ pex64_dump_xdata (FILE *file, bfd *abfd,
   bfd_vma vsize;
   bfd_byte *data = NULL;
   bfd_vma end_addr;
+  bfd_size_type sec_size;
 
   if (!section)
     section = pex64_get_section_by_rva (abfd, addr, ".data");
@@ -329,13 +330,29 @@ pex64_dump_xdata (FILE *file, bfd *abfd,
   if (!section)
     return;
 
+  sec_size = section->rawsize > 0 ? section->rawsize : section->size;
   vsize = section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
   addr -= vsize;
 
+  /* PR 17512: file: 2245-7442-0.004.  */
+  if (addr >= sec_size)
+    {
+      fprintf (file, _("warning: xdata section corrupt\n"));
+      return;
+    }
+
   if (endx)
-    end_addr = endx[0] - vsize;
+    {
+      end_addr = endx[0] - vsize;
+      /* PR 17512: file: 2245-7442-0.004.  */
+      if (end_addr > sec_size)
+	{
+	  fprintf (file, _("warning: xdata section corrupt"));
+	  end_addr = sec_size;
+	}
+    }
   else
-    end_addr = (section->rawsize != 0 ? section->rawsize : section->size);
+    end_addr = sec_size;
 
   if (bfd_malloc_and_get_section (abfd, section, &data))
     {
@@ -383,7 +400,11 @@ pex64_dump_xdata (FILE *file, bfd *abfd,
 	ui.FrameRegister == 0 ? "none"
 			      : pex_regs[(unsigned int) ui.FrameRegister]);
 
-      pex64_xdata_print_uwd_codes (file, &ui, pc_addr);
+      /* PR 17512: file: 2245-7442-0.004.  */
+      if (ui.CountOfCodes * 2 + ui.rawUnwindCodes + addr >= data + section->size)
+	fprintf (file, _("Too many unwind codes (%ld)\n"), (long) ui.CountOfCodes);
+      else
+	pex64_xdata_print_uwd_codes (file, &ui, pc_addr);
       
       /* Now we need end of this xdata block.  */
       addr += ui.SizeOfBlock;
@@ -439,6 +460,12 @@ pex64_bfd_print_pdata (bfd *abfd, void *
     return TRUE;
 
   stop = pei_section_data (abfd, section)->virt_size;
+  /* PR 17512: file: 005-181405-0.004.  */
+  if (stop == 0 || section->size == 0)
+    {
+      fprintf (file, _("No unwind data in .pdata section\n"));
+      return TRUE;
+    }
   if ((stop % onaline) != 0)
     fprintf (file,
 	     _("warning: .pdata section size (%ld) is not a multiple of %d\n"),
@@ -469,6 +496,7 @@ pex64_bfd_print_pdata (bfd *abfd, void *
 
       if (i + PDATA_ROW_SIZE > stop)
 	break;
+
       pex64_get_runtime_function (abfd, &rf, &data[i]);
 
       if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
@@ -573,6 +601,7 @@ pex64_bfd_print_pdata (bfd *abfd, void *
 		 identical pointers in the array; advance past all of them.  */
 	      while (p[0] <= rf.rva_UnwindData)
 		++p;
+
 	      if (p[0] == ~((bfd_vma) 0))
 		p = NULL;
 
Index: binutils-2.23.1/bfd/libieee.h
===================================================================
--- binutils-2.23.1.orig/bfd/libieee.h	2009-09-02 09:18:37.000000000 +0200
+++ binutils-2.23.1/bfd/libieee.h	2015-01-16 18:20:55.000000000 +0100
@@ -67,6 +67,7 @@ typedef struct {
   unsigned char *input_p;
   unsigned char *first_byte;
   unsigned char *last_byte;
+  bfd_size_type total_amt;
   bfd *abfd;
 } common_header_type ;
 
Index: binutils-2.23.1/bfd/mach-o.c
===================================================================
--- binutils-2.23.1.orig/bfd/mach-o.c	2012-07-24 23:06:58.000000000 +0200
+++ binutils-2.23.1/bfd/mach-o.c	2015-01-16 18:20:55.000000000 +0100
@@ -1070,8 +1070,11 @@ bfd_mach_o_canonicalize_one_reloc (bfd *
       else if (reloc.r_scattered
 	       || (reloc.r_type != BFD_MACH_O_GENERIC_RELOC_PAIR))
         {
+	  /* PR 17512: file: 006-2964-0.004.  */
+	  if (num >= mdata->nsects)
+	    return -1;
+	  
           BFD_ASSERT (num != 0);
-          BFD_ASSERT (num <= mdata->nsects);
           sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
           /* For a symbol defined in section S, the addend (stored in the
              binary) contains the address of the section.  To comply with
@@ -3062,10 +3065,8 @@ bfd_mach_o_read_symtab_symbols (bfd *abf
   unsigned long i;
 
   if (sym == NULL || sym->symbols)
-    {
-      /* Return now if there are no symbols or if already loaded.  */
-      return TRUE;
-    }
+    /* Return now if there are no symbols or if already loaded.  */
+    return TRUE;
 
   sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
 
@@ -3076,12 +3077,18 @@ bfd_mach_o_read_symtab_symbols (bfd *abf
     }
 
   if (!bfd_mach_o_read_symtab_strtab (abfd))
-    return FALSE;
+    {
+      sym->symbols = NULL;
+      return FALSE;
+    }
 
   for (i = 0; i < sym->nsyms; i++)
     {
       if (!bfd_mach_o_read_symtab_symbol (abfd, sym, &sym->symbols[i], i))
-	return FALSE;
+	{
+	  sym->symbols = NULL;
+	  return FALSE;
+	}
     }
 
   return TRUE;
Index: binutils-2.23.1/bfd/versados.c
===================================================================
--- binutils-2.23.1.orig/bfd/versados.c	2012-05-05 05:05:25.000000000 +0200
+++ binutils-2.23.1/bfd/versados.c	2015-01-16 18:20:55.000000000 +0100
@@ -431,7 +431,8 @@ process_otr (bfd *abfd, struct ext_otr *
       else
 	{
 	  need_contents = 1;
-	  if (dst_idx < esdid->section->size)
+	  
+	  if (esdid->section && dst_idx < esdid->section->size)
 	    if (pass == 2)
 	      {
 		/* Absolute code, comes in 16 bit lumps.  */
@@ -446,8 +447,15 @@ process_otr (bfd *abfd, struct ext_otr *
 
   if (!contents && need_contents)
     {
-      bfd_size_type size = esdid->section->size;
-      esdid->contents = bfd_alloc (abfd, size);
+      if (esdid->section)
+	{
+	  bfd_size_type size;
+
+	  size = esdid->section->size;
+	  esdid->contents = bfd_alloc (abfd, size);
+	}
+      else
+	esdid->contents = NULL;
     }
 }
 
@@ -586,6 +594,13 @@ versados_object_p (bfd *abfd)
       return NULL;
     }
 
+  /* PR 17512: file: 726-2128-0.004.  */
+  if (len < 13)
+    {
+      bfd_set_error (bfd_error_wrong_format);
+      return NULL;
+    }
+
   if (bfd_bread (&ext.type, (bfd_size_type) len, abfd) != len)
     {
       if (bfd_get_error () != bfd_error_system_call)
Index: binutils-2.23.1/bfd/vms-alpha.c
===================================================================
--- binutils-2.23.1.orig/bfd/vms-alpha.c	2011-08-04 10:13:53.000000000 +0200
+++ binutils-2.23.1/bfd/vms-alpha.c	2015-01-16 18:20:55.000000000 +0100
@@ -369,9 +369,9 @@ struct vms_section_data_struct
   ((struct vms_section_data_struct *)sec->used_by_bfd)
 
 /* To be called from the debugger.  */
-struct vms_private_data_struct *bfd_vms_get_data (bfd *abfd);
+struct vms_private_data_struct *bfd_vms_get_data (bfd *);
 
-static int vms_get_remaining_object_record (bfd *abfd, int read_so_far);
+static int vms_get_remaining_object_record (bfd *, unsigned int);
 static bfd_boolean _bfd_vms_slurp_object_records (bfd * abfd);
 static void alpha_vms_add_fixup_lp (struct bfd_link_info *, bfd *, bfd *);
 static void alpha_vms_add_fixup_ca (struct bfd_link_info *, bfd *, bfd *);
@@ -379,8 +379,8 @@ static void alpha_vms_add_fixup_qr (stru
                                     bfd_vma);
 static void alpha_vms_add_fixup_lr (struct bfd_link_info *, unsigned int,
                                     bfd_vma);
-static void alpha_vms_add_lw_reloc (struct bfd_link_info *info);
-static void alpha_vms_add_qw_reloc (struct bfd_link_info *info);
+static void alpha_vms_add_lw_reloc (struct bfd_link_info *);
+static void alpha_vms_add_qw_reloc (struct bfd_link_info *);
 
 struct vector_type
 {
@@ -793,7 +793,7 @@ _bfd_vms_get_object_record (bfd *abfd)
    Return the size of the record or 0 on failure.  */
 
 static int
-vms_get_remaining_object_record (bfd *abfd, int read_so_far)
+vms_get_remaining_object_record (bfd *abfd, unsigned int read_so_far)
 {
   unsigned int to_read;
 
@@ -829,7 +829,10 @@ vms_get_remaining_object_record (bfd *ab
         return 0;
       PRIV (recrd.buf_size) = to_read;
     }
-
+  /* PR 17512: file: 025-1974-0.004.  */
+  else if (to_read <= read_so_far)
+    return 0;
+  
   /* Read the remaining record.  */
   to_read -= read_so_far;
 
