From: Nick Clifton Date: Tue, 29 Aug 2017 11:37:45 +0000 (+0100) Subject: Import patch from mainline to fix address violation issues when parsing corrupt binaries. X-Git-Tag: binutils-2_29_1~48 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=796337aa8ba0aa0397c07c264f82fe8eb9fd46e0;p=thirdparty%2Fbinutils-gdb.git Import patch from mainline to fix address violation issues when parsing corrupt binaries. * 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. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index c5739aed96e..c90206c2f50 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +2017-08-29 Nick Clifton + + Import from mainline: + + 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-08-23 Alan Modra PR 21988 diff --git a/bfd/mach-o.c b/bfd/mach-o.c index 2c1973c2a42..51920df6833 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -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; diff --git a/bfd/nlmcode.h b/bfd/nlmcode.h index 6d6aed02c10..350c83e1208 100644 --- a/bfd/nlmcode.h +++ b/bfd/nlmcode.h @@ -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) diff --git a/bfd/section.c b/bfd/section.c index 28eee7f8b3c..811d42a0d02 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -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; diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c index 91e8b6e0324..0b41db4409e 100644 --- a/bfd/vms-alpha.c +++ b/bfd/vms-alpha.c @@ -895,7 +895,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")); @@ -5685,8 +5685,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); @@ -5697,58 +5698,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; @@ -6220,7 +6245,7 @@ evax_bfd_print_etir (FILE *file, const char *name, fprintf (file, _("OPR_ADD (add)\n")); break; case ETIR__C_OPR_SUB: - fprintf (file, _("OPR_SUB (substract)\n")); + fprintf (file, _("OPR_SUB (subtract)\n")); break; case ETIR__C_OPR_MUL: fprintf (file, _("OPR_MUL (multiply)\n"));