Markus Koschany <a...@debian.org> writes: > In my opinion CVE-2016-6131 is not a security issue and in this case we > should mark it as no-dsa. I did the same for all of the newly reported > CVEs last week. In general gdb and valgrind are development tools and > I'm sure there are numerous ways to craft a special executable that can > make these tools crash. You won't find the circumstances in a production > environment though, so I'm all for removing the packages from > dla-needed.txt until there is a real security issue. The security team > and others seem to agree. [1][2]
I have a build of binutils for all pending CVEs except CVE-2016-4491, which I did not apply due to the code being very different - which could mean that the CVE doesn't apply to the wheezy version. The debdiff is applied. I haven't tested yet, was about to do that today. Are you saying I should not worry about uploading my package at this point in time? -- Brian May <b...@debian.org>
diff -u binutils-2.22/debian/changelog binutils-2.22/debian/changelog --- binutils-2.22/debian/changelog +++ binutils-2.22/debian/changelog @@ -1,3 +1,20 @@ +binutils (2.22-8+deb7u3) wheezy-security; urgency=high + + * Non-maintainer upload by the LTS Team. + * Fixes for the following CVEs: + * CVE-2016-2226.patch: Exploitable buffer overflow + * CVE-2016-4487.patch: Invalid write due to a use-after-free to array btypevec + * CVE-2016-4488.patch: Invalid write due to a use-after-free to array ktypevec + * CVE-2016-4489.patch: Invalid write due to integer overflow + * CVE-2016-4490-1.patch: Write access violation + * CVE-2016-4490-2.patch: Write access violation + * CVE-2016-4492_CVE-2016-4493.patch: Read/write access violations + * CVE-2016-6131.patch: Libiberty Demangler segfaults + * CVE-2016-XXXX.patch: Stack buffer overflow when printing bad bytes in + Intel Hex objects + + -- Brian May <b...@debian.org> Tue, 05 Jul 2016 18:18:56 +1000 + binutils (2.22-8+deb7u2) wheezy-security; urgency=high * FTBFS on armel, kfreebsd-i386, mips, mipsel, powerpc, and s390 fixed. diff -u binutils-2.22/debian/patches/series binutils-2.22/debian/patches/series --- binutils-2.22/debian/patches/series +++ binutils-2.22/debian/patches/series @@ -43,0 +44,10 @@ + +CVE-2016-2226.patch +CVE-2016-4487.patch +CVE-2016-4488.patch +CVE-2016-4489.patch +CVE-2016-4490-1.patch +CVE-2016-4490-2.patch +CVE-2016-4492_CVE-2016-4493.patch +CVE-2016-6131.patch +CVE-2016-XXXX.patch only in patch2: unchanged: --- binutils-2.22.orig/debian/patches/CVE-2016-2226.patch +++ binutils-2.22/debian/patches/CVE-2016-2226.patch @@ -0,0 +1,52 @@ +--- a/libiberty/cplus-dem.c ++++ b/libiberty/cplus-dem.c +@@ -56,6 +56,13 @@ + void * realloc (); + #endif + ++#ifdef HAVE_LIMITS_H ++#include <limits.h> ++#endif ++#ifndef INT_MAX ++# define INT_MAX (int)(((unsigned int) ~0) >> 1) /* 0x7FFFFFFF */ ++#endif ++ + #include <demangle.h> + #undef CURRENT_DEMANGLING_STYLE + #define CURRENT_DEMANGLING_STYLE work->options +@@ -4231,6 +4238,8 @@ + } + else + { ++ if (work -> typevec_size > INT_MAX / 2) ++ xmalloc_failed (INT_MAX); + work -> typevec_size *= 2; + work -> typevec + = XRESIZEVEC (char *, work->typevec, work->typevec_size); +@@ -4258,6 +4267,8 @@ + } + else + { ++ if (work -> ksize > INT_MAX / 2) ++ xmalloc_failed (INT_MAX); + work -> ksize *= 2; + work -> ktypevec + = XRESIZEVEC (char *, work->ktypevec, work->ksize); +@@ -4287,6 +4298,8 @@ + } + else + { ++ if (work -> bsize > INT_MAX / 2) ++ xmalloc_failed (INT_MAX); + work -> bsize *= 2; + work -> btypevec + = XRESIZEVEC (char *, work->btypevec, work->bsize); +@@ -4741,6 +4754,8 @@ + else if (s->e - s->p < n) + { + tem = s->p - s->b; ++ if (n > INT_MAX / 2 - tem) ++ xmalloc_failed (INT_MAX); + n += tem; + n *= 2; + s->b = XRESIZEVEC (char, s->b, n); only in patch2: unchanged: --- binutils-2.22.orig/debian/patches/CVE-2016-4487.patch +++ binutils-2.22/debian/patches/CVE-2016-4487.patch @@ -0,0 +1,11 @@ +--- a/libiberty/cplus-dem.c ++++ b/libiberty/cplus-dem.c +@@ -1225,6 +1225,8 @@ + if (work -> btypevec != NULL) + { + free ((char *) work -> btypevec); ++ work->btypevec = NULL; ++ work->bsize = 0; + } + if (work -> ktypevec != NULL) + { only in patch2: unchanged: --- binutils-2.22.orig/debian/patches/CVE-2016-4488.patch +++ binutils-2.22/debian/patches/CVE-2016-4488.patch @@ -0,0 +1,11 @@ +--- a/libiberty/cplus-dem.c ++++ b/libiberty/cplus-dem.c +@@ -1231,6 +1231,8 @@ + if (work -> ktypevec != NULL) + { + free ((char *) work -> ktypevec); ++ work->ktypevec = NULL; ++ work->bsize = 0; + } + } + only in patch2: unchanged: --- binutils-2.22.orig/debian/patches/CVE-2016-4489.patch +++ binutils-2.22/debian/patches/CVE-2016-4489.patch @@ -0,0 +1,14 @@ +--- a/libiberty/cplus-dem.c ++++ b/libiberty/cplus-dem.c +@@ -2990,6 +2990,11 @@ + success = 1; + break; + } ++ else if (n == -1) ++ { ++ success = 0; ++ break; ++ } + } + else + { only in patch2: unchanged: --- binutils-2.22.orig/debian/patches/CVE-2016-4490-1.patch +++ binutils-2.22/debian/patches/CVE-2016-4490-1.patch @@ -0,0 +1,169 @@ +--- a/libiberty/cp-demangle.c ++++ b/libiberty/cp-demangle.c +@@ -124,6 +124,13 @@ + # endif /* alloca */ + #endif /* HAVE_ALLOCA_H */ + ++#ifdef HAVE_LIMITS_H ++#include <limits.h> ++#endif ++#ifndef INT_MAX ++# define INT_MAX (int)(((unsigned int) ~0) >> 1) /* 0x7FFFFFFF */ ++#endif ++ + #include "ansidecl.h" + #include "libiberty.h" + #include "demangle.h" +@@ -343,7 +350,7 @@ + struct demangle_component *); + + static struct demangle_component * +-d_make_template_param (struct d_info *, long); ++d_make_template_param (struct d_info *, int); + + static struct demangle_component * + d_make_sub (struct d_info *, const char *, int); +@@ -366,7 +373,7 @@ + + static struct demangle_component *d_source_name (struct d_info *); + +-static long d_number (struct d_info *); ++static int d_number (struct d_info *); + + static struct demangle_component *d_identifier (struct d_info *, int); + +@@ -988,7 +995,7 @@ + /* Add a new template parameter. */ + + static struct demangle_component * +-d_make_template_param (struct d_info *di, long i) ++d_make_template_param (struct d_info *di, int i) + { + struct demangle_component *p; + +@@ -1004,7 +1011,7 @@ + /* Add a new function parameter. */ + + static struct demangle_component * +-d_make_function_param (struct d_info *di, long i) ++d_make_function_param (struct d_info *di, int i) + { + struct demangle_component *p; + +@@ -1425,7 +1432,7 @@ + static struct demangle_component * + d_source_name (struct d_info *di) + { +- long len; ++ int len; + struct demangle_component *ret; + + len = d_number (di); +@@ -1438,12 +1445,12 @@ + + /* number ::= [n] <(non-negative decimal integer)> */ + +-static long ++static int + d_number (struct d_info *di) + { + int negative; + char peek; +- long ret; ++ int ret; + + negative = 0; + peek = d_peek_char (di); +@@ -1653,7 +1660,7 @@ + { + struct demangle_component *p = NULL; + struct demangle_component *next = NULL; +- long len, i; ++ int len, i; + char c; + const char *str; + +@@ -1793,7 +1800,7 @@ + case 'C': + { + struct demangle_component *derived_type; +- long offset; ++ int offset; + struct demangle_component *base_type; + + derived_type = cplus_demangle_type (di); +@@ -2547,10 +2554,10 @@ + + /* <non-negative number> _ */ + +-static long ++static int + d_compact_number (struct d_info *di) + { +- long num; ++ int num; + if (d_peek_char (di) == '_') + num = 0; + else if (d_peek_char (di) == 'n') +@@ -2558,7 +2565,7 @@ + else + num = d_number (di) + 1; + +- if (! d_check_char (di, '_')) ++ if (num < 0 || ! d_check_char (di, '_')) + return -1; + return num; + } +@@ -2570,7 +2577,7 @@ + static struct demangle_component * + d_template_param (struct d_info *di) + { +- long param; ++ int param; + + if (! d_check_char (di, 'T')) + return NULL; +@@ -2756,9 +2763,10 @@ + } + else + { +- index = d_compact_number (di) + 1; +- if (index == 0) ++ index = d_compact_number (di); ++ if (index == INT_MAX || index == -1) + return NULL; ++ index ++; + } + return d_make_function_param (di, index); + } +@@ -3002,7 +3010,7 @@ + static int + d_discriminator (struct d_info *di) + { +- long discrim; ++ int discrim; + + if (d_peek_char (di) != '_') + return 1; +@@ -3058,7 +3066,7 @@ + d_unnamed_type (struct d_info *di) + { + struct demangle_component *ret; +- long num; ++ int num; + + if (! d_check_char (di, 'U')) + return NULL; +@@ -3378,10 +3386,10 @@ + } + + static inline void +-d_append_num (struct d_print_info *dpi, long l) ++d_append_num (struct d_print_info *dpi, int l) + { + char buf[25]; +- sprintf (buf,"%ld", l); ++ sprintf (buf,"%d", l); + d_append_string (dpi, buf); + } + only in patch2: unchanged: --- binutils-2.22.orig/debian/patches/CVE-2016-4490-2.patch +++ binutils-2.22/debian/patches/CVE-2016-4490-2.patch @@ -0,0 +1,16 @@ +--- a/libiberty/testsuite/demangle-expected ++++ b/libiberty/testsuite/demangle-expected +@@ -4151,3 +4151,13 @@ + --format=auto + _ZN3Psi7VariantIIcPKcEE5visitIIRZN11VariantTest9TestVisit11test_methodEvEUlS2_E0_RZNS6_11test_methodEvEUlcE1_RZNS6_11test_methodEvEUlNS_4NoneEE_EEENS_13VariantDetail19SelectVisitorResultIIDpT_EE4typeEDpOSG_ + Psi::VariantDetail::SelectVisitorResult<VariantTest::TestVisit::test_method()::{lambda(char const*)#2}&, VariantTest::TestVisit::test_method()::{lambda(char)#3}&, VariantTest::TestVisit::test_method()::{lambda(Psi::None)#1}&>::type Psi::Variant<char, char const*>::visit<VariantTest::TestVisit::test_method()::{lambda(char const*)#2}&, VariantTest::TestVisit::test_method()::{lambda(char)#3}&, VariantTest::TestVisit::test_method()::{lambda(Psi::None)#1}&>((VariantTest::TestVisit::test_method()::{lambda(Psi::None)#1}&)...) ++# ++# Tests integer overflow problem PR70492 ++ ++__vt_90000000000cafebabe ++__vt_90000000000cafebabe ++# ++# Tests write access violation PR70498 ++ ++_Z80800000000000000000000 ++_Z80800000000000000000000 only in patch2: unchanged: --- binutils-2.22.orig/debian/patches/CVE-2016-4492_CVE-2016-4493.patch +++ binutils-2.22/debian/patches/CVE-2016-4492_CVE-2016-4493.patch @@ -0,0 +1,59 @@ +--- a/libiberty/cplus-dem.c ++++ b/libiberty/cplus-dem.c +@@ -2033,7 +2033,8 @@ + else + { + int symbol_len = consume_count (mangled); +- if (symbol_len == -1) ++ if (symbol_len == -1 ++ || symbol_len > (long) strlen (*mangled)) + return -1; + if (symbol_len == 0) + string_appendn (s, "0", 1); +@@ -3593,7 +3594,7 @@ + /* A back reference to a previously seen type */ + case 'T': + (*mangled)++; +- if (!get_count (mangled, &n) || n >= work -> ntypes) ++ if (!get_count (mangled, &n) || n < 0 || n >= work -> ntypes) + { + success = 0; + } +@@ -3768,7 +3769,7 @@ + /* A back reference to a previously seen squangled type */ + case 'B': + (*mangled)++; +- if (!get_count (mangled, &n) || n >= work -> numb) ++ if (!get_count (mangled, &n) || n < 0 || n >= work -> numb) + success = 0; + else + string_append (result, work->btypevec[n]); +@@ -4109,7 +4110,8 @@ + + literal_len = consume_count (mangled); + +- if (literal_len <= 0) ++ if (literal_len <= 0 ++ || literal_len > (long) strlen (*mangled)) + return 0; + + /* Literal parameters are names of arrays, functions, etc. and the +--- a/libiberty/testsuite/demangle-expected ++++ b/libiberty/testsuite/demangle-expected +@@ -4161,3 +4161,16 @@ + + _Z80800000000000000000000 + _Z80800000000000000000000 ++# ++# Tests write access violation PR70926 ++ ++0__Ot2m02R5T0000500000 ++0__Ot2m02R5T0000500000 ++# ++ ++0__GT50000000000_ ++0__GT50000000000_ ++# ++ ++__t2m05B500000000000000000_ ++__t2m05B500000000000000000_ only in patch2: unchanged: --- binutils-2.22.orig/debian/patches/CVE-2016-4493.patch +++ binutils-2.22/debian/patches/CVE-2016-4493.patch @@ -0,0 +1,63 @@ +Index: libiberty/cplus-dem.c +=================================================================== +--- a/libiberty/cplus-dem.c (revision 235801) ++++ b/libiberty/cplus-dem.c (working copy) +@@ -2051,7 +2051,8 @@ demangle_template_value_parm (struct work_stuff *w + else + { + int symbol_len = consume_count (mangled); +- if (symbol_len == -1) ++ if (symbol_len == -1 ++ || symbol_len > (long) strlen (*mangled)) + return -1; + if (symbol_len == 0) + string_appendn (s, "0", 1); +@@ -3611,7 +3612,7 @@ do_type (struct work_stuff *work, const char **man + /* A back reference to a previously seen type */ + case 'T': + (*mangled)++; +- if (!get_count (mangled, &n) || n >= work -> ntypes) ++ if (!get_count (mangled, &n) || n < 0 || n >= work -> ntypes) + { + success = 0; + } +@@ -3789,7 +3790,7 @@ do_type (struct work_stuff *work, const char **man + /* A back reference to a previously seen squangled type */ + case 'B': + (*mangled)++; +- if (!get_count (mangled, &n) || n >= work -> numb) ++ if (!get_count (mangled, &n) || n < 0 || n >= work -> numb) + success = 0; + else + string_append (result, work->btypevec[n]); +@@ -4130,7 +4131,8 @@ do_hpacc_template_literal (struct work_stuff *work + + literal_len = consume_count (mangled); + +- if (literal_len <= 0) ++ if (literal_len <= 0 ++ || literal_len > (long) strlen (*mangled)) + return 0; + + /* Literal parameters are names of arrays, functions, etc. and the +Index: libiberty/testsuite/demangle-expected +=================================================================== +--- a/libiberty/testsuite/demangle-expected (revision 235801) ++++ b/libiberty/testsuite/demangle-expected (working copy) +@@ -4441,3 +4441,16 @@ __vt_90000000000cafebabe + + _Z80800000000000000000000 + _Z80800000000000000000000 ++# ++# Tests write access violation PR70926 ++ ++0__Ot2m02R5T0000500000 ++0__Ot2m02R5T0000500000 ++# ++ ++0__GT50000000000_ ++0__GT50000000000_ ++# ++ ++__t2m05B500000000000000000_ ++__t2m05B500000000000000000_ only in patch2: unchanged: --- binutils-2.22.orig/debian/patches/CVE-2016-6131.patch +++ binutils-2.22/debian/patches/CVE-2016-6131.patch @@ -0,0 +1,153 @@ +--- a/libiberty/cplus-dem.c ++++ b/libiberty/cplus-dem.c +@@ -144,6 +144,9 @@ + string* previous_argument; /* The last function argument demangled. */ + int nrepeats; /* The number of times to repeat the previous + argument. */ ++ int *proctypevec; /* Indices of currently processed remembered typevecs. */ ++ int proctypevec_size; ++ int nproctypes; + }; + + #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI) +@@ -429,6 +432,10 @@ + + static void remember_type (struct work_stuff *, const char *, int); + ++static void push_processed_type (struct work_stuff *, int); ++ ++static void pop_processed_type (struct work_stuff *); ++ + static void remember_Btype (struct work_stuff *, const char *, int, int); + + static int register_Btype (struct work_stuff *); +@@ -1283,6 +1290,13 @@ + memcpy (to->btypevec[i], from->btypevec[i], len); + } + ++ if (from->proctypevec) ++ { ++ to->proctypevec = XNEWVEC (int, from->proctypevec_size); ++ memcpy (to->proctypevec, from->proctypevec, ++ from->proctypevec_size * sizeof(int)); ++ } ++ + if (from->ntmpl_args) + to->tmpl_argvec = XNEWVEC (char *, from->ntmpl_args); + +@@ -1317,6 +1331,12 @@ + work -> typevec = NULL; + work -> typevec_size = 0; + } ++ if (work -> proctypevec != NULL) ++ { ++ free (work -> proctypevec); ++ work -> proctypevec = NULL; ++ work -> proctypevec_size = 0; ++ } + if (work->tmpl_argvec) + { + int i; +@@ -3535,6 +3555,8 @@ + do_type (struct work_stuff *work, const char **mangled, string *result) + { + int n; ++ int i; ++ int is_proctypevec; + int done; + int success; + string decl; +@@ -3547,6 +3569,7 @@ + + done = 0; + success = 1; ++ is_proctypevec = 0; + while (success && !done) + { + int member; +@@ -3599,7 +3622,14 @@ + success = 0; + } + else +- { ++ for (i = 0; i < work -> nproctypes; i++) ++ if (work -> proctypevec [i] == n) ++ success = 0; ++ ++ if (success) ++ { ++ is_proctypevec = 1; ++ push_processed_type (work, n); + remembered_type = work -> typevec[n]; + mangled = &remembered_type; + } +@@ -3820,6 +3850,9 @@ + string_delete (result); + string_delete (&decl); + ++ if (is_proctypevec) ++ pop_processed_type (work); ++ + if (success) + /* Assume an integral type, if we're not sure. */ + return (int) ((tk == tk_none) ? tk_integral : tk); +@@ -4233,6 +4266,34 @@ + } + + static void ++push_processed_type (struct work_stuff *work, int typevec_index) ++{ ++ if (work -> nproctypes >= work -> proctypevec_size) ++ { ++ if (work -> proctypevec_size == 0) ++ { ++ work -> proctypevec_size = 3; ++ work -> proctypevec = XNEWVEC (int, work -> proctypevec_size); ++ } ++ else ++ { ++ if (work -> proctypevec_size > INT_MAX / 2) ++ xmalloc_failed (INT_MAX); ++ work -> proctypevec_size *= 2; ++ work -> proctypevec ++ = XRESIZEVEC (int, work->proctypevec, work->proctypevec_size); ++ } ++ } ++ work -> proctypevec [work -> nproctypes ++] = typevec_index; ++} ++ ++static void ++pop_processed_type (struct work_stuff *work) ++{ ++ work -> nproctypes --; ++} ++ ++static void + remember_type (struct work_stuff *work, const char *start, int len) + { + char *tem; +@@ -4496,10 +4557,13 @@ + { + string_append (declp, ", "); + } ++ push_processed_type (work, t); + if (!do_arg (work, &tem, &arg)) + { ++ pop_processed_type (work); + return (0); + } ++ pop_processed_type (work); + if (PRINT_ARG_TYPES) + { + string_appends (declp, &arg); +--- a/libiberty/testsuite/demangle-expected ++++ b/libiberty/testsuite/demangle-expected +@@ -4174,3 +4174,8 @@ + + __t2m05B500000000000000000_ + __t2m05B500000000000000000_ ++# ++# Tests stack overflow PR71696 ++ ++__10%0__S4_0T0T0 ++%0<>::%0(%0<>) only in patch2: unchanged: --- binutils-2.22.orig/debian/patches/CVE-2016-XXXX.patch +++ binutils-2.22/debian/patches/CVE-2016-XXXX.patch @@ -0,0 +1,62 @@ +From 7e27a9d5f22f9f7ead11738b1546d0b5c737266b Mon Sep 17 00:00:00 2001 +From: Yuriy M. Kaminskiy <yum...@gmail.com> +Date: Tue, 4 Aug 2015 16:51:53 +0100 +Subject: [PATCH] Fix stack buffer overflows when parsing corrupt ihex files. + + PR binutils/18750 + * ihex.c (ihex_scan): Fixes incorrect escape sequence in error message + and stack overflow when char is signed and \200-\376 was in place of hex + digit; also fixes \377 was handled as EOF instead of "incorrect character". + (ihex_read_section): Changed for consistency. + (ihex_bad_byte): Prevent (now impossible to trigger) stack + overflow and incorrect escape sequence handling. + * srec.c (srec_bad_byte): Likewise. + + * readelf.c (process_mips_specific): Fix incorrect escape + sequence handling. +--- + bfd/ihex.c | 6 +++--- + bfd/srec.c | 2 +- + binutils/readelf.c | 2 +- + 5 files changed, 28 insertions(+), 5 deletions(-) + +--- a/bfd/ihex.c ++++ b/bfd/ihex.c +@@ -220,7 +220,7 @@ + char buf[10]; + + if (! ISPRINT (c)) +- sprintf (buf, "\\%03o", (unsigned int) c); ++ sprintf (buf, "\\%03o", (unsigned int) c & 0xff); + else + { + buf[0] = c; +@@ -277,7 +277,7 @@ + else + { + file_ptr pos; +- char hdr[8]; ++ unsigned char hdr[8]; + unsigned int i; + unsigned int len; + bfd_vma addr; +@@ -554,7 +554,7 @@ + error = FALSE; + while ((c = ihex_get_byte (abfd, &error)) != EOF) + { +- char hdr[8]; ++ unsigned char hdr[8]; + unsigned int len; + unsigned int type; + unsigned int i; +--- a/bfd/srec.c ++++ b/bfd/srec.c +@@ -251,7 +251,7 @@ + char buf[40]; + + if (! ISPRINT (c)) +- sprintf (buf, "\\%03o", (unsigned int) c); ++ sprintf (buf, "\\%03o", (unsigned int) c & 0xff); + else + { + buf[0] = c;