diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 34 | ||||
-rw-r--r-- | bfd/coffcode.h | 38 | ||||
-rw-r--r-- | bfd/mach-o.c | 54 | ||||
-rw-r--r-- | bfd/peXXigen.c | 20 | ||||
-rw-r--r-- | bfd/peicode.h | 3 | ||||
-rw-r--r-- | bfd/tekhex.c | 6 | ||||
-rw-r--r-- | bfd/versados.c | 20 |
7 files changed, 140 insertions, 35 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 3b15cef..ceb77ff 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,37 @@ +2015-01-21 Nick Clifton <nickc@redhat.com> + + PR binutils/17512 + * coffcode.h (coff_set_arch_mach_hook): Check return value from + bfd_malloc. + (coff_slurp_line_table): Return FALSE if the line number + information was corrupt. + (coff_slurp_symbol_table): Return FALSE if the symbol information + was corrupt. + * mach-o.c (bfd_mach_o_bfd_copy_private_header_data): Always + initialise the fields of the dyld_info structure. + (bfd_mach_o_build_exec_seg_command): Replace assertion with an + error message and a return value. + (bfd_mach_o_layout_commands): Change the function to boolean. + Return FALSE if the function fails. + (bfd_mach_o_build_commands): Fail if bfd_mach_o_layout_commands + fails. + (bfd_mach_o_read_command): Fail if an unrecognised command is + encountered. + * peXXigen.c (_bfd_XXi_swap_aouthdr_in): Set bfd_error if the + read fails. + (slurp_symtab): Check the return from bfd_malloc. + (_bfd_XX_bfd_copy_private_bfd_data_common): Fail if the copy + encountered an error. + (_bfd_XXi_final_link_postscript): Fail if a section could not be + copied. + * peicode.h (pe_bfd_object_p): Fail if the header could not be + swapped in. + * tekhex.c (first_phase): Fail if the section is too big. + * versados.c (struct esdid): Add content_size field. + (process_otr): Use and check the new field. + (versados_get_section_contents): Check that the section exists and + that the requested data is available. + 2015-01-20 Chung-Lin Tang <cltang@codesourcery.com> * elf32-nios2.c (elf_backend_default_execstack): Define as 0. diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 9e1c20a..181f9af 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -2073,10 +2073,14 @@ coff_mkobject_hook (bfd * abfd, #endif if ((internal_f->f_flags & F_GO32STUB) != 0) - coff->go32stub = (char *) bfd_alloc (abfd, (bfd_size_type) GO32_STUBSIZE); + { + coff->go32stub = (char *) bfd_alloc (abfd, (bfd_size_type) GO32_STUBSIZE); + if (coff->go32stub == NULL) + return NULL; + } if (coff->go32stub != NULL) memcpy (coff->go32stub, internal_f->go32stub, GO32_STUBSIZE); - + return coff; } #endif @@ -2278,6 +2282,8 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr) bfd_size_type amt = bfd_coff_symesz (abfd); buf = bfd_malloc (amt); + if (buf == NULL) + return FALSE; if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0 || bfd_bread (buf, amt, abfd) != amt) { @@ -2666,10 +2672,16 @@ coff_write_relocs (bfd * abfd, int first_undef) amt = s->reloc_count; amt *= sizeof (arelent *); p = bfd_malloc (amt); - if (p == NULL && s->reloc_count > 0) - return FALSE; - memcpy (p, s->orelocation, (size_t) amt); - qsort (p, s->reloc_count, sizeof (arelent *), compare_arelent_ptr); + if (p == NULL) + { + if (s->reloc_count > 0) + return FALSE; + } + else + { + memcpy (p, s->orelocation, (size_t) amt); + qsort (p, s->reloc_count, sizeof (arelent *), compare_arelent_ptr); + } } #endif @@ -4526,6 +4538,7 @@ coff_slurp_line_table (bfd *abfd, asection *asect) unsigned int nbr_func; LINENO *src; bfd_boolean have_func; + bfd_boolean ret = TRUE; BFD_ASSERT (asect->lineno == NULL); @@ -4575,6 +4588,7 @@ coff_slurp_line_table (bfd *abfd, asection *asect) (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"), abfd, (long) symndx, counter); cache_ptr->line_number = -1; + ret = FALSE; continue; } @@ -4587,6 +4601,7 @@ coff_slurp_line_table (bfd *abfd, asection *asect) (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"), abfd, (long) symndx, counter); cache_ptr->line_number = -1; + ret = FALSE; continue; } sym = (coff_symbol_type *) (ent->u.syment._n._n_n._n_zeroes); @@ -4599,6 +4614,7 @@ coff_slurp_line_table (bfd *abfd, asection *asect) (_("%B: warning: illegal symbol in line number entry %d"), abfd, counter); cache_ptr->line_number = -1; + ret = FALSE; continue; } @@ -4678,11 +4694,15 @@ coff_slurp_line_table (bfd *abfd, asection *asect) memcpy (lineno_cache, n_lineno_cache, amt); } + else + ret = FALSE; bfd_release (abfd, func_table); } + else + ret = FALSE; } - return TRUE; + return ret; } /* Slurp in the symbol table, converting it to generic form. Note @@ -4697,6 +4717,7 @@ coff_slurp_symbol_table (bfd * abfd) unsigned int *table_ptr; bfd_size_type amt; unsigned int number_of_symbols = 0; + bfd_boolean ret = TRUE; if (obj_symbols (abfd)) return TRUE; @@ -5017,6 +5038,7 @@ coff_slurp_symbol_table (bfd * abfd) (_("%B: Unrecognized storage class %d for %s symbol `%s'"), abfd, src->u.syment.n_sclass, dst->symbol.section->name, dst->symbol.name); + ret = FALSE; case C_EXTLAB: /* External load time label. */ case C_HIDDEN: /* Ext symbol in dmert public lib. */ dst->symbol.flags = BSF_DEBUGGING; @@ -5052,7 +5074,7 @@ coff_slurp_symbol_table (bfd * abfd) } } - return TRUE; + return ret; } /* Classify a COFF symbol. A couple of targets have globally visible diff --git a/bfd/mach-o.c b/bfd/mach-o.c index 44b12b5..e136c2d 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -690,6 +690,20 @@ bfd_mach_o_bfd_copy_private_header_data (bfd *ibfd, bfd *obfd) ody->export_size = idy->export_size; ody->export_content = idy->export_content; } + /* PR 17512L: file: 730e492d. */ + else + { + ody->rebase_size = + ody->bind_size = + ody->weak_bind_size = + ody->lazy_bind_size = + ody->export_size = 0; + ody->rebase_content = + ody->bind_content = + ody->weak_bind_content = + ody->lazy_bind_content = + ody->export_content = NULL; + } } break; @@ -2764,7 +2778,14 @@ bfd_mach_o_build_exec_seg_command (bfd *abfd, bfd_mach_o_segment_command *seg) bfd_mach_o_append_section_to_segment (seg, s); - BFD_ASSERT (s->addr >= vma); + if (s->addr < vma) + { + (*_bfd_error_handler) + (_("section address (%lx) below start of segment (%lx)"), + (unsigned long) s->addr, (unsigned long) vma); + return FALSE; + } + vma = s->addr + s->size; } @@ -2839,7 +2860,7 @@ bfd_mach_o_build_exec_seg_command (bfd *abfd, bfd_mach_o_segment_command *seg) /* Layout the commands: set commands size and offset, set ncmds and sizeofcmds fields in header. */ -static void +static bfd_boolean bfd_mach_o_layout_commands (bfd_mach_o_data_struct *mdata) { unsigned wide = mach_o_wide_p (&mdata->header); @@ -2847,6 +2868,7 @@ bfd_mach_o_layout_commands (bfd_mach_o_data_struct *mdata) ufile_ptr offset; bfd_mach_o_load_command *cmd; unsigned int align; + bfd_boolean ret = TRUE; hdrlen = wide ? BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE; align = wide ? 8 - 1 : 4 - 1; @@ -2902,6 +2924,7 @@ bfd_mach_o_layout_commands (bfd_mach_o_data_struct *mdata) (*_bfd_error_handler) (_("unable to layout unknown load command 0x%lx"), (unsigned long) cmd->type); + ret = FALSE; break; } @@ -2910,6 +2933,8 @@ bfd_mach_o_layout_commands (bfd_mach_o_data_struct *mdata) } mdata->header.sizeofcmds = offset - hdrlen; mdata->filelen = offset; + + return ret; } /* Subroutine of bfd_mach_o_build_commands: set type, name and nsects of a @@ -3044,8 +3069,7 @@ bfd_mach_o_build_commands (bfd *abfd) if (nbr_commands == 0) { /* Layout commands (well none...) and set headers command fields. */ - bfd_mach_o_layout_commands (mdata); - return TRUE; + return bfd_mach_o_layout_commands (mdata); } /* Create commands for segments (and symtabs), prepend them. */ @@ -3128,7 +3152,8 @@ bfd_mach_o_build_commands (bfd *abfd) } /* Layout commands. */ - bfd_mach_o_layout_commands (mdata); + if (! bfd_mach_o_layout_commands (mdata)) + return FALSE; /* So, now we have sized the commands and the filelen set to that. Now we can build the segment command and set the section file offsets. */ @@ -4687,21 +4712,10 @@ bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command) return FALSE; break; default: - { - static bfd_boolean unknown_set = FALSE; - static unsigned long unknown_command = 0; - - /* Prevent reams of error messages when parsing corrupt binaries. */ - if (!unknown_set) - unknown_set = TRUE; - else if (command->type == unknown_command) - break; - unknown_command = command->type; - - (*_bfd_error_handler)(_("%B: unknown load command 0x%lx"), - abfd, (unsigned long) command->type); - break; - } + command->len = 0; + (*_bfd_error_handler)(_("%B: unknown load command 0x%lx"), + abfd, (unsigned long) command->type); + return FALSE; } return TRUE; diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c index 0abe609..122ddf1 100644 --- a/bfd/peXXigen.c +++ b/bfd/peXXigen.c @@ -526,6 +526,8 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd, (*_bfd_error_handler) (_("%B: aout header specifies an invalid number of data-directory entries: %d"), abfd, a->NumberOfRvaAndSizes); + bfd_set_error (bfd_error_bad_value); + /* Paranoia: If the number is corrupt, then assume that the actual entries themselves might be corrupt as well. */ a->NumberOfRvaAndSizes = 0; @@ -2007,7 +2009,11 @@ slurp_symtab (bfd *abfd, sym_cache *psc) if (storage < 0) return NULL; if (storage) - sy = (asymbol **) bfd_malloc (storage); + { + sy = (asymbol **) bfd_malloc (storage); + if (sy == NULL) + return NULL; + } psc->symcount = bfd_canonicalize_symtab (abfd, sy); if (psc->symcount < 0) @@ -2963,8 +2969,16 @@ _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd) } if (!bfd_set_section_contents (obfd, section, data, 0, section->size)) - _bfd_error_handler (_("Failed to update file offsets in debug directory")); + { + _bfd_error_handler (_("Failed to update file offsets in debug directory")); + return FALSE; + } } + else if (section) + { + _bfd_error_handler (_("%A: Failed to read debug data section"), obfd); + return FALSE; + } } return TRUE; @@ -4475,6 +4489,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo) } free (tmp_data); } + else + result = FALSE; } } #endif diff --git a/bfd/peicode.h b/bfd/peicode.h index 92deb11..e36568a 100644 --- a/bfd/peicode.h +++ b/bfd/peicode.h @@ -1343,7 +1343,10 @@ pe_bfd_object_p (bfd * abfd) != (bfd_size_type) opt_hdr_size) return NULL; + bfd_set_error (bfd_error_no_error); bfd_coff_swap_aouthdr_in (abfd, opthdr, & internal_a); + if (bfd_get_error () != bfd_error_no_error) + return NULL; } return coff_real_object_p (abfd, internal_f.f_nscns, &internal_f, diff --git a/bfd/tekhex.c b/bfd/tekhex.c index 94b4773..63d7d8d 100644 --- a/bfd/tekhex.c +++ b/bfd/tekhex.c @@ -407,7 +407,13 @@ first_phase (bfd *abfd, int type, char *src, char * src_end) return FALSE; if (!getvalue (&src, &val, src_end)) return FALSE; + if (val < section->vma) + val = section->vma; section->size = val - section->vma; + /* PR 17512: file: objdump-s-endless-loop.tekhex. + Check for overlarge section sizes. */ + if (section->size & 0x80000000) + return FALSE; section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC; break; case '0': diff --git a/bfd/versados.c b/bfd/versados.c index 95f5f53..2540314 100644 --- a/bfd/versados.c +++ b/bfd/versados.c @@ -57,6 +57,7 @@ struct esdid { asection *section; /* Ptr to bfd version. */ unsigned char *contents; /* Used to build image. */ + bfd_size_type content_size; /* The size of the contents buffer. */ int pc; int relocs; /* Reloc count, valid end of pass 1. */ int donerel; /* Have relocs been translated. */ @@ -406,7 +407,7 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass) if (pass == 1) need_contents = TRUE; - else if (contents && dst_idx < esdid->section->size - sizeinwords * 2) + else if (contents && dst_idx < esdid->content_size - sizeinwords * 2) for (j = 0; j < sizeinwords * 2; j++) { contents[dst_idx + (sizeinwords * 2) - j - 1] = val; @@ -449,7 +450,7 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass) { need_contents = TRUE; - if (esdid->section && contents && dst_idx < esdid->section->size) + if (esdid->section && contents && dst_idx < esdid->content_size - 1) if (pass == 2) { /* Absolute code, comes in 16 bit lumps. */ @@ -472,6 +473,7 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass) size = esdid->section->size; esdid->contents = bfd_alloc (abfd, size); + esdid->content_size = size; } else esdid->contents = NULL; @@ -686,12 +688,20 @@ versados_get_section_contents (bfd *abfd, file_ptr offset, bfd_size_type count) { + struct esdid *esdid; + if (!versados_pass_2 (abfd)) return FALSE; - memcpy (location, - EDATA (abfd, section->target_index).contents + offset, - (size_t) count); + esdid = &EDATA (abfd, section->target_index); + + if (esdid->contents == NULL + || offset < 0 + || (bfd_size_type) offset > esdid->content_size + || offset + count > esdid->content_size) + return FALSE; + + memcpy (location, esdid->contents + offset, (size_t) count); return TRUE; } |