Fix address violation issues encountered when parsing corrupt binaries.
PR 21840 * mach-o.c (bfd_mach_o_read_symtab_strtab): Fail if the symtab size is -1. * nlmcode.h (nlm_swap_auxiliary_headers_in): Replace assertion with error return. * section.c (bfd_make_section_with_flags): Fail if the name or bfd are NULL. * vms-alpha.c (bfd_make_section_with_flags): Correct computation of end pointer. (evax_bfd_print_emh): Check for invalid string lengths.
This commit is contained in:
parent
63d4980d60
commit
8bdf0be19d
|
@ -1,3 +1,16 @@
|
|||
2017-07-27 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR 21840
|
||||
* mach-o.c (bfd_mach_o_read_symtab_strtab): Fail if the symtab
|
||||
size is -1.
|
||||
* nlmcode.h (nlm_swap_auxiliary_headers_in): Replace assertion
|
||||
with error return.
|
||||
* section.c (bfd_make_section_with_flags): Fail if the name or bfd
|
||||
are NULL.
|
||||
* vms-alpha.c (bfd_make_section_with_flags): Correct computation
|
||||
of end pointer.
|
||||
(evax_bfd_print_emh): Check for invalid string lengths.
|
||||
|
||||
2017-07-25 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* po/fr.po: Updated French translation.
|
||||
|
|
|
@ -3749,6 +3749,9 @@ bfd_mach_o_read_symtab_strtab (bfd *abfd)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* See PR 21840 for a reproducer. */
|
||||
if ((sym->strsize + 1) == 0)
|
||||
return FALSE;
|
||||
sym->strtab = bfd_alloc (abfd, sym->strsize + 1);
|
||||
if (sym->strtab == NULL)
|
||||
return FALSE;
|
||||
|
|
|
@ -351,7 +351,9 @@ nlm_swap_auxiliary_headers_in (bfd *abfd)
|
|||
bfd_byte *contents;
|
||||
bfd_byte *p, *pend;
|
||||
|
||||
BFD_ASSERT (hdrLength == 0 && hdr == NULL);
|
||||
/* See PR 21840 for a reproducer. */
|
||||
if (hdrLength != 0 || hdr != NULL)
|
||||
return FALSE;
|
||||
|
||||
pos = bfd_tell (abfd);
|
||||
if (bfd_seek (abfd, dataOffset, SEEK_SET) != 0)
|
||||
|
|
|
@ -1240,7 +1240,7 @@ bfd_make_section_with_flags (bfd *abfd, const char *name,
|
|||
struct section_hash_entry *sh;
|
||||
asection *newsect;
|
||||
|
||||
if (abfd->output_has_begun)
|
||||
if (abfd == NULL || name == NULL || abfd->output_has_begun)
|
||||
{
|
||||
bfd_set_error (bfd_error_invalid_operation);
|
||||
return NULL;
|
||||
|
|
|
@ -903,7 +903,7 @@ _bfd_vms_slurp_ehdr (bfd *abfd)
|
|||
|
||||
vms_rec = PRIV (recrd.rec);
|
||||
/* PR 17512: file: 62736583. */
|
||||
end = vms_rec + PRIV (recrd.buf_size);
|
||||
end = PRIV (recrd.buf) + PRIV (recrd.buf_size);
|
||||
|
||||
vms_debug2 ((2, "HDR/EMH\n"));
|
||||
|
||||
|
@ -5737,8 +5737,9 @@ evax_bfd_print_emh (FILE *file, unsigned char *rec, unsigned int rec_len)
|
|||
{
|
||||
struct vms_emh_common *emh = (struct vms_emh_common *)rec;
|
||||
unsigned int subtype;
|
||||
int extra;
|
||||
|
||||
subtype = (unsigned)bfd_getl16 (emh->subtyp);
|
||||
subtype = (unsigned) bfd_getl16 (emh->subtyp);
|
||||
|
||||
/* xgettext:c-format */
|
||||
fprintf (file, _(" EMH %u (len=%u): "), subtype, rec_len);
|
||||
|
@ -5749,58 +5750,82 @@ evax_bfd_print_emh (FILE *file, unsigned char *rec, unsigned int rec_len)
|
|||
fprintf (file, _(" Error: The length is less than the length of an EMH record\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
extra = rec_len - sizeof (struct vms_emh_common);
|
||||
|
||||
switch (subtype)
|
||||
{
|
||||
case EMH__C_MHD:
|
||||
{
|
||||
struct vms_emh_mhd *mhd = (struct vms_emh_mhd *)rec;
|
||||
const char *name;
|
||||
struct vms_emh_mhd *mhd = (struct vms_emh_mhd *) rec;
|
||||
const char * name;
|
||||
const char * nextname;
|
||||
const char * maxname;
|
||||
|
||||
/* PR 21840: Check for invalid lengths. */
|
||||
if (rec_len < sizeof (* mhd))
|
||||
{
|
||||
fprintf (file, _(" Error: The record length is less than the size of an EMH_MHD record\n"));
|
||||
return;
|
||||
}
|
||||
fprintf (file, _("Module header\n"));
|
||||
fprintf (file, _(" structure level: %u\n"), mhd->strlvl);
|
||||
fprintf (file, _(" max record size: %u\n"),
|
||||
(unsigned)bfd_getl32 (mhd->recsiz));
|
||||
(unsigned) bfd_getl32 (mhd->recsiz));
|
||||
name = (char *)(mhd + 1);
|
||||
maxname = (char *) rec + rec_len;
|
||||
if (name > maxname - 2)
|
||||
{
|
||||
fprintf (file, _(" Error: The module name is missing\n"));
|
||||
return;
|
||||
}
|
||||
nextname = name + name[0] + 1;
|
||||
if (nextname >= maxname)
|
||||
{
|
||||
fprintf (file, _(" Error: The module name is too long\n"));
|
||||
return;
|
||||
}
|
||||
fprintf (file, _(" module name : %.*s\n"), name[0], name + 1);
|
||||
name += name[0] + 1;
|
||||
name = nextname;
|
||||
if (name > maxname - 2)
|
||||
{
|
||||
fprintf (file, _(" Error: The module version is missing\n"));
|
||||
return;
|
||||
}
|
||||
nextname = name + name[0] + 1;
|
||||
if (nextname >= maxname)
|
||||
{
|
||||
fprintf (file, _(" Error: The module version is too long\n"));
|
||||
return;
|
||||
}
|
||||
fprintf (file, _(" module version : %.*s\n"), name[0], name + 1);
|
||||
name += name[0] + 1;
|
||||
fprintf (file, _(" compile date : %.17s\n"), name);
|
||||
name = nextname;
|
||||
if ((maxname - name) < 17 && maxname[-1] != 0)
|
||||
fprintf (file, _(" Error: The compile date is truncated\n"));
|
||||
else
|
||||
fprintf (file, _(" compile date : %.17s\n"), name);
|
||||
}
|
||||
break;
|
||||
|
||||
case EMH__C_LNM:
|
||||
{
|
||||
fprintf (file, _("Language Processor Name\n"));
|
||||
fprintf (file, _(" language name: %.*s\n"),
|
||||
(int)(rec_len - sizeof (struct vms_emh_common)),
|
||||
(char *)rec + sizeof (struct vms_emh_common));
|
||||
}
|
||||
fprintf (file, _("Language Processor Name\n"));
|
||||
fprintf (file, _(" language name: %.*s\n"), extra, (char *)(emh + 1));
|
||||
break;
|
||||
|
||||
case EMH__C_SRC:
|
||||
{
|
||||
fprintf (file, _("Source Files Header\n"));
|
||||
fprintf (file, _(" file: %.*s\n"),
|
||||
(int)(rec_len - sizeof (struct vms_emh_common)),
|
||||
(char *)rec + sizeof (struct vms_emh_common));
|
||||
}
|
||||
fprintf (file, _("Source Files Header\n"));
|
||||
fprintf (file, _(" file: %.*s\n"), extra, (char *)(emh + 1));
|
||||
break;
|
||||
|
||||
case EMH__C_TTL:
|
||||
{
|
||||
fprintf (file, _("Title Text Header\n"));
|
||||
fprintf (file, _(" title: %.*s\n"),
|
||||
(int)(rec_len - sizeof (struct vms_emh_common)),
|
||||
(char *)rec + sizeof (struct vms_emh_common));
|
||||
}
|
||||
fprintf (file, _("Title Text Header\n"));
|
||||
fprintf (file, _(" title: %.*s\n"), extra, (char *)(emh + 1));
|
||||
break;
|
||||
|
||||
case EMH__C_CPR:
|
||||
{
|
||||
fprintf (file, _("Copyright Header\n"));
|
||||
fprintf (file, _(" copyright: %.*s\n"),
|
||||
(int)(rec_len - sizeof (struct vms_emh_common)),
|
||||
(char *)rec + sizeof (struct vms_emh_common));
|
||||
}
|
||||
fprintf (file, _("Copyright Header\n"));
|
||||
fprintf (file, _(" copyright: %.*s\n"), extra, (char *)(emh + 1));
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf (file, _("unhandled emh subtype %u\n"), subtype);
|
||||
break;
|
||||
|
|
|
@ -135,8 +135,8 @@ _bfd_hexdump (int level, unsigned char *ptr, int size, int offset)
|
|||
#endif
|
||||
|
||||
|
||||
/* Copy sized string (string with fixed size) to new allocated area
|
||||
size is string size (size of record) */
|
||||
/* Copy sized string (string with fixed size) to new allocated area.
|
||||
Size is string size (size of record). */
|
||||
|
||||
char *
|
||||
_bfd_vms_save_sized_string (unsigned char *str, unsigned int size)
|
||||
|
@ -151,8 +151,8 @@ _bfd_vms_save_sized_string (unsigned char *str, unsigned int size)
|
|||
return newstr;
|
||||
}
|
||||
|
||||
/* Copy counted string (string with size at first byte) to new allocated area
|
||||
ptr points to size byte on entry */
|
||||
/* Copy counted string (string with size at first byte) to new allocated area.
|
||||
PTR points to size byte on entry. */
|
||||
|
||||
char *
|
||||
_bfd_vms_save_counted_string (unsigned char *ptr, unsigned int maxlen)
|
||||
|
|
Loading…
Reference in New Issue