mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-28 06:20:30 +00:00
More fixes for invalid memory accesses triggered by fuzzed binaries.
PR binutils/17512 * nm.c (print_symbol): Add 'is_synthetic' parameter. Use it to help initialize the info.elfinfo field. (print_size_symbols): Add 'synth_count' parameter. Use it to set the is_synthetic parameter when calling print_symbol. (print_symbols): Likewise. (display_rel_file): Pass synth_count to printing function. (display_archive): Break loop if the last archive displayed matches the current archive. * size.c (display_archive): Likewise. * archive.c (do_slurp_bsd_armap): Make sure that the parsed sized is at least big enough for the header to be read. * elf32-i386.c (elf_i386_get_plt_sym_val): Skip unknown relocs. * mach-o.c (bfd_mach_o_get_synthetic_symtab): Add range checks. (bfd_mach_o_read_command): Prevetn duplicate error messages about unrecognized commands. * syms.c (_bfd_stab_section_find_nearest_line): Add range checks when indexing into the string table.
This commit is contained in:
parent
82b1b41bcd
commit
896ca09813
@ -1,3 +1,15 @@
|
||||
2015-01-05 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR binutils/17512
|
||||
* archive.c (do_slurp_bsd_armap): Make sure that the parsed sized
|
||||
is at least big enough for the header to be read.
|
||||
* elf32-i386.c (elf_i386_get_plt_sym_val): Skip unknown relocs.
|
||||
* mach-o.c (bfd_mach_o_get_synthetic_symtab): Add range checks.
|
||||
(bfd_mach_o_read_command): Prevetn duplicate error messages about
|
||||
unrecognized commands.
|
||||
* syms.c (_bfd_stab_section_find_nearest_line): Add range checks
|
||||
when indexing into the string table.
|
||||
|
||||
2015-01-01 Alan Modra <amodra@gmail.com>
|
||||
|
||||
Update year range in copyright notice of all files.
|
||||
|
@ -903,7 +903,8 @@ do_slurp_bsd_armap (bfd *abfd)
|
||||
parsed_size = mapdata->parsed_size;
|
||||
free (mapdata);
|
||||
/* PR 17512: file: 883ff754. */
|
||||
if (parsed_size == 0)
|
||||
/* PR 17512: file: 0458885f. */
|
||||
if (parsed_size < 4)
|
||||
return FALSE;
|
||||
|
||||
raw_armap = (bfd_byte *) bfd_zalloc (abfd, parsed_size);
|
||||
|
@ -5194,8 +5194,9 @@ bad_return:
|
||||
{
|
||||
long reloc_index;
|
||||
|
||||
if (p->howto->type != R_386_JUMP_SLOT
|
||||
&& p->howto->type != R_386_IRELATIVE)
|
||||
if (p->howto == NULL /* PR 17512: file: bc9d6cf5. */
|
||||
|| (p->howto->type != R_386_JUMP_SLOT
|
||||
&& p->howto->type != R_386_IRELATIVE))
|
||||
continue;
|
||||
|
||||
reloc_index = H_GET_32 (abfd, (plt_contents + plt_offset
|
||||
|
@ -1214,10 +1214,9 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
|
||||
for (isym = isymbuf + 1, sym = symbase; isym < isymend; isym++, sym++)
|
||||
{
|
||||
memcpy (&sym->internal_elf_sym, isym, sizeof (Elf_Internal_Sym));
|
||||
|
||||
sym->symbol.the_bfd = abfd;
|
||||
|
||||
sym->symbol.name = bfd_elf_sym_name (abfd, hdr, isym, NULL);
|
||||
|
||||
sym->symbol.value = isym->st_value;
|
||||
|
||||
if (isym->st_shndx == SHN_UNDEF)
|
||||
|
61
bfd/mach-o.c
61
bfd/mach-o.c
@ -790,18 +790,19 @@ bfd_mach_o_get_synthetic_symtab (bfd *abfd,
|
||||
bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
|
||||
bfd_mach_o_symtab_command *symtab = mdata->symtab;
|
||||
asymbol *s;
|
||||
char * s_start;
|
||||
char * s_end;
|
||||
unsigned long count, i, j, n;
|
||||
size_t size;
|
||||
char *names;
|
||||
char *nul_name;
|
||||
const char stub [] = "$stub";
|
||||
|
||||
*ret = NULL;
|
||||
|
||||
/* Stop now if no symbols or no indirect symbols. */
|
||||
if (dysymtab == NULL || symtab == NULL || symtab->symbols == NULL)
|
||||
return 0;
|
||||
|
||||
if (dysymtab->nindirectsyms == 0)
|
||||
if (dysymtab == NULL || dysymtab->nindirectsyms == 0
|
||||
|| symtab == NULL || symtab->symbols == NULL)
|
||||
return 0;
|
||||
|
||||
/* We need to allocate a bfd symbol for every indirect symbol and to
|
||||
@ -811,19 +812,23 @@ bfd_mach_o_get_synthetic_symtab (bfd *abfd,
|
||||
|
||||
for (j = 0; j < count; j++)
|
||||
{
|
||||
const char * strng;
|
||||
unsigned int isym = dysymtab->indirect_syms[j];
|
||||
|
||||
/* Some indirect symbols are anonymous. */
|
||||
if (isym < symtab->nsyms && symtab->symbols[isym].symbol.name)
|
||||
size += strlen (symtab->symbols[isym].symbol.name) + sizeof ("$stub");
|
||||
if (isym < symtab->nsyms && (strng = symtab->symbols[isym].symbol.name))
|
||||
/* PR 17512: file: f5b8eeba. */
|
||||
size += strnlen (strng, symtab->strsize - (strng - symtab->strtab)) + sizeof (stub);
|
||||
}
|
||||
|
||||
s = *ret = (asymbol *) bfd_malloc (size);
|
||||
s_start = bfd_malloc (size);
|
||||
s = *ret = (asymbol *) s_start;
|
||||
if (s == NULL)
|
||||
return -1;
|
||||
names = (char *) (s + count);
|
||||
nul_name = names;
|
||||
*names++ = 0;
|
||||
s_end = s_start + size;
|
||||
|
||||
n = 0;
|
||||
for (i = 0; i < mdata->nsects; i++)
|
||||
@ -843,10 +848,19 @@ bfd_mach_o_get_synthetic_symtab (bfd *abfd,
|
||||
last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
|
||||
addr = sec->addr;
|
||||
entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
|
||||
|
||||
/* PR 17512: file: 08e15eec. */
|
||||
if (first >= count || last >= count || first > last)
|
||||
goto fail;
|
||||
|
||||
for (j = first; j < last; j++)
|
||||
{
|
||||
unsigned int isym = dysymtab->indirect_syms[j];
|
||||
|
||||
/* PR 17512: file: 04d64d9b. */
|
||||
if (((char *) s) + sizeof (* s) > s_end)
|
||||
goto fail;
|
||||
|
||||
s->flags = BSF_GLOBAL | BSF_SYNTHETIC;
|
||||
s->section = sec->bfdsection;
|
||||
s->value = addr - sec->addr;
|
||||
@ -860,10 +874,16 @@ bfd_mach_o_get_synthetic_symtab (bfd *abfd,
|
||||
|
||||
s->name = names;
|
||||
len = strlen (sym);
|
||||
/* PR 17512: file: 47dfd4d2. */
|
||||
if (names + len >= s_end)
|
||||
goto fail;
|
||||
memcpy (names, sym, len);
|
||||
names += len;
|
||||
memcpy (names, "$stub", sizeof ("$stub"));
|
||||
names += sizeof ("$stub");
|
||||
/* PR 17512: file: 18f340a4. */
|
||||
if (names + sizeof (stub) >= s_end)
|
||||
goto fail;
|
||||
memcpy (names, stub, sizeof (stub));
|
||||
names += sizeof (stub);
|
||||
}
|
||||
else
|
||||
s->name = nul_name;
|
||||
@ -879,6 +899,11 @@ bfd_mach_o_get_synthetic_symtab (bfd *abfd,
|
||||
}
|
||||
|
||||
return n;
|
||||
|
||||
fail:
|
||||
free (s_start);
|
||||
* ret = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
@ -4660,9 +4685,21 @@ bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
|
||||
return FALSE;
|
||||
break;
|
||||
default:
|
||||
(*_bfd_error_handler)(_("%B: unknown load command 0x%lx"),
|
||||
abfd, (unsigned long) command->type);
|
||||
break;
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
12
bfd/syms.c
12
bfd/syms.c
@ -823,6 +823,7 @@ _bfd_generic_read_minisymbols (bfd *abfd,
|
||||
|
||||
*minisymsp = syms;
|
||||
*sizep = sizeof (asymbol *);
|
||||
|
||||
return symcount;
|
||||
|
||||
error_return:
|
||||
@ -1191,6 +1192,8 @@ _bfd_stab_section_find_nearest_line (bfd *abfd,
|
||||
{
|
||||
nul_fun = stab;
|
||||
nul_str = str;
|
||||
if (file_name >= (char *) info->strs + strsize)
|
||||
file_name = NULL;
|
||||
if (stab + STABSIZE + TYPEOFF < info->stabs + stabsize
|
||||
&& *(stab + STABSIZE + TYPEOFF) == (bfd_byte) N_SO)
|
||||
{
|
||||
@ -1200,6 +1203,8 @@ _bfd_stab_section_find_nearest_line (bfd *abfd,
|
||||
directory_name = file_name;
|
||||
file_name = ((char *) str
|
||||
+ bfd_get_32 (abfd, stab + STRDXOFF));
|
||||
if (file_name >= (char *) info->strs + strsize)
|
||||
file_name = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1207,6 +1212,9 @@ _bfd_stab_section_find_nearest_line (bfd *abfd,
|
||||
case N_SOL:
|
||||
/* The name of an include file. */
|
||||
file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
|
||||
/* PR 17512: file: 0c680a1f. */
|
||||
if (file_name >= (char *) info->strs + strsize)
|
||||
file_name = NULL;
|
||||
break;
|
||||
|
||||
case N_FUN:
|
||||
@ -1214,6 +1222,8 @@ _bfd_stab_section_find_nearest_line (bfd *abfd,
|
||||
function_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
|
||||
if (function_name == (char *) str)
|
||||
continue;
|
||||
if (function_name >= (char *) info->strs + strsize)
|
||||
function_name = NULL;
|
||||
|
||||
nul_fun = NULL;
|
||||
info->indextable[i].val = bfd_get_32 (abfd, stab + VALOFF);
|
||||
@ -1321,6 +1331,8 @@ _bfd_stab_section_find_nearest_line (bfd *abfd,
|
||||
if (val <= offset)
|
||||
{
|
||||
file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
|
||||
if (file_name >= (char *) info->strs + strsize)
|
||||
file_name = NULL;
|
||||
*pline = 0;
|
||||
}
|
||||
break;
|
||||
|
@ -1,3 +1,16 @@
|
||||
2015-01-05 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR binutils/17512
|
||||
* nm.c (print_symbol): Add 'is_synthetic' parameter. Use it to
|
||||
help initialize the info.elfinfo field.
|
||||
(print_size_symbols): Add 'synth_count' parameter. Use it to set
|
||||
the is_synthetic parameter when calling print_symbol.
|
||||
(print_symbols): Likewise.
|
||||
(display_rel_file): Pass synth_count to printing function.
|
||||
(display_archive): Break loop if the last archive displayed
|
||||
matches the current archive.
|
||||
* size.c (display_archive): Likewise.
|
||||
|
||||
2015-01-05 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR binutils/17531
|
||||
|
@ -806,7 +806,11 @@ get_relocs (bfd *abfd, asection *sec, void *dataarg)
|
||||
/* Print a single symbol. */
|
||||
|
||||
static void
|
||||
print_symbol (bfd *abfd, asymbol *sym, bfd_vma ssize, bfd *archive_bfd)
|
||||
print_symbol (bfd * abfd,
|
||||
asymbol * sym,
|
||||
bfd_vma ssize,
|
||||
bfd * archive_bfd,
|
||||
bfd_boolean is_synthetic)
|
||||
{
|
||||
symbol_info syminfo;
|
||||
struct extended_symbol_info info;
|
||||
@ -816,12 +820,12 @@ print_symbol (bfd *abfd, asymbol *sym, bfd_vma ssize, bfd *archive_bfd)
|
||||
format->print_symbol_filename (archive_bfd, abfd);
|
||||
|
||||
bfd_get_symbol_info (abfd, sym, &syminfo);
|
||||
|
||||
info.sinfo = &syminfo;
|
||||
info.ssize = ssize;
|
||||
if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
|
||||
info.elfinfo = (elf_symbol_type *) sym;
|
||||
else
|
||||
info.elfinfo = NULL;
|
||||
/* Synthetic symbols do not have a full elf_symbol_type set of data available. */
|
||||
info.elfinfo = is_synthetic ? NULL : elf_symbol_from (abfd, sym);
|
||||
|
||||
format->print_symbol_info (&info, abfd);
|
||||
|
||||
if (line_numbers)
|
||||
@ -941,12 +945,17 @@ print_symbol (bfd *abfd, asymbol *sym, bfd_vma ssize, bfd *archive_bfd)
|
||||
/* Print the symbols when sorting by size. */
|
||||
|
||||
static void
|
||||
print_size_symbols (bfd *abfd, bfd_boolean is_dynamic,
|
||||
struct size_sym *symsizes, long symcount,
|
||||
bfd *archive_bfd)
|
||||
print_size_symbols (bfd * abfd,
|
||||
bfd_boolean is_dynamic,
|
||||
struct size_sym * symsizes,
|
||||
long symcount,
|
||||
long synth_count,
|
||||
bfd * archive_bfd)
|
||||
{
|
||||
asymbol *store;
|
||||
struct size_sym *from, *fromend;
|
||||
struct size_sym *from;
|
||||
struct size_sym *fromend;
|
||||
struct size_sym *fromsynth;
|
||||
|
||||
store = bfd_make_empty_symbol (abfd);
|
||||
if (store == NULL)
|
||||
@ -954,6 +963,8 @@ print_size_symbols (bfd *abfd, bfd_boolean is_dynamic,
|
||||
|
||||
from = symsizes;
|
||||
fromend = from + symcount;
|
||||
fromsynth = symsizes + (symcount - synth_count);
|
||||
|
||||
for (; from < fromend; from++)
|
||||
{
|
||||
asymbol *sym;
|
||||
@ -962,20 +973,34 @@ print_size_symbols (bfd *abfd, bfd_boolean is_dynamic,
|
||||
if (sym == NULL)
|
||||
bfd_fatal (bfd_get_filename (abfd));
|
||||
|
||||
print_symbol (abfd, sym, from->size, archive_bfd);
|
||||
print_symbol (abfd, sym, from->size, archive_bfd, from >= fromsynth);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Print the symbols. If ARCHIVE_BFD is non-NULL, it is the archive
|
||||
containing ABFD. */
|
||||
/* Print the symbols of ABFD that are held in MINISYMS.
|
||||
|
||||
If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD.
|
||||
|
||||
SYMCOUNT is the number of symbols in MINISYMS and SYNTH_COUNT
|
||||
is the number of these that are synthetic. Synthetic symbols,
|
||||
if any are present, always come at the end of the MINISYMS.
|
||||
|
||||
SIZE is the size of a symbol in MINISYMS. */
|
||||
|
||||
static void
|
||||
print_symbols (bfd *abfd, bfd_boolean is_dynamic, void *minisyms, long symcount,
|
||||
unsigned int size, bfd *archive_bfd)
|
||||
print_symbols (bfd * abfd,
|
||||
bfd_boolean is_dynamic,
|
||||
void * minisyms,
|
||||
long symcount,
|
||||
long synth_count,
|
||||
unsigned int size,
|
||||
bfd * archive_bfd)
|
||||
{
|
||||
asymbol *store;
|
||||
bfd_byte *from, *fromend;
|
||||
bfd_byte *from;
|
||||
bfd_byte *fromend;
|
||||
bfd_byte *fromsynth;
|
||||
|
||||
store = bfd_make_empty_symbol (abfd);
|
||||
if (store == NULL)
|
||||
@ -983,6 +1008,8 @@ print_symbols (bfd *abfd, bfd_boolean is_dynamic, void *minisyms, long symcount,
|
||||
|
||||
from = (bfd_byte *) minisyms;
|
||||
fromend = from + symcount * size;
|
||||
fromsynth = (bfd_byte *) minisyms + ((symcount - synth_count) * size);
|
||||
|
||||
for (; from < fromend; from += size)
|
||||
{
|
||||
asymbol *sym;
|
||||
@ -991,7 +1018,7 @@ print_symbols (bfd *abfd, bfd_boolean is_dynamic, void *minisyms, long symcount,
|
||||
if (sym == NULL)
|
||||
bfd_fatal (bfd_get_filename (abfd));
|
||||
|
||||
print_symbol (abfd, sym, (bfd_vma) 0, archive_bfd);
|
||||
print_symbol (abfd, sym, (bfd_vma) 0, archive_bfd, from >= fromsynth);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1001,6 +1028,7 @@ static void
|
||||
display_rel_file (bfd *abfd, bfd *archive_bfd)
|
||||
{
|
||||
long symcount;
|
||||
long synth_count = 0;
|
||||
void *minisyms;
|
||||
unsigned int size;
|
||||
struct size_sym *symsizes;
|
||||
@ -1031,11 +1059,10 @@ display_rel_file (bfd *abfd, bfd *archive_bfd)
|
||||
non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (show_synthetic && size == sizeof (asymbol *))
|
||||
{
|
||||
asymbol *synthsyms;
|
||||
long synth_count;
|
||||
asymbol **static_syms = NULL;
|
||||
asymbol **dyn_syms = NULL;
|
||||
long static_count = 0;
|
||||
@ -1061,6 +1088,7 @@ display_rel_file (bfd *abfd, bfd *archive_bfd)
|
||||
bfd_fatal (bfd_get_filename (abfd));
|
||||
}
|
||||
}
|
||||
|
||||
synth_count = bfd_get_synthetic_symtab (abfd, static_count, static_syms,
|
||||
dyn_count, dyn_syms, &synthsyms);
|
||||
if (synth_count > 0)
|
||||
@ -1106,9 +1134,9 @@ display_rel_file (bfd *abfd, bfd *archive_bfd)
|
||||
}
|
||||
|
||||
if (! sort_by_size)
|
||||
print_symbols (abfd, dynamic, minisyms, symcount, size, archive_bfd);
|
||||
print_symbols (abfd, dynamic, minisyms, symcount, synth_count, size, archive_bfd);
|
||||
else
|
||||
print_size_symbols (abfd, dynamic, symsizes, symcount, archive_bfd);
|
||||
print_size_symbols (abfd, dynamic, symsizes, symcount, synth_count, archive_bfd);
|
||||
|
||||
free (minisyms);
|
||||
free (symsizes);
|
||||
@ -1181,6 +1209,8 @@ display_archive (bfd *file)
|
||||
bfd_close (last_arfile);
|
||||
lineno_cache_bfd = NULL;
|
||||
lineno_cache_rel_bfd = NULL;
|
||||
if (arfile == last_arfile)
|
||||
return;
|
||||
}
|
||||
last_arfile = arfile;
|
||||
}
|
||||
@ -1434,7 +1464,6 @@ print_symbol_info_bsd (struct extended_symbol_info *info, bfd *abfd)
|
||||
print_value (abfd, SYM_SIZE (info));
|
||||
else
|
||||
print_value (abfd, SYM_VALUE (info));
|
||||
|
||||
if (print_size && SYM_SIZE (info))
|
||||
{
|
||||
printf (" ");
|
||||
|
@ -365,7 +365,14 @@ display_archive (bfd *file)
|
||||
display_bfd (arfile);
|
||||
|
||||
if (last_arfile != NULL)
|
||||
bfd_close (last_arfile);
|
||||
{
|
||||
bfd_close (last_arfile);
|
||||
|
||||
/* PR 17512: file: a244edbc. */
|
||||
if (last_arfile == arfile)
|
||||
return;
|
||||
}
|
||||
|
||||
last_arfile = arfile;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user