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.
This commit is contained in:
parent
015de6884f
commit
201159ecec
@ -1,3 +1,22 @@
|
||||
2014-11-11 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
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.
|
||||
|
||||
2014-11-11 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR binutils/17512
|
||||
|
@ -4453,11 +4453,11 @@ buy_and_read (bfd *abfd, file_ptr where, bfd_size_type size)
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4637,13 +4637,20 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
|
||||
/* 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);
|
||||
}
|
||||
memcpy (lineno_cache, n_lineno_cache, amt);
|
||||
/* PR 17521: file: 078-10659-0.004. */
|
||||
if (n_cache_ptr < n_lineno_cache + asect->lineno_count)
|
||||
{
|
||||
amt = n_cache_ptr - n_lineno_cache;
|
||||
memcpy (lineno_cache, n_lineno_cache, amt * sizeof (alent));
|
||||
memset (lineno_cache + amt, 0, (asect->lineno_count - amt) * sizeof (alent));
|
||||
}
|
||||
else
|
||||
memcpy (lineno_cache, n_lineno_cache, amt);
|
||||
}
|
||||
bfd_release (abfd, func_table);
|
||||
}
|
||||
@ -5074,13 +5081,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
|
||||
|
@ -1758,15 +1758,15 @@ coff_get_normalized_symtab (bfd *abfd)
|
||||
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. */
|
||||
|
22
bfd/elf.c
22
bfd/elf.c
@ -7269,8 +7269,12 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
|
||||
|
||||
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;
|
||||
|
||||
@ -7430,8 +7434,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;
|
||||
|
||||
@ -7572,16 +7580,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
|
||||
|
@ -149,8 +149,13 @@ _bfd_XXi_swap_sym_in (bfd * abfd, void * ext1, void * in1)
|
||||
|
||||
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;
|
||||
@ -170,15 +175,22 @@ _bfd_XXi_swap_sym_in (bfd * abfd, void * ext1, void * in1)
|
||||
{
|
||||
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;
|
||||
@ -283,6 +295,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:
|
||||
@ -1681,7 +1696,9 @@ pe_print_edata (bfd * abfd, void * vfile)
|
||||
bfd_fprintf_vma (abfd, file, edt.name);
|
||||
|
||||
if ((edt.name >= adj) && (edt.name < adj + datasize))
|
||||
fprintf (file, " %s\n", data + edt.name - adj);
|
||||
fprintf (file, " %.*s\n",
|
||||
(int) (datasize - (edt.name - adj)),
|
||||
data + edt.name - adj);
|
||||
else
|
||||
fprintf (file, "(outside .edata section)\n");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user