Fix address violation errors parsing corrupt binary files.
PR 21813 binutils* rddbg.c (read_symbol_stabs_debugging_info): Check for an empty string whilst concatenating symbol names. bfd * mach-o.c (bfd_mach_o_canonicalize_relocs): Pass the base address of the relocs to the canonicalize_one_reloc routine. * mach-o.h (struct bfd_mach_o_backend_data): Update the prototype for the _bfd_mach_o_canonicalize_one_reloc field. * mach-o-arm.c (bfd_mach_o_arm_canonicalize_one_reloc): Add res_base parameter. Use to check for corrupt pair relocs. * mach-o-aarch64.c (bfd_mach_o_arm64_canonicalize_one_reloc): Likewise. * mach-o-i386.c (bfd_mach_o_i386_canonicalize_one_reloc): Likewise. * mach-o-x86-64.c (bfd_mach_o_x86_64_canonicalize_one_reloc): Likewise. * vms-alpha.c (_bfd_vms_slurp_eihd): Make sure that there is enough data in the record before attempting to parse it. (_bfd_vms_slurp_eeom): Likewise. (_bfd_vms_slurp_egsd): Check for an invalid section index. (image_set_ptr): Likewise. (alpha_vms_slurp_relocs): Likewise.
This commit is contained in:
parent
e8d84ca1b4
commit
ca4cf9b9c6
@ -1,3 +1,27 @@
|
||||
2017-07-24 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR 21813
|
||||
* mach-o.c (bfd_mach_o_canonicalize_relocs): Pass the base address
|
||||
of the relocs to the canonicalize_one_reloc routine.
|
||||
* mach-o.h (struct bfd_mach_o_backend_data): Update the prototype
|
||||
for the _bfd_mach_o_canonicalize_one_reloc field.
|
||||
* mach-o-arm.c (bfd_mach_o_arm_canonicalize_one_reloc): Add
|
||||
res_base parameter. Use to check for corrupt pair relocs.
|
||||
* mach-o-aarch64.c (bfd_mach_o_arm64_canonicalize_one_reloc):
|
||||
Likewise.
|
||||
* mach-o-i386.c (bfd_mach_o_i386_canonicalize_one_reloc):
|
||||
Likewise.
|
||||
* mach-o-x86-64.c (bfd_mach_o_x86_64_canonicalize_one_reloc):
|
||||
Likewise.
|
||||
|
||||
* vms-alpha.c (_bfd_vms_slurp_eihd): Make sure that there is
|
||||
enough data in the record before attempting to parse it.
|
||||
(_bfd_vms_slurp_eeom): Likewise.
|
||||
|
||||
(_bfd_vms_slurp_egsd): Check for an invalid section index.
|
||||
(image_set_ptr): Likewise.
|
||||
(alpha_vms_slurp_relocs): Likewise.
|
||||
|
||||
2017-07-24 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR 21803
|
||||
|
@ -149,7 +149,9 @@ static reloc_howto_type arm64_howto_table[]=
|
||||
static bfd_boolean
|
||||
bfd_mach_o_arm64_canonicalize_one_reloc (bfd * abfd,
|
||||
struct mach_o_reloc_info_external * raw,
|
||||
arelent *res, asymbol **syms)
|
||||
arelent * res,
|
||||
asymbol ** syms,
|
||||
arelent * res_base ATTRIBUTE_UNUSED)
|
||||
{
|
||||
bfd_mach_o_reloc_info reloc;
|
||||
|
||||
|
@ -149,7 +149,9 @@ static reloc_howto_type arm_howto_table[]=
|
||||
static bfd_boolean
|
||||
bfd_mach_o_arm_canonicalize_one_reloc (bfd * abfd,
|
||||
struct mach_o_reloc_info_external * raw,
|
||||
arelent *res, asymbol **syms)
|
||||
arelent * res,
|
||||
asymbol ** syms,
|
||||
arelent * res_base)
|
||||
{
|
||||
bfd_mach_o_reloc_info reloc;
|
||||
|
||||
@ -161,6 +163,9 @@ bfd_mach_o_arm_canonicalize_one_reloc (bfd *abfd,
|
||||
switch (reloc.r_type)
|
||||
{
|
||||
case BFD_MACH_O_ARM_RELOC_PAIR:
|
||||
/* PR 21813: Check for a corrupt PAIR reloc at the start. */
|
||||
if (res == res_base)
|
||||
return FALSE;
|
||||
if (reloc.r_length == 2)
|
||||
{
|
||||
res->howto = &arm_howto_table[7];
|
||||
|
@ -114,7 +114,9 @@ static reloc_howto_type i386_howto_table[]=
|
||||
static bfd_boolean
|
||||
bfd_mach_o_i386_canonicalize_one_reloc (bfd * abfd,
|
||||
struct mach_o_reloc_info_external * raw,
|
||||
arelent *res, asymbol **syms)
|
||||
arelent * res,
|
||||
asymbol ** syms,
|
||||
arelent * res_base)
|
||||
{
|
||||
bfd_mach_o_reloc_info reloc;
|
||||
|
||||
@ -126,6 +128,9 @@ bfd_mach_o_i386_canonicalize_one_reloc (bfd *abfd,
|
||||
switch (reloc.r_type)
|
||||
{
|
||||
case BFD_MACH_O_GENERIC_RELOC_PAIR:
|
||||
/* PR 21813: Check for a corrupt PAIR reloc at the start. */
|
||||
if (res == res_base)
|
||||
return FALSE;
|
||||
if (reloc.r_length == 2)
|
||||
{
|
||||
res->howto = &i386_howto_table[7];
|
||||
|
@ -122,7 +122,9 @@ static reloc_howto_type x86_64_howto_table[]=
|
||||
static bfd_boolean
|
||||
bfd_mach_o_x86_64_canonicalize_one_reloc (bfd * abfd,
|
||||
struct mach_o_reloc_info_external * raw,
|
||||
arelent *res, asymbol **syms)
|
||||
arelent * res,
|
||||
asymbol ** syms,
|
||||
arelent * res_base ATTRIBUTE_UNUSED)
|
||||
{
|
||||
bfd_mach_o_reloc_info reloc;
|
||||
|
||||
|
@ -1496,7 +1496,7 @@ bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (!(*bed->_bfd_mach_o_canonicalize_one_reloc)(abfd, &native_relocs[i],
|
||||
&res[i], syms))
|
||||
&res[i], syms, res))
|
||||
goto err;
|
||||
}
|
||||
free (native_relocs);
|
||||
|
@ -746,7 +746,7 @@ typedef struct bfd_mach_o_backend_data
|
||||
enum bfd_architecture arch;
|
||||
bfd_vma page_size;
|
||||
bfd_boolean (*_bfd_mach_o_canonicalize_one_reloc)
|
||||
(bfd *, struct mach_o_reloc_info_external *, arelent *, asymbol **);
|
||||
(bfd *, struct mach_o_reloc_info_external *, arelent *, asymbol **, arelent *);
|
||||
bfd_boolean (*_bfd_mach_o_swap_reloc_out)(arelent *, bfd_mach_o_reloc_info *);
|
||||
bfd_boolean (*_bfd_mach_o_print_thread)(bfd *, bfd_mach_o_thread_flavour *,
|
||||
void *, char *);
|
||||
|
@ -473,6 +473,14 @@ _bfd_vms_slurp_eihd (bfd *abfd, unsigned int *eisd_offset,
|
||||
|
||||
vms_debug2 ((8, "_bfd_vms_slurp_eihd\n"));
|
||||
|
||||
/* PR 21813: Check for an undersized record. */
|
||||
if (PRIV (recrd.buf_size) < sizeof (* eihd))
|
||||
{
|
||||
_bfd_error_handler (_("Corrupt EIHD record - size is too small"));
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
size = bfd_getl32 (eihd->size);
|
||||
imgtype = bfd_getl32 (eihd->imgtype);
|
||||
|
||||
@ -1312,19 +1320,38 @@ _bfd_vms_slurp_egsd (bfd *abfd)
|
||||
if (old_flags & EGSY__V_DEF)
|
||||
{
|
||||
struct vms_esdf *esdf = (struct vms_esdf *)vms_rec;
|
||||
long psindx;
|
||||
|
||||
entry->value = bfd_getl64 (esdf->value);
|
||||
if (PRIV (sections) == NULL)
|
||||
return FALSE;
|
||||
entry->section = PRIV (sections)[bfd_getl32 (esdf->psindx)];
|
||||
|
||||
psindx = bfd_getl32 (esdf->psindx);
|
||||
/* PR 21813: Check for an out of range index. */
|
||||
if (psindx < 0 || psindx >= (int) PRIV (section_count))
|
||||
{
|
||||
_bfd_error_handler (_("Corrupt EGSD record: its psindx field is too big (%#lx)"),
|
||||
psindx);
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return FALSE;
|
||||
}
|
||||
entry->section = PRIV (sections)[psindx];
|
||||
|
||||
if (old_flags & EGSY__V_NORM)
|
||||
{
|
||||
PRIV (norm_sym_count)++;
|
||||
|
||||
entry->code_value = bfd_getl64 (esdf->code_address);
|
||||
entry->code_section =
|
||||
PRIV (sections)[bfd_getl32 (esdf->ca_psindx)];
|
||||
psindx = bfd_getl32 (esdf->ca_psindx);
|
||||
/* PR 21813: Check for an out of range index. */
|
||||
if (psindx < 0 || psindx >= (int) PRIV (section_count))
|
||||
{
|
||||
_bfd_error_handler (_("Corrupt EGSD record: its psindx field is too big (%#lx)"),
|
||||
psindx);
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return FALSE;
|
||||
}
|
||||
entry->code_section = PRIV (sections)[psindx];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1351,9 +1378,20 @@ _bfd_vms_slurp_egsd (bfd *abfd)
|
||||
|
||||
if (old_flags & EGSY__V_REL)
|
||||
{
|
||||
long psindx;
|
||||
|
||||
if (PRIV (sections) == NULL)
|
||||
return FALSE;
|
||||
entry->section = PRIV (sections)[bfd_getl32 (egst->psindx)];
|
||||
psindx = bfd_getl32 (egst->psindx);
|
||||
/* PR 21813: Check for an out of range index. */
|
||||
if (psindx < 0 || psindx >= (int) PRIV (section_count))
|
||||
{
|
||||
_bfd_error_handler (_("Corrupt EGSD record: its psindx field is too big (%#lx)"),
|
||||
psindx);
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return FALSE;
|
||||
}
|
||||
entry->section = PRIV (sections)[psindx];
|
||||
}
|
||||
else
|
||||
entry->section = bfd_abs_section_ptr;
|
||||
@ -1446,6 +1484,9 @@ image_set_ptr (bfd *abfd, bfd_vma vma, int sect, struct bfd_link_info *info)
|
||||
|
||||
if (PRIV (sections) == NULL)
|
||||
return;
|
||||
if (sect < 0 || sect >= (int) PRIV (section_count))
|
||||
return;
|
||||
|
||||
sec = PRIV (sections)[sect];
|
||||
|
||||
if (info)
|
||||
@ -2450,6 +2491,14 @@ _bfd_vms_slurp_eeom (bfd *abfd)
|
||||
|
||||
vms_debug2 ((2, "EEOM\n"));
|
||||
|
||||
/* PR 21813: Check for an undersized record. */
|
||||
if (PRIV (recrd.buf_size) < sizeof (* eeom))
|
||||
{
|
||||
_bfd_error_handler (_("Corrupt EEOM record - size is too small"));
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PRIV (eom_data).eom_l_total_lps = bfd_getl32 (eeom->total_lps);
|
||||
PRIV (eom_data).eom_w_comcod = bfd_getl16 (eeom->comcod);
|
||||
if (PRIV (eom_data).eom_w_comcod > 1)
|
||||
@ -5173,7 +5222,7 @@ alpha_vms_slurp_relocs (bfd *abfd)
|
||||
}
|
||||
else if (cur_psidx >= 0)
|
||||
{
|
||||
if (PRIV (sections) == NULL)
|
||||
if (PRIV (sections) == NULL || cur_psidx >= (int) PRIV (section_count))
|
||||
return FALSE;
|
||||
reloc->sym_ptr_ptr =
|
||||
PRIV (sections)[cur_psidx]->symbol_ptr_ptr;
|
||||
|
@ -1,3 +1,9 @@
|
||||
2017-07-24 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR 21813
|
||||
* rddbg.c (read_symbol_stabs_debugging_info): Check for an empty
|
||||
string whilst concatenating symbol names.
|
||||
|
||||
2017-07-21 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* po/fr.po: Updated French translation.
|
||||
|
@ -303,7 +303,8 @@ read_symbol_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
|
||||
return FALSE;
|
||||
f = NULL;
|
||||
|
||||
while (s[strlen (s) - 1] == '\\'
|
||||
while (strlen (s) > 0
|
||||
&& s[strlen (s) - 1] == '\\'
|
||||
&& ps + 1 < symend)
|
||||
{
|
||||
char *sc, *n;
|
||||
|
Loading…
Reference in New Issue
Block a user