From 2cc3922462c9dd86f50a419a2a4abb0f3b5b4745 Mon Sep 17 00:00:00 2001 From: Thiruvadi Rajaraman Date: Thu, 31 Aug 2017 19:23:29 +0530 Subject: binutils: CVE-2017-12450_12452_12453_12454_12456 Source: git://sourceware.org/git/binutils-gdb.git MR: 73854, 73827, 73814, 73801, 73775 Type: Security Fix Disposition: Backport from binutils-2_29-branch ChangeID: fb23096307f9903872a04edf171d1fd2099e35c5 Description: 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. Affects: <= 2.29 Signed-off-by: Thiruvadi Rajaraman Reviewed-by: Armin Kuster Signed-off-by: Armin Kuster Signed-off-by: Armin Kuster --- .../CVE-2017-12450_12452_12453_12454_12456.patch | 375 +++++++++++++++++++++ .../CVE-2017-12450_12452_12453_12454_12456_1.patch | 113 +++++++ 2 files changed, 488 insertions(+) create mode 100644 meta/recipes-devtools/binutils/binutils/CVE-2017-12450_12452_12453_12454_12456.patch create mode 100644 meta/recipes-devtools/binutils/binutils/CVE-2017-12450_12452_12453_12454_12456_1.patch (limited to 'meta/recipes-devtools/binutils/binutils') diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-12450_12452_12453_12454_12456.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-12450_12452_12453_12454_12456.patch new file mode 100644 index 0000000000..503f655b61 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-12450_12452_12453_12454_12456.patch @@ -0,0 +1,375 @@ +commit ca4cf9b9c622a5695e01f7f5815a7382a31fcf51 +Author: Nick Clifton +Date: Mon Jul 24 13:49:22 2017 +0100 + + 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. + + (alpha_vms_object_p): Check for a truncated record. + +Upstream-Status: Backport + +CVE: CVE-2017-12450, CVE-2017-12452, CVE-2017-12453, CVE-2017-12454, CVE-2017-12456 +Signed-off-by: Thiruvadi Rajaraman + +Index: git/bfd/mach-o-aarch64.c +=================================================================== +--- git.orig/bfd/mach-o-aarch64.c 2017-08-31 19:17:51.264385450 +0530 ++++ git/bfd/mach-o-aarch64.c 2017-08-31 19:18:02.620442777 +0530 +@@ -147,9 +147,11 @@ + }; + + static bfd_boolean +-bfd_mach_o_arm64_canonicalize_one_reloc (bfd *abfd, +- struct mach_o_reloc_info_external *raw, +- arelent *res, asymbol **syms) ++bfd_mach_o_arm64_canonicalize_one_reloc (bfd * abfd, ++ struct mach_o_reloc_info_external * raw, ++ arelent * res, ++ asymbol ** syms, ++ arelent * res_base ATTRIBUTE_UNUSED) + { + bfd_mach_o_reloc_info reloc; + +Index: git/bfd/mach-o-i386.c +=================================================================== +--- git.orig/bfd/mach-o-i386.c 2017-08-31 19:17:51.264385450 +0530 ++++ git/bfd/mach-o-i386.c 2017-08-31 19:18:02.620442777 +0530 +@@ -112,9 +112,11 @@ + }; + + static bfd_boolean +-bfd_mach_o_i386_canonicalize_one_reloc (bfd *abfd, +- struct mach_o_reloc_info_external *raw, +- arelent *res, asymbol **syms) ++bfd_mach_o_i386_canonicalize_one_reloc (bfd * abfd, ++ struct mach_o_reloc_info_external * raw, ++ arelent * res, ++ asymbol ** syms, ++ arelent * res_base) + { + bfd_mach_o_reloc_info reloc; + +@@ -126,6 +128,9 @@ + 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]; +@@ -391,9 +396,9 @@ + { NULL, NULL } + }; + +-#define bfd_mach_o_canonicalize_one_reloc bfd_mach_o_i386_canonicalize_one_reloc +-#define bfd_mach_o_swap_reloc_out bfd_mach_o_i386_swap_reloc_out +-#define bfd_mach_o_print_thread bfd_mach_o_i386_print_thread ++#define bfd_mach_o_canonicalize_one_reloc bfd_mach_o_i386_canonicalize_one_reloc ++#define bfd_mach_o_swap_reloc_out bfd_mach_o_i386_swap_reloc_out ++#define bfd_mach_o_print_thread bfd_mach_o_i386_print_thread + + #define bfd_mach_o_tgt_seg_table mach_o_i386_segsec_names_xlat + #define bfd_mach_o_section_type_valid_for_tgt NULL +Index: git/bfd/mach-o-x86-64.c +=================================================================== +--- git.orig/bfd/mach-o-x86-64.c 2017-08-31 19:17:51.264385450 +0530 ++++ git/bfd/mach-o-x86-64.c 2017-08-31 19:18:02.620442777 +0530 +@@ -120,9 +120,11 @@ + }; + + static bfd_boolean +-bfd_mach_o_x86_64_canonicalize_one_reloc (bfd *abfd, +- struct mach_o_reloc_info_external *raw, +- arelent *res, asymbol **syms) ++bfd_mach_o_x86_64_canonicalize_one_reloc (bfd * abfd, ++ struct mach_o_reloc_info_external * raw, ++ arelent * res, ++ asymbol ** syms, ++ arelent * res_base ATTRIBUTE_UNUSED) + { + bfd_mach_o_reloc_info reloc; + +Index: git/bfd/mach-o.c +=================================================================== +--- git.orig/bfd/mach-o.c 2017-08-31 19:18:02.440441869 +0530 ++++ git/bfd/mach-o.c 2017-08-31 19:18:02.620442777 +0530 +@@ -1496,7 +1496,7 @@ + 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); +Index: git/bfd/mach-o.h +=================================================================== +--- git.orig/bfd/mach-o.h 2017-08-31 19:17:51.264385450 +0530 ++++ git/bfd/mach-o.h 2017-08-31 19:18:02.620442777 +0530 +@@ -746,7 +746,7 @@ + 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 *); +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-08-31 19:18:02.564442494 +0530 ++++ git/bfd/ChangeLog 2017-08-31 19:18:02.620442777 +0530 +@@ -11,6 +11,30 @@ + of end pointer. + (evax_bfd_print_emh): Check for invalid string lengths. + ++ 2017-07-24 Nick Clifton ++ ++ 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-19 Nick Clifton + + PR 21786 +Index: git/bfd/mach-o-arm.c +=================================================================== +--- git.orig/bfd/mach-o-arm.c 2017-08-31 19:17:51.264385450 +0530 ++++ git/bfd/mach-o-arm.c 2017-08-31 19:18:02.620442777 +0530 +@@ -30,7 +30,7 @@ + #define bfd_mach_o_mkobject bfd_mach_o_arm_mkobject + + #define bfd_mach_o_canonicalize_one_reloc bfd_mach_o_arm_canonicalize_one_reloc +-#define bfd_mach_o_swap_reloc_out NULL ++#define bfd_mach_o_swap_reloc_out NULL + #define bfd_mach_o_bfd_reloc_type_lookup bfd_mach_o_arm_bfd_reloc_type_lookup + #define bfd_mach_o_bfd_reloc_name_lookup bfd_mach_o_arm_bfd_reloc_name_lookup + +@@ -147,9 +147,11 @@ + }; + + static bfd_boolean +-bfd_mach_o_arm_canonicalize_one_reloc (bfd *abfd, +- struct mach_o_reloc_info_external *raw, +- arelent *res, asymbol **syms) ++bfd_mach_o_arm_canonicalize_one_reloc (bfd * abfd, ++ struct mach_o_reloc_info_external * raw, ++ arelent * res, ++ asymbol ** syms, ++ arelent * res_base) + { + bfd_mach_o_reloc_info reloc; + +@@ -161,6 +163,9 @@ + 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]; +Index: git/bfd/vms-alpha.c +=================================================================== +--- git.orig/bfd/vms-alpha.c 2017-08-31 19:18:02.556442454 +0530 ++++ git/bfd/vms-alpha.c 2017-08-31 19:20:56.233322607 +0530 +@@ -473,6 +473,14 @@ + + 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); + +@@ -1255,19 +1263,39 @@ + 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]; ++ + } + } + } +@@ -1294,9 +1322,20 @@ + + 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; +@@ -1387,6 +1426,10 @@ + + if (PRIV (sections) == NULL) + return; ++ ++ if (sect < 0 || sect >= (int) PRIV (section_count)) ++ return; ++ + sec = PRIV (sections)[sect]; + + if (info) +@@ -2360,6 +2403,14 @@ + + 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) +@@ -2540,6 +2591,10 @@ + PRIV (recrd.buf_size) = PRIV (recrd.rec_size); + } + ++ /* PR 21813: Check for a truncated record. */ ++ if (PRIV (recrd.rec_size < test_len)) ++ goto error_ret; ++ + /* Read the remaining record. */ + remaining = PRIV (recrd.rec_size) - test_len; + to_read = MIN (VMS_BLOCK_SIZE - test_len, remaining); +@@ -5074,7 +5129,7 @@ + } + 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; +Index: git/binutils/ChangeLog +=================================================================== +--- git.orig/binutils/ChangeLog 2017-08-31 19:18:01.816438718 +0530 ++++ git/binutils/ChangeLog 2017-08-31 19:18:02.624442798 +0530 +@@ -1,3 +1,9 @@ ++2017-07-24 Nick Clifton ++ ++ PR 21813 ++ * rddbg.c (read_symbol_stabs_debugging_info): Check for an empty ++ string whilst concatenating symbol names. ++ + 2017-02-14 Nick Clifton + + PR binutils/21157 +Index: git/binutils/rddbg.c +=================================================================== +--- git.orig/binutils/rddbg.c 2017-08-31 19:17:51.596387126 +0530 ++++ git/binutils/rddbg.c 2017-08-31 19:18:02.624442798 +0530 +@@ -300,7 +300,8 @@ + + s = i.name; + f = NULL; +- while (s[strlen (s) - 1] == '\\' ++ while (strlen (s) > 0 ++ && s[strlen (s) - 1] == '\\' + && ps + 1 < symend) + { + char *sc, *n; diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-12450_12452_12453_12454_12456_1.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-12450_12452_12453_12454_12456_1.patch new file mode 100644 index 0000000000..208bbbafae --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-12450_12452_12453_12454_12456_1.patch @@ -0,0 +1,113 @@ +commit cb06d03ad92ffcfaa09c3f065837cb39e9e1486d +Author: Nick Clifton +Date: Wed Jun 21 11:13:49 2017 +0100 + + Fix address violation parsing a corrupt IEEE Alpha binary. + + PR binutils/21637 + * vms-alpha.c (_bfd_vms_slurp_egsd): Check for an empty section + list. + (image_set_ptr): Likewise. + (alpha_vms_fix_sec_rel): Likewise. + (alpha_vms_slurp_relocs): Likewise. + +Upstream-Status: Backport + +CVE: CVE-2017-12450, CVE-2017-12452, CVE-2017-12453, CVE-2017-12454, CVE-2017-12456 +Signed-off-by: Thiruvadi Rajaraman + +Index: git/bfd/vms-alpha.c +=================================================================== +--- git.orig/bfd/vms-alpha.c 2017-08-31 18:01:00.742098130 +0530 ++++ git/bfd/vms-alpha.c 2017-08-31 18:01:06.000000000 +0530 +@@ -1257,6 +1257,8 @@ + struct vms_esdf *esdf = (struct vms_esdf *)vms_rec; + + entry->value = bfd_getl64 (esdf->value); ++ if (PRIV (sections) == NULL) ++ return FALSE; + entry->section = PRIV (sections)[bfd_getl32 (esdf->psindx)]; + + if (old_flags & EGSY__V_NORM) +@@ -1291,7 +1293,11 @@ + entry->symbol_vector = bfd_getl32 (egst->value); + + if (old_flags & EGSY__V_REL) +- entry->section = PRIV (sections)[bfd_getl32 (egst->psindx)]; ++ { ++ if (PRIV (sections) == NULL) ++ return FALSE; ++ entry->section = PRIV (sections)[bfd_getl32 (egst->psindx)]; ++ } + else + entry->section = bfd_abs_section_ptr; + +@@ -1379,6 +1385,8 @@ + + vms_debug2 ((4, "image_set_ptr (0x%08x, sect=%d)\n", (unsigned)vma, sect)); + ++ if (PRIV (sections) == NULL) ++ return; + sec = PRIV (sections)[sect]; + + if (info) +@@ -1691,7 +1699,12 @@ + alpha_vms_fix_sec_rel (bfd *abfd, struct bfd_link_info *info, + unsigned int rel, bfd_vma vma) + { +- asection *sec = PRIV (sections)[rel & RELC_MASK]; ++ asection *sec; ++ ++ if (PRIV (sections) == NULL) ++ return 0; ++ ++ sec = PRIV (sections)[rel & RELC_MASK]; + + if (info) + { +@@ -5000,6 +5013,8 @@ + return FALSE; + } + ++ if (PRIV (sections) == NULL) ++ return FALSE; + sec = PRIV (sections)[cur_psect]; + if (sec == bfd_abs_section_ptr) + { +@@ -5058,8 +5073,12 @@ + reloc->sym_ptr_ptr = sym; + } + else if (cur_psidx >= 0) +- reloc->sym_ptr_ptr = +- PRIV (sections)[cur_psidx]->symbol_ptr_ptr; ++ { ++ if (PRIV (sections) == NULL) ++ return FALSE; ++ reloc->sym_ptr_ptr = ++ PRIV (sections)[cur_psidx]->symbol_ptr_ptr; ++ } + else + reloc->sym_ptr_ptr = NULL; + +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-08-31 18:01:06.000000000 +0530 ++++ git/bfd/ChangeLog 2017-08-31 18:01:49.114384620 +0530 +@@ -31,7 +31,16 @@ + 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 ++ 2017-06-21 Nick Clifton ++ ++ PR binutils/21637 ++ * vms-alpha.c (_bfd_vms_slurp_egsd): Check for an empty section ++ list. ++ (image_set_ptr): Likewise. ++ (alpha_vms_fix_sec_rel): Likewise. ++ (alpha_vms_slurp_relocs): Likewise. ++ ++2017-06-19 Nick Clifton + + PR binutils/21618 + * vms-alpha.c (evax_bfd_print_emh): Check for insufficient record -- cgit 1.2.3-korg