diff options
author | Nick Clifton <nickc@redhat.com> | 2015-02-26 21:32:04 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2015-02-26 21:32:04 +0000 |
commit | c86934ceee0971a04bbfc145c7b9a53357c25c91 (patch) | |
tree | 3507e8637f28e853d3f611db5a83fd03c9f33866 | |
parent | 9beb7c4e1d403e1374096df3a16607132a8cfe84 (diff) | |
download | binutils-c86934ceee0971a04bbfc145c7b9a53357c25c91.zip binutils-c86934ceee0971a04bbfc145c7b9a53357c25c91.tar.gz binutils-c86934ceee0971a04bbfc145c7b9a53357c25c91.tar.bz2 |
Fixes illegal memory access errors and arithmetic overflows when running strip on fuzzed binaries.
PR binutils/17512
* coffcode.h (coff_compute_section_file_positions): Report
negative page sizes.
* elf.c (elf_fake_sections): Handle excessive alignmment powers.
(assign_file_positions_for_non_load_sections): Replace assertion
with an error message.
(rewrite_elf_program_header): Handle excessive segment
alignments.
* mach-o.c (bfd_mach_o_read_section_32): Likewise.
(bfd_mach_o_read_section_64): Likewise.
* peXXigen.c (_bfd_XX_bfd_copy_private_bfd_data_common): Use %B to
print a bfd name, not %A.
-rw-r--r-- | bfd/ChangeLog | 15 | ||||
-rw-r--r-- | bfd/coffcode.h | 9 | ||||
-rw-r--r-- | bfd/elf.c | 32 | ||||
-rw-r--r-- | bfd/mach-o.c | 13 | ||||
-rw-r--r-- | bfd/peXXigen.c | 4 |
5 files changed, 67 insertions, 6 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index c2f114a..3916116 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +2015-02-26 Nick Clifton <nickc@redhat.com> + + PR binutils/17512 + * coffcode.h (coff_compute_section_file_positions): Report + negative page sizes. + * elf.c (elf_fake_sections): Handle excessive alignmment powers. + (assign_file_positions_for_non_load_sections): Replace assertion + with an error message. + (rewrite_elf_program_header): Handle excessive segment + alignments. + * mach-o.c (bfd_mach_o_read_section_32): Likewise. + (bfd_mach_o_read_section_64): Likewise. + * peXXigen.c (_bfd_XX_bfd_copy_private_bfd_data_common): Use %B to + print a bfd name, not %A. + 2015-02-26 Alan Modra <amodra@gmail.com> * elf64-ppc.c (plt_stub_size, build_plt_stub): Don't build diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 0ac4ce0..8576c0a 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -3170,6 +3170,15 @@ coff_compute_section_file_positions (bfd * abfd) This repairs 'ld -r' for arm-wince-pe target. */ if (page_size == 0) page_size = 1; + + /* PR 17512: file: 0ac816d3. */ + if (page_size < 0) + { + bfd_set_error (bfd_error_file_too_big); + (*_bfd_error_handler) + (_("%B: page size is too large (0x%x)"), abfd, page_size); + return FALSE; + } } else page_size = PE_DEF_FILE_ALIGNMENT; @@ -2758,6 +2758,15 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg) this_hdr->sh_offset = 0; this_hdr->sh_size = asect->size; this_hdr->sh_link = 0; + /* PR 17512: file: 0eb809fe, 8b0535ee. */ + if (asect->alignment_power >= (sizeof (bfd_vma) * 8) - 1) + { + (*_bfd_error_handler) + (_("%B: error: Alignment power %d of section `%A' is too big"), + abfd, asect, asect->alignment_power); + arg->failed = TRUE; + return; + } this_hdr->sh_addralign = (bfd_vma) 1 << asect->alignment_power; /* The sh_entsize and sh_info fields may have been set already by copy_private_section_data. */ @@ -5211,7 +5220,14 @@ assign_file_positions_for_non_load_sections (bfd *abfd, && (p->p_type != PT_NOTE || bfd_get_format (abfd) != bfd_core)) { - BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs); + if (m->includes_filehdr || m->includes_phdrs) + { + /* PR 17512: file: 2195325e. */ + (*_bfd_error_handler) + (_("%B: warning: non-load segment includes file header and/or program header"), + abfd); + return FALSE; + } p->p_filesz = 0; p->p_offset = m->sections[0]->filepos; @@ -5952,8 +5968,8 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) something. They are allowed by the ELF spec however, so only a warning is produced. */ if (segment->p_type == PT_LOAD) - (*_bfd_error_handler) (_("%B: warning: Empty loadable segment" - " detected, is this intentional ?\n"), + (*_bfd_error_handler) (_("\ +%B: warning: Empty loadable segment detected, is this intentional ?"), ibfd); map->count = 0; @@ -6566,7 +6582,15 @@ rewrite: i++, segment++) if (segment->p_type == PT_LOAD && maxpagesize < segment->p_align) - maxpagesize = segment->p_align; + { + /* PR 17512: file: f17299af. */ + if (segment->p_align > (bfd_vma) 1 << ((sizeof (bfd_vma) * 8) - 2)) + (*_bfd_error_handler) (_("\ +%B: warning: segment alignment of 0x%llx is too large"), + ibfd, (long long) segment->p_align); + else + maxpagesize = segment->p_align; + } if (maxpagesize != get_elf_backend_data (obfd)->maxpagesize) bfd_emul_set_maxpagesize (bfd_get_target (obfd), maxpagesize); diff --git a/bfd/mach-o.c b/bfd/mach-o.c index 955685f..010a076 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -3469,6 +3469,13 @@ bfd_mach_o_read_section_32 (bfd *abfd, section->size = bfd_h_get_32 (abfd, raw.size); section->offset = bfd_h_get_32 (abfd, raw.offset); section->align = bfd_h_get_32 (abfd, raw.align); + /* PR 17512: file: 0017eb76. */ + if (section->align > 64) + { + (*_bfd_error_handler) (_("bfd_mach_o_read_section_32: overlarge alignment value: 0x%x, using 32 instead"), + section->align); + section->align = 32; + } section->reloff = bfd_h_get_32 (abfd, raw.reloff); section->nreloc = bfd_h_get_32 (abfd, raw.nreloc); section->flags = bfd_h_get_32 (abfd, raw.flags); @@ -3508,6 +3515,12 @@ bfd_mach_o_read_section_64 (bfd *abfd, section->size = bfd_h_get_64 (abfd, raw.size); section->offset = bfd_h_get_32 (abfd, raw.offset); section->align = bfd_h_get_32 (abfd, raw.align); + if (section->align > 64) + { + (*_bfd_error_handler) (_("bfd_mach_o_read_section_64: overlarge alignment value: 0x%x, using 32 instead"), + section->align); + section->align = 32; + } section->reloff = bfd_h_get_32 (abfd, raw.reloff); section->nreloc = bfd_h_get_32 (abfd, raw.nreloc); section->flags = bfd_h_get_32 (abfd, raw.flags); diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c index c13c3ff..6aa18ca 100644 --- a/bfd/peXXigen.c +++ b/bfd/peXXigen.c @@ -2955,7 +2955,7 @@ _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd) if (ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size + (addr - section->vma) > bfd_get_section_size (section)) { - _bfd_error_handler (_("%A: Data Directory size (%lx) exceeds space left in section (%lx)"), + _bfd_error_handler (_("%B: Data Directory size (%lx) exceeds space left in section (%lx)"), obfd, ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size, bfd_get_section_size (section) - (addr - section->vma)); return FALSE; @@ -2991,7 +2991,7 @@ _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd) } else if (section) { - _bfd_error_handler (_("%A: Failed to read debug data section"), obfd); + _bfd_error_handler (_("%B: Failed to read debug data section"), obfd); return FALSE; } } |