diff options
author | Nick Clifton <nickc@redhat.com> | 2014-11-26 14:11:23 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2014-11-26 14:11:23 +0000 |
commit | a11652892c18324bf3abb8b25c01475e5a18632a (patch) | |
tree | 651732ecd80594056102f5b551cc7ed6f0b5143f /bfd/versados.c | |
parent | 0cfd832fc7d4f1b5633248754dcc75fa90b5475b (diff) | |
download | fsf-binutils-gdb-a11652892c18324bf3abb8b25c01475e5a18632a.zip fsf-binutils-gdb-a11652892c18324bf3abb8b25c01475e5a18632a.tar.gz fsf-binutils-gdb-a11652892c18324bf3abb8b25c01475e5a18632a.tar.bz2 |
More fixes for memory access errors triggered by attemps to examine corrupted binaries.
PR binutils/17512
* dwarf.c (display_block): Do nothing if the block starts after
the end of the buffer.
(read_and_display_attr_value): Add range checks.
(struct Frame_Chunk): Make the ncols and ra fields unsigned.
(frame_need_space): Test for an ncols of zero.
(read_cie): Fail if the augmentation data extends off the end of
the buffer.
(display_debug_frames): Add checks for read_cie failing. Add
range checks.
* coff-h8300.c (rtype2howto): Replace abort with returning a NULL
value.
* coff-h8500.c (rtype2howto): Likewise.
* coff-tic30.c (rtype2howto): Likewise.
* coff-z80.c (rtype2howto): Likewise.
* coff-z8k.c (rtype2howto): Likewise.
* coff-ia64.c (RTYPE2HOWTO): Always return a valid howto.
* coff-m68k.c (m68k_rtype2howto): Return a NULL howto if none
could be found.
* coff-mcore.c (RTYPE2HOWTO): Add range checking.
* coff-w65.c (rtype2howto): Likewise.
* coff-we32k.c (RTYPE2HOWTO): Likewise.
* pe-mips.c (RTYPE2HOWTO): Likewise.
* coff-x86_64.c (coff_amd64_reloc): Likewise. Replace abort with
an error return.
* coffcode.h (coff_slurp_reloc_table): Allow the rel parameter to
be unused.
* coffgen.c (make_a_section_from_file): Check the length of a
section name before testing to see if it is a debug section name.
(coff_object_p): Zero out any uninitialised bytes in the opt
header.
* ecoff.c (_bfd_ecoff_slurp_symbolic_info): Test for the raw
source being empty when there are values to be processed.
(_bfd_ecoff_slurp_symbol_table): Add range check.
* mach-o.c (bfd_mach_o_canonicalize_one_reloc): Likewise.
(bfd_mach_o_mangle_sections): Move test for too many sections to
before the allocation of the section table.
(bfd_mach_o_read_symtab_strtab): If the read fails, free the
memory and nullify the symbol pointer.
* reloc.c (bfd_generic_get_relocated_section_contents): Add
handling of a bfd_reloc_notsupported return value.
* versados.c (EDATA): Add range checking.
(get_record): Likewise.
(process_otr): Check for contents being available before updating
them.
(versados_canonicalize_reloc): Add range check.
Diffstat (limited to 'bfd/versados.c')
-rw-r--r-- | bfd/versados.c | 45 |
1 files changed, 29 insertions, 16 deletions
diff --git a/bfd/versados.c b/bfd/versados.c index 2368998..1dfe748 100644 --- a/bfd/versados.c +++ b/bfd/versados.c @@ -85,8 +85,8 @@ typedef struct versados_data_struct tdata_type; #define VDATA(abfd) (abfd->tdata.versados_data) -#define EDATA(abfd, n) (abfd->tdata.versados_data->e[n]) -#define RDATA(abfd, n) (abfd->tdata.versados_data->rest[n]) +#define EDATA(abfd, n) (abfd->tdata.versados_data->e[(n) < 16 ? (n) : 0]) +#define RDATA(abfd, n) (abfd->tdata.versados_data->rest[(n) < 240 ? (n) : 0]) struct ext_otr { @@ -181,14 +181,22 @@ versados_new_symbol (bfd *abfd, return n; } -static int +static bfd_boolean get_record (bfd *abfd, union ext_any *ptr) { if (bfd_bread (&ptr->size, (bfd_size_type) 1, abfd) != 1 || (bfd_bread ((char *) ptr + 1, (bfd_size_type) ptr->size, abfd) != ptr->size)) - return 0; - return 1; + return FALSE; + + { + bfd_size_type amt = ptr->size + 1; + + if (amt < sizeof (* ptr)) + memset ((char *) ptr + amt, 0, sizeof (* ptr) - amt); + } + + return TRUE; } static int @@ -366,7 +374,7 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass) struct esdid *esdid = &EDATA (abfd, otr->esdid - 1); unsigned char *contents = esdid->contents; - int need_contents = 0; + bfd_boolean need_contents = FALSE; unsigned int dst_idx = esdid->pc; for (shift = ((unsigned long) 1 << 31); shift && srcp < endp; shift >>= 1) @@ -390,8 +398,8 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass) int val = get_offset (offsetlen, srcp + esdids); if (pass == 1) - need_contents = 1; - else + need_contents = TRUE; + else if (contents) for (j = 0; j < sizeinwords * 2; j++) { contents[dst_idx + (sizeinwords * 2) - j - 1] = val; @@ -429,19 +437,21 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass) } else { - need_contents = 1; - - if (esdid->section && dst_idx < esdid->section->size) + need_contents = TRUE; + + if (esdid->section && contents && dst_idx < esdid->section->size) if (pass == 2) { /* Absolute code, comes in 16 bit lumps. */ contents[dst_idx] = srcp[0]; contents[dst_idx + 1] = srcp[1]; } + dst_idx += 2; srcp += 2; } } + EDATA (abfd, otr->esdid - 1).pc = dst_idx; if (!contents && need_contents) @@ -461,7 +471,7 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass) static bfd_boolean versados_scan (bfd *abfd) { - int loop = 1; + bfd_boolean loop = TRUE; int i; int j; int nsecs = 0; @@ -479,13 +489,13 @@ versados_scan (bfd *abfd) union ext_any any; if (!get_record (abfd, &any)) - return TRUE; + return FALSE; switch (any.header.type) { case VHEADER: break; case VEND: - loop = 0; + loop = FALSE; break; case VESTDEF: process_esd (abfd, &any.esd, 1); @@ -512,7 +522,6 @@ versados_scan (bfd *abfd) { amt = (bfd_size_type) esdid->relocs * sizeof (arelent); esdid->section->relocation = bfd_alloc (abfd, amt); - esdid->pc = 0; if (esdid->contents) @@ -571,7 +580,7 @@ versados_scan (bfd *abfd) VDATA (abfd)->ref_idx = 0; - return 1; + return TRUE; } /* Check whether an existing file is a versados file. */ @@ -773,6 +782,7 @@ versados_canonicalize_reloc (bfd *abfd, versados_pass_2 (abfd); src = section->relocation; + if (!EDATA (abfd, section->target_index).donerel) { EDATA (abfd, section->target_index).donerel = 1; @@ -790,6 +800,9 @@ versados_canonicalize_reloc (bfd *abfd, src[count].sym_ptr_ptr = e->section->symbol_ptr_ptr; } + /* PR 17512: file:3757-2936-0.004. */ + else if ((unsigned) (esdid - ES_BASE) >= bfd_get_symcount (abfd)) + src[count].sym_ptr_ptr = bfd_und_section_ptr->symbol_ptr_ptr; else src[count].sym_ptr_ptr = symbols + esdid - ES_BASE; } |