From 62c4dc16dd8fe99cba970c5e7d8dfc063855d4b9 Mon Sep 17 00:00:00 2001 From: Thiruvadi Rajaraman Date: Wed, 30 Aug 2017 17:54:52 +0530 Subject: binutils: CVE-2017-12449, CVE-2017_12455, CVE-2017-12457, CVE-2017-12458, CVE-2017-12459 Source: git://sourceware.org/git/binutils-gdb.git MR: 73867, 73788, 73762, 73749, 73734 Type: Security Fix Disposition: Backport from binutils-2_29-branch ChangeID: 29a1fd75a879d40560b3891305b7d9577e26ffe5 Description: 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. Fix address violations when reading corrupt VMS records. PR binutils/21618 * vms-alpha.c (evax_bfd_print_emh): Check for insufficient record length. (evax_bfd_print_eeom): Likewise. (evax_bfd_print_egsd): Check for an overlarge record length. (evax_bfd_print_etir): Likewise. Affects: <= 2.29 Signed-off-by: Thiruvadi Rajaraman Reviewed-by: Armin Kuster Signed-off-by: Armin Kuster Signed-off-by: Armin Kuster --- meta/recipes-devtools/binutils/binutils-2.27.inc | 2 + .../binutils/CVE-2017-12449_12455_12457.patch | 240 +++++++++++++++++++++ .../binutils/CVE-2017-12449_12455_12457_1.patch | 97 +++++++++ 3 files changed, 339 insertions(+) create mode 100644 meta/recipes-devtools/binutils/binutils/CVE-2017-12449_12455_12457.patch create mode 100644 meta/recipes-devtools/binutils/binutils/CVE-2017-12449_12455_12457_1.patch diff --git a/meta/recipes-devtools/binutils/binutils-2.27.inc b/meta/recipes-devtools/binutils/binutils-2.27.inc index 772df0af30..8cb7abc08a 100644 --- a/meta/recipes-devtools/binutils/binutils-2.27.inc +++ b/meta/recipes-devtools/binutils/binutils-2.27.inc @@ -54,6 +54,8 @@ SRC_URI = "\ file://CVE-2017-9041_2.patch \ file://CVE-2017-7226.patch \ file://CVE-2017-12448.patch \ + file://CVE-2017-12449_12455_12457_1.patch \ + file://CVE-2017-12449_12455_12457.patch \ " S = "${WORKDIR}/git" diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-12449_12455_12457.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-12449_12455_12457.patch new file mode 100644 index 0000000000..d7512b3829 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-12449_12455_12457.patch @@ -0,0 +1,240 @@ +commit 8bdf0be19d2777565a8b1c88347f65d6a4b8c5fc +Author: Nick Clifton +Date: Thu Jul 27 12:04:50 2017 +0100 + + 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. + +Upstream-Status: Backport + +CVE: CVE-2017-12449_12455_12457 +Signed-off-by: Thiruvadi Rajaraman + +Index: git/bfd/mach-o.c +=================================================================== +--- git.orig/bfd/mach-o.c 2017-08-30 17:21:59.684671218 +0530 ++++ git/bfd/mach-o.c 2017-08-30 17:22:19.136813620 +0530 +@@ -3739,6 +3739,9 @@ + } + 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; +Index: git/bfd/nlmcode.h +=================================================================== +--- git.orig/bfd/nlmcode.h 2017-08-30 17:21:59.688671247 +0530 ++++ git/bfd/nlmcode.h 2017-08-30 17:22:19.140813649 +0530 +@@ -351,7 +351,9 @@ + 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) +Index: git/bfd/section.c +=================================================================== +--- git.orig/bfd/section.c 2017-08-30 17:21:59.708671392 +0530 ++++ git/bfd/section.c 2017-08-30 17:22:19.140813649 +0530 +@@ -1240,7 +1240,7 @@ + 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; +Index: git/bfd/vms-alpha.c +=================================================================== +--- git.orig/bfd/vms-alpha.c 2017-08-30 17:22:19.080813209 +0530 ++++ git/bfd/vms-alpha.c 2017-08-30 17:22:19.140813649 +0530 +@@ -5562,8 +5562,9 @@ + { + 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); + + fprintf (file, _(" EMH %u (len=%u): "), subtype, rec_len); + +@@ -5573,58 +5574,82 @@ + 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; +Index: git/bfd/vms-misc.c +=================================================================== +--- git.orig/bfd/vms-misc.c 2017-08-30 17:21:59.716671451 +0530 ++++ git/bfd/vms-misc.c 2017-08-30 17:22:19.140813649 +0530 +@@ -135,8 +135,8 @@ + #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, int size) +@@ -151,8 +151,8 @@ + 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) +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-08-30 17:22:19.080813209 +0530 ++++ git/bfd/ChangeLog 2017-08-30 17:23:51.069502425 +0530 +@@ -1,3 +1,16 @@ ++2017-07-27 Nick Clifton ++ ++ 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-19 Nick Clifton + + PR 21787 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-12449_12455_12457_1.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-12449_12455_12457_1.patch new file mode 100644 index 0000000000..6dae0f6c24 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-12449_12455_12457_1.patch @@ -0,0 +1,97 @@ +commit bc21b167eb0106eb31d946a0eb5acfb7e4d5d8a1 +Author: Nick Clifton +Date: Mon Jun 19 14:52:36 2017 +0100 + + Fix address violations when reading corrupt VMS records. + + PR binutils/21618 + * vms-alpha.c (evax_bfd_print_emh): Check for insufficient record + length. + (evax_bfd_print_eeom): Likewise. + (evax_bfd_print_egsd): Check for an overlarge record length. + (evax_bfd_print_etir): Likewise. + +Upstream-Status: Backport + +CVE: CVE-2017-12449_12455_12457 +Signed-off-by: Thiruvadi Rajaraman + +Index: git/bfd/vms-alpha.c +=================================================================== +--- git.orig/bfd/vms-alpha.c 2017-08-30 17:08:27.408159234 +0530 ++++ git/bfd/vms-alpha.c 2017-08-30 17:12:07.289044702 +0530 +@@ -5567,6 +5567,13 @@ + + fprintf (file, _(" EMH %u (len=%u): "), subtype, rec_len); + ++ /* PR 21618: Check for invalid lengths. */ ++ if (rec_len < sizeof (* emh)) ++ { ++ fprintf (file, _(" Error: The length is less than the length of an EMH record\n")); ++ return; ++ } ++ + switch (subtype) + { + case EMH__C_MHD: +@@ -5630,6 +5637,14 @@ + struct vms_eeom *eeom = (struct vms_eeom *)rec; + + fprintf (file, _(" EEOM (len=%u):\n"), rec_len); ++ ++ /* PR 21618: Check for invalid lengths. */ ++ if (rec_len < sizeof (* eeom)) ++ { ++ fprintf (file, _(" Error: The length is less than the length of an EEOM record\n")); ++ return; ++ } ++ + fprintf (file, _(" number of cond linkage pairs: %u\n"), + (unsigned)bfd_getl32 (eeom->total_lps)); + fprintf (file, _(" completion code: %u\n"), +@@ -5718,6 +5733,12 @@ + n, type, len); + n++; + ++ if (off + len > rec_len || off + len < off) ++ { ++ fprintf (file, _(" Error: length larger than remaining space in record\n")); ++ return; ++ } ++ + switch (type) + { + case EGSD__C_PSC: +@@ -5958,6 +5979,12 @@ + size = bfd_getl16 (etir->size); + buf = rec + off + sizeof (struct vms_etir); + ++ if (off + size > rec_len || off + size < off) ++ { ++ fprintf (file, _(" Error: length larger than remaining space in record\n")); ++ return; ++ } ++ + fprintf (file, _(" (type: %3u, size: 4+%3u): "), type, size - 4); + switch (type) + { +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-08-30 17:08:43.612213596 +0530 ++++ git/bfd/ChangeLog 2017-08-30 17:13:27.217438742 +0530 +@@ -5,6 +5,15 @@ + correct magic bytes at the start, set the error to wrong format + and clear the format selector before returning NULL. + ++ 2017-06-19 Nick Clifton ++ ++ PR binutils/21618 ++ * vms-alpha.c (evax_bfd_print_emh): Check for insufficient record ++ length. ++ (evax_bfd_print_eeom): Likewise. ++ (evax_bfd_print_egsd): Check for an overlarge record length. ++ (evax_bfd_print_etir): Likewise. ++ + 2017-04-25 Maciej W. Rozycki + + * readelf.c (process_mips_specific): Remove error reporting from -- cgit 1.2.3-korg