diffstat for perl-5.14.2 perl-5.14.2 changelog | 73 ++++++++++ control | 9 - patches/CVE-2012-6329.patch | 54 ++++++++ patches/CVE-2013-1667.patch | 171 +++++++++++++++++++++++++ patches/CVE-2013-7422.patch | 171 +++++++++++++++++++++++++ patches/CVE-2014-4330.patch | 261 +++++++++++++++++++++++++++++++++++++++ patches/CVE-2016-2381.patch | 104 +++++++++++++++ patches/fixes/CVE-2012-5195.diff | 32 ++++ patches/fixes/CVE-2012-5526.diff | 65 +++++++++ patches/series | 7 + 10 files changed, 944 insertions(+), 3 deletions(-) diff -Nru perl-5.14.2/debian/changelog perl-5.14.2/debian/changelog --- perl-5.14.2/debian/changelog 2011-11-28 20:05:37.000000000 +0000 +++ perl-5.14.2/debian/changelog 2016-03-01 16:03:26.000000000 +0000 @@ -1,3 +1,76 @@ +perl (5.14.2-6ubuntu2.5) precise-security; urgency=medium + + * SECURITY UPDATE: denial of service via regular expression invalid + backreference + - debian/patches/CVE-2013-7422.patch: properly handle big + backreferences in regcomp.c. + - CVE-2013-7422 + * SECURITY UPDATE: denial of service in Data::Dumper + - debian/patches/CVE-2014-4330.patch: limit recursion in MANIFEST, + dist/Data-Dumper/Dumper.pm, dist/Data-Dumper/Dumper.xs, + dist/Data-Dumper/t/recurse.t. + - CVE-2014-4330 + * SECURITY UPDATE: environment variable confusion issue + - debian/patches/CVE-2016-2381.patch: remove duplicate environment + variables from environ in perl.c. + - CVE-2016-2381 + + -- Marc Deslauriers Tue, 01 Mar 2016 11:02:10 -0500 + +perl (5.14.2-6ubuntu2.4) precise-security; urgency=medium + + * SECURITY UPDATE: arbitrary command execution via _compile function in + Maketext.pm + - debian/patches/CVE-2012-6329.patch: escape backslashes and reject + method names with colons or apostrophes in + dist/Locale-Maketext/lib/Locale/Maketext.pm. + - CVE-2012-6329 + + -- Marc Deslauriers Tue, 04 Feb 2014 16:02:26 -0500 + +perl (5.14.2-6ubuntu2.3) precise-security; urgency=low + + * SECURITY UPDATE: algorithmic complexity attack on hash keys + - debian/patches/CVE-2013-1667.patch: fix hsplit() in hv.c, fix tests + in ext/Hash-Util-FieldHash/t/10_hash.t, t/op/hash.t. + - CVE-2013-1667 + + -- Marc Deslauriers Mon, 18 Mar 2013 10:48:33 -0400 + +perl (5.14.2-6ubuntu2.2) precise-security; urgency=low + + * SECURITY UPDATE: Heap overflow in "x" operator (LP: #1069034) + - CVE-2012-5195 + * SECURITY UPDATE: CGI.pm improper cookie and p3p CRLF escaping + - CVE-2012-5526 + + -- Seth Arnold Mon, 26 Nov 2012 11:27:58 -0800 + +perl (5.14.2-6ubuntu2.1) precise-proposed; urgency=low + + * Add versioned conflict against libxml-sax-perl to ensure it's upgraded + to a version that doesn't use Files::Basename or is removed from the + system. This fixes upgrades from 10.04. (LP: #990256) + + -- Stéphane Graber Fri, 10 Aug 2012 15:51:31 -0400 + +perl (5.14.2-6ubuntu2) precise; urgency=low + + * Have perl, perl-modules, and perl-base conflict with versions of + mono-gac requiring File::Basename, to ensure a smooth upgrade from lucid. + LP: #948848. + + -- Steve Langasek Fri, 23 Mar 2012 07:59:20 -0700 + +perl (5.14.2-6ubuntu1) precise; urgency=low + + * debian/control: Add doc-base conflict also to perl, perl-modules, and + libperl5.14. Otherwise they can get unpacked before upgrading perl-base + and doc-base and thus still cause symbol lookup errors in the doc-base + trigger. (Closes: #648954, LP: #902553) + + -- Martin Pitt Fri, 16 Dec 2011 12:25:31 +0100 + perl (5.14.2-6) unstable; urgency=low [ Niko Tyni ] diff -Nru perl-5.14.2/debian/control perl-5.14.2/debian/control --- perl-5.14.2/debian/control 2011-11-28 20:05:37.000000000 +0000 +++ perl-5.14.2/debian/control 2012-08-10 20:58:36.000000000 +0000 @@ -1,7 +1,8 @@ Source: perl Section: perl Priority: standard -Maintainer: Niko Tyni +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: Niko Tyni Uploaders: Dominic Hargreaves Standards-Version: 3.9.2 Build-Depends: file, cpio (>= 2.6-5), libdb-dev, libgdbm-dev, netbase [!hurd-any], @@ -18,7 +19,7 @@ Pre-Depends: ${shlibs:Depends}, dpkg (>= 1.14.20) Conflicts: safe-rm (<< 0.8), update-inetd (<< 4.41), - doc-base (<< 0.10.3) + doc-base (<< 0.10.3), mono-gac (<< 2.10.8.1-1ubuntu1), libxml-sax-perl (<< 0.99+dfsg-1ubuntu0.1) Breaks: autoconf2.13 (<< 2.13-45), libscalar-list-utils-perl (<< 1:1.23), libfile-spec-perl (<< 3.3300), @@ -219,6 +220,7 @@ libfile-path-perl, libshell-perl, libperl4-corelibs-perl +Conflicts: doc-base (<< 0.10.3), mono-gac (<< 2.10.8.1-1), libxml-sax-perl (<< 0.99+dfsg-1ubuntu0.1) Description: Core Perl modules Architecture independent Perl modules. These modules are part of Perl and required if the `perl' package is installed. @@ -247,6 +249,7 @@ Priority: optional Architecture: any Depends: ${shlibs:Depends}, perl-base (= ${binary:Version}) +Conflicts: doc-base (<< 0.10.3), libxml-sax-perl (<< 0.99+dfsg-1ubuntu0.1) Replaces: perl-base (<= 5.8.7-4) Description: shared Perl library This package is required by programs which embed a Perl interpreter to @@ -268,7 +271,7 @@ Priority: standard Architecture: any Depends: perl-base (= ${binary:Version}), perl-modules (>= ${source:Version}), ${shlibs:Depends} -Conflicts: libjson-pp-perl (<< 2.27200-2) +Conflicts: libjson-pp-perl (<< 2.27200-2), doc-base (<< 0.10.3), mono-gac (<< 2.10.8.1-1), libxml-sax-perl (<< 0.99+dfsg-1ubuntu0.1) Breaks: perl-doc (<< ${Upstream-Version}-1), libdigest-md5-perl (<< 2.51), libmime-base64-perl (<< 3.13), diff -Nru perl-5.14.2/debian/patches/CVE-2012-6329.patch perl-5.14.2/debian/patches/CVE-2012-6329.patch --- perl-5.14.2/debian/patches/CVE-2012-6329.patch 1970-01-01 00:00:00.000000000 +0000 +++ perl-5.14.2/debian/patches/CVE-2012-6329.patch 2014-02-04 21:02:20.000000000 +0000 @@ -0,0 +1,54 @@ +Description: fix arbitrary command execution via _compile function in Maketext.pm +Origin: backport, http://perl5.git.perl.org/perl.git/commit/1735f6f53ca19f99c6e9e39496c486af323ba6a8 +Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=695224 + +Index: perl-5.14.2/dist/Locale-Maketext/lib/Locale/Maketext.pm +=================================================================== +--- perl-5.14.2.orig/dist/Locale-Maketext/lib/Locale/Maketext.pm 2011-09-19 09:18:22.000000000 -0400 ++++ perl-5.14.2/dist/Locale-Maketext/lib/Locale/Maketext.pm 2014-02-04 15:54:01.434100335 -0500 +@@ -625,21 +625,9 @@ + # 0-length method name means to just interpolate: + push @code, ' ('; + } +- elsif($m =~ /^\w+(?:\:\:\w+)*$/s +- and $m !~ m/(?:^|\:)\d/s +- # exclude starting a (sub)package or symbol with a digit ++ elsif($m =~ /^\w+$/s ++ # exclude anything fancy, especially fully-qualified module names + ) { +- # Yes, it even supports the demented (and undocumented?) +- # $obj->Foo::bar(...) syntax. +- $target->_die_pointing( +- $string_to_compile, q{Can't use "SUPER::" in a bracket-group method}, +- 2 + length($c[-1]) +- ) +- if $m =~ m/^SUPER::/s; +- # Because for SUPER:: to work, we'd have to compile this into +- # the right package, and that seems just not worth the bother, +- # unless someone convinces me otherwise. +- + push @code, ' $_[0]->' . $m . '('; + } + else { +@@ -693,7 +681,9 @@ + elsif(substr($1,0,1) ne '~') { + # it's stuff not containing "~" or "[" or "]" + # i.e., a literal blob +- $c[-1] .= $1; ++ my $text = $1; ++ $text =~ s/\\/\\\\/g; ++ $c[-1] .= $text; + + } + elsif($1 eq '~~') { # "~~" +@@ -731,7 +721,9 @@ + else { + # It's a "~X" where X is not a special character. + # Consider it a literal ~ and X. +- $c[-1] .= $1; ++ my $text = $1; ++ $text =~ s/\\/\\\\/g; ++ $c[-1] .= $text; + } + } + } diff -Nru perl-5.14.2/debian/patches/CVE-2013-1667.patch perl-5.14.2/debian/patches/CVE-2013-1667.patch --- perl-5.14.2/debian/patches/CVE-2013-1667.patch 1970-01-01 00:00:00.000000000 +0000 +++ perl-5.14.2/debian/patches/CVE-2013-1667.patch 2013-03-18 14:48:27.000000000 +0000 @@ -0,0 +1,171 @@ +From d59e31fc729d8a39a774f03bc6bc457029a7aef2 Mon Sep 17 00:00:00 2001 +From: Yves Orton +Date: Tue, 12 Feb 2013 10:53:05 +0100 +Subject: [PATCH] Prevent premature hsplit() calls, and only trigger REHASH after hsplit() + +Triggering a hsplit due to long chain length allows an attacker +to create a carefully chosen set of keys which can cause the hash +to use 2 * (2**32) * sizeof(void *) bytes ram. AKA a DOS via memory +exhaustion. Doing so also takes non trivial time. + +Eliminating this check, and only inspecting chain length after a +normal hsplit() (triggered when keys>buckets) prevents the attack +entirely, and makes such attacks relatively benign. + +(cherry picked from commit f1220d61455253b170e81427c9d0357831ca0fac) +--- + ext/Hash-Util-FieldHash/t/10_hash.t | 18 ++++++++++++++++-- + hv.c | 35 ++++++++--------------------------- + t/op/hash.t | 20 +++++++++++++++++--- + 3 files changed, 41 insertions(+), 32 deletions(-) + +diff --git a/ext/Hash-Util-FieldHash/t/10_hash.t b/ext/Hash-Util-FieldHash/t/10_hash.t +index 2cfb4e8..d58f053 100644 +--- a/ext/Hash-Util-FieldHash/t/10_hash.t ++++ b/ext/Hash-Util-FieldHash/t/10_hash.t +@@ -38,15 +38,29 @@ use constant START => "a"; + + # some initial hash data + fieldhash my %h2; +-%h2 = map {$_ => 1} 'a'..'cc'; ++my $counter= "a"; ++$h2{$counter++}++ while $counter ne 'cd'; + + ok (!Internals::HvREHASH(%h2), + "starting with pre-populated non-pathological hash (rehash flag if off)"); + + my @keys = get_keys(\%h2); ++my $buckets= buckets(\%h2); + $h2{$_}++ for @keys; ++$h2{$counter++}++ while buckets(\%h2) == $buckets; # force a split + ok (Internals::HvREHASH(%h2), +- scalar(@keys) . " colliding into the same bucket keys are triggering rehash"); ++ scalar(@keys) . " colliding into the same bucket keys are triggering rehash after split"); ++ ++# returns the number of buckets in a hash ++sub buckets { ++ my $hr = shift; ++ my $keys_buckets= scalar(%$hr); ++ if ($keys_buckets=~m!/([0-9]+)\z!) { ++ return 0+$1; ++ } else { ++ return 8; ++ } ++} + + sub get_keys { + my $hr = shift; +diff --git a/hv.c b/hv.c +index 2be1feb..abb9d76 100644 +--- a/hv.c ++++ b/hv.c +@@ -35,7 +35,8 @@ holds the key and hash value. + #define PERL_HASH_INTERNAL_ACCESS + #include "perl.h" + +-#define HV_MAX_LENGTH_BEFORE_SPLIT 14 ++#define HV_MAX_LENGTH_BEFORE_REHASH 14 ++#define SHOULD_DO_HSPLIT(xhv) ((xhv)->xhv_keys > (xhv)->xhv_max) /* HvTOTALKEYS(hv) > HvMAX(hv) */ + + static const char S_strtab_error[] + = "Cannot modify shared string table in hv_%s"; +@@ -794,29 +795,9 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, + if (masked_flags & HVhek_ENABLEHVKFLAGS) + HvHASKFLAGS_on(hv); + +- { +- const HE *counter = HeNEXT(entry); +- +- xhv->xhv_keys++; /* HvTOTALKEYS(hv)++ */ +- if (!counter) { /* initial entry? */ +- } else if (xhv->xhv_keys > xhv->xhv_max) { +- /* Use only the old HvKEYS(hv) > HvMAX(hv) condition to limit +- bucket splits on a rehashed hash, as we're not going to +- split it again, and if someone is lucky (evil) enough to +- get all the keys in one list they could exhaust our memory +- as we repeatedly double the number of buckets on every +- entry. Linear search feels a less worse thing to do. */ +- hsplit(hv); +- } else if(!HvREHASH(hv)) { +- U32 n_links = 1; +- +- while ((counter = HeNEXT(counter))) +- n_links++; +- +- if (n_links > HV_MAX_LENGTH_BEFORE_SPLIT) { +- hsplit(hv); +- } +- } ++ xhv->xhv_keys++; /* HvTOTALKEYS(hv)++ */ ++ if ( SHOULD_DO_HSPLIT(xhv) ) { ++ hsplit(hv); + } + + if (return_svp) { +@@ -1192,7 +1173,7 @@ S_hsplit(pTHX_ HV *hv) + + + /* Pick your policy for "hashing isn't working" here: */ +- if (longest_chain <= HV_MAX_LENGTH_BEFORE_SPLIT /* split worked? */ ++ if (longest_chain <= HV_MAX_LENGTH_BEFORE_REHASH /* split worked? */ + || HvREHASH(hv)) { + return; + } +@@ -2831,8 +2812,8 @@ S_share_hek_flags(pTHX_ const char *str, I32 len, register U32 hash, int flags) + + xhv->xhv_keys++; /* HvTOTALKEYS(hv)++ */ + if (!next) { /* initial entry? */ +- } else if (xhv->xhv_keys > xhv->xhv_max /* HvKEYS(hv) > HvMAX(hv) */) { +- hsplit(PL_strtab); ++ } else if ( SHOULD_DO_HSPLIT(xhv) ) { ++ hsplit(PL_strtab); + } + } + +diff --git a/t/op/hash.t b/t/op/hash.t +index 278bea7..201260a 100644 +--- a/t/op/hash.t ++++ b/t/op/hash.t +@@ -39,22 +39,36 @@ use constant THRESHOLD => 14; + use constant START => "a"; + + # some initial hash data +-my %h2 = map {$_ => 1} 'a'..'cc'; ++my %h2; ++my $counter= "a"; ++$h2{$counter++}++ while $counter ne 'cd'; + + ok (!Internals::HvREHASH(%h2), + "starting with pre-populated non-pathological hash (rehash flag if off)"); + + my @keys = get_keys(\%h2); ++my $buckets= buckets(\%h2); + $h2{$_}++ for @keys; ++$h2{$counter++}++ while buckets(\%h2) == $buckets; # force a split + ok (Internals::HvREHASH(%h2), +- scalar(@keys) . " colliding into the same bucket keys are triggering rehash"); ++ scalar(@keys) . " colliding into the same bucket keys are triggering rehash after split"); ++ ++# returns the number of buckets in a hash ++sub buckets { ++ my $hr = shift; ++ my $keys_buckets= scalar(%$hr); ++ if ($keys_buckets=~m!/([0-9]+)\z!) { ++ return 0+$1; ++ } else { ++ return 8; ++ } ++} + + sub get_keys { + my $hr = shift; + + # the minimum of bits required to mount the attack on a hash + my $min_bits = log(THRESHOLD)/log(2); +- + # if the hash has already been populated with a significant amount + # of entries the number of mask bits can be higher + my $keys = scalar keys %$hr; +-- +1.7.4.1 + diff -Nru perl-5.14.2/debian/patches/CVE-2013-7422.patch perl-5.14.2/debian/patches/CVE-2013-7422.patch --- perl-5.14.2/debian/patches/CVE-2013-7422.patch 1970-01-01 00:00:00.000000000 +0000 +++ perl-5.14.2/debian/patches/CVE-2013-7422.patch 2016-03-01 15:56:35.000000000 +0000 @@ -0,0 +1,171 @@ +Backport of: + +From 0c2990d652e985784f095bba4bc356481a66aa06 Mon Sep 17 00:00:00 2001 +From: David Mitchell +Date: Wed, 16 Oct 2013 13:59:12 +0100 +Subject: [PATCH] [perl #119505] Segfault from bad backreference + +The code that parses regex backrefs (or ambiguous backref/octal) such as +\123, did a simple atoi(), which could wrap round to negative values on +long digit strings and cause seg faults. + +Include a check on the length of the digit string, and if greater than 9 +digits, assume it can never be a valid backref (obviating the need for the +atoi() call). + +I've also simplified the code a bit, putting most of the \g handling code +into a single block, rather than doing multiple "if (isg) {...}". +--- + regcomp.c | 64 ++++++++++++++++++++++++++++++++++++++++++----------------- + t/re/re_tests | 41 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 87 insertions(+), 18 deletions(-) + +Index: perl-5.14.2/regcomp.c +=================================================================== +--- perl-5.14.2.orig/regcomp.c 2016-03-01 10:51:35.984873567 -0500 ++++ perl-5.14.2/regcomp.c 2016-03-01 10:56:29.536041619 -0500 +@@ -7854,6 +7854,21 @@ + } + + ++/* return atoi(p), unless it's too big to sensibly be a backref, ++ * in which case return I32_MAX (rather than possibly 32-bit wrapping) */ ++ ++static I32 ++S_backref_value(char *p) ++{ ++ char *q = p; ++ ++ for (;isDIGIT(*q); q++); /* calculate length of num */ ++ if (q - p == 0 || q - p > 9) ++ return I32_MAX; ++ return atoi(p); ++} ++ ++ + /* + - regatom - the lowest level + +@@ -8324,10 +8339,11 @@ + case '5': case '6': case '7': case '8': case '9': + { + I32 num; +- bool isg = *RExC_parse == 'g'; +- bool isrel = 0; + bool hasbrace = 0; +- if (isg) { ++ ++ if (*RExC_parse == 'g') { ++ bool isrel = 0; ++ + RExC_parse++; + if (*RExC_parse == '{') { + RExC_parse++; +@@ -8341,18 +8357,35 @@ + if (isrel) RExC_parse--; + RExC_parse -= 2; + goto parse_named_seq; +- } } +- num = atoi(RExC_parse); +- if (isg && num == 0) +- vFAIL("Reference to invalid group 0"); +- if (isrel) { +- num = RExC_npar - num; +- if (num < 1) +- vFAIL("Reference to nonexistent or unclosed group"); ++ } ++ ++ num = S_backref_value(RExC_parse); ++ if (num == 0) ++ vFAIL("Reference to invalid group 0"); ++ else if (num == I32_MAX) { ++ if (isDIGIT(*RExC_parse)) ++ vFAIL("Reference to nonexistent group"); ++ else ++ vFAIL("Unterminated \\g... pattern"); ++ } ++ ++ if (isrel) { ++ num = RExC_npar - num; ++ if (num < 1) ++ vFAIL("Reference to nonexistent or unclosed group"); ++ } + } +- if (!isg && num > 9 && num >= RExC_npar) +- goto defchar; +- else { ++ else { ++ num = S_backref_value(RExC_parse); ++ /* bare \NNN might be backref or octal */ ++ if (num == I32_MAX || (num > 9 && num >= RExC_npar)) ++ /* Probably a character specified in octal, e.g. \35 */ ++ goto defchar; ++ } ++ ++ /* at this point RExC_parse definitely points to a backref ++ * number */ ++ { + char * const parse_start = RExC_parse - 1; /* MJD */ + while (isDIGIT(*RExC_parse)) + RExC_parse++; +@@ -8588,7 +8621,7 @@ + case '0': case '1': case '2': case '3':case '4': + case '5': case '6': case '7': case '8':case '9': + if (*p == '0' || +- (isDIGIT(p[1]) && atoi(p) >= RExC_npar)) ++ (isDIGIT(p[1]) && S_backref_value(p) >= RExC_npar)) + { + I32 flags = PERL_SCAN_SILENT_ILLDIGIT; + STRLEN numlen = 3; +Index: perl-5.14.2/t/re/re_tests +=================================================================== +--- perl-5.14.2.orig/t/re/re_tests 2016-03-01 10:51:35.984873567 -0500 ++++ perl-5.14.2/t/re/re_tests 2016-03-01 10:51:35.980873513 -0500 +@@ -1471,6 +1471,47 @@ + [a\o{400}] \x{100} y $& \x{100} + [a\o{1000}] \x{200} y $& \x{200} + ++# avoid problems with 32-bit signed integer overflow ++ ++(.)\g2147483648} x c - Reference to nonexistent group in regex ++(.)\g2147483649} x c - Reference to nonexistent group in regex ++(.)\g2147483650} x c - Reference to nonexistent group in regex ++(.)\g4294967296} x c - Reference to nonexistent group in regex ++(.)\g4294967297} x c - Reference to nonexistent group in regex ++(.)\g4294967298} x c - Reference to nonexistent group in regex ++a(.)\g2147483648} x c - Reference to nonexistent group in regex ++a(.)\g2147483649} x c - Reference to nonexistent group in regex ++a(.)\g2147483650} x c - Reference to nonexistent group in regex ++a(.)\g4294967296} x c - Reference to nonexistent group in regex ++a(.)\g4294967297} x c - Reference to nonexistent group in regex ++a(.)\g4294967298} x c - Reference to nonexistent group in regex ++ ++(.)\g{2147483648} x c - Reference to nonexistent group in regex ++(.)\g{2147483649} x c - Reference to nonexistent group in regex ++(.)\g{2147483650} x c - Reference to nonexistent group in regex ++(.)\g{4294967296} x c - Reference to nonexistent group in regex ++(.)\g{4294967297} x c - Reference to nonexistent group in regex ++(.)\g{4294967298} x c - Reference to nonexistent group in regex ++a(.)\g{2147483648} x c - Reference to nonexistent group in regex ++a(.)\g{2147483649} x c - Reference to nonexistent group in regex ++a(.)\g{2147483650} x c - Reference to nonexistent group in regex ++a(.)\g{4294967296} x c - Reference to nonexistent group in regex ++a(.)\g{4294967297} x c - Reference to nonexistent group in regex ++a(.)\g{4294967298} x c - Reference to nonexistent group in regex ++ ++(.)\2147483648 b\o{214}7483648 y $1 b ++(.)\2147483649 b\o{214}7483649 y $1 b ++(.)\2147483650 b\o{214}7483650 y $1 b ++(.)\4294967296 b\o{42}94967296 y $1 b ++(.)\4294967297 b\o{42}94967297 y $1 b ++(.)\4294967298 b\o{42}94967298 y $1 b ++a(.)\2147483648 ab\o{214}7483648 y $1 b ++a(.)\2147483649 ab\o{214}7483649 y $1 b ++a(.)\2147483650 ab\o{214}7483650 y $1 b ++a(.)\4294967296 ab\o{42}94967296 y $1 b ++a(.)\4294967297 ab\o{42}94967297 y $1 b ++a(.)\4294967298 ab\o{42}94967298 y $1 b ++ + # The below was inserting a NULL into the character class. + [\8\9] \000 n - - + [\8\9] 8 y $& 8 diff -Nru perl-5.14.2/debian/patches/CVE-2014-4330.patch perl-5.14.2/debian/patches/CVE-2014-4330.patch --- perl-5.14.2/debian/patches/CVE-2014-4330.patch 1970-01-01 00:00:00.000000000 +0000 +++ perl-5.14.2/debian/patches/CVE-2014-4330.patch 2016-03-01 17:09:34.000000000 +0000 @@ -0,0 +1,261 @@ +Backport of: + +From 19be3be6968e2337bcdfe480693fff795ecd1304 Mon Sep 17 00:00:00 2001 +From: Tony Cook +Date: Mon, 30 Jun 2014 12:16:03 +1000 +Subject: [PATCH] don't recurse infinitely in Data::Dumper + +Add a configuration variable/option to limit recursion when dumping +deep data structures. + +Defaults the limit to 1000, which can be reduced or increase, or +eliminated by setting it to 0. + +This patch addresses CVE-2014-4330. This bug was found and +reported by: LSE Leading Security Experts GmbH employee Markus +Vervier. +--- + MANIFEST | 1 + + dist/Data-Dumper/Dumper.pm | 25 +++++++++++++++++++++++- + dist/Data-Dumper/Dumper.xs | 32 ++++++++++++++++++++++--------- + dist/Data-Dumper/t/recurse.t | 45 ++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 93 insertions(+), 10 deletions(-) + create mode 100644 dist/Data-Dumper/t/recurse.t + +Index: perl-5.14.2/MANIFEST +=================================================================== +--- perl-5.14.2.orig/MANIFEST 2016-03-01 12:09:19.091083837 -0500 ++++ perl-5.14.2/MANIFEST 2016-03-01 12:09:31.367244883 -0500 +@@ -2900,6 +2900,7 @@ + dist/Data-Dumper/t/overload.t See if Data::Dumper works for overloaded data + dist/Data-Dumper/t/pair.t See if Data::Dumper pair separator works + dist/Data-Dumper/t/perl-74170.t Regression test for stack reallocation ++dist/Data-Dumper/t/recurse.t See if Data::Dumper::Maxrecurse works + dist/Data-Dumper/t/terse.t See if Data::Dumper terse option works + dist/Devel-SelfStubber/lib/Devel/SelfStubber.pm Generate stubs for SelfLoader.pm + dist/Devel-SelfStubber/t/Devel-SelfStubber.t See if Devel::SelfStubber works +Index: perl-5.14.2/dist/Data-Dumper/Dumper.pm +=================================================================== +--- perl-5.14.2.orig/dist/Data-Dumper/Dumper.pm 2016-03-01 12:09:19.091083837 -0500 ++++ perl-5.14.2/dist/Data-Dumper/Dumper.pm 2016-03-01 12:09:19.091083837 -0500 +@@ -53,6 +53,7 @@ + $Useperl = 0 unless defined $Useperl; + $Sortkeys = 0 unless defined $Sortkeys; + $Deparse = 0 unless defined $Deparse; ++$Maxrecurse = 1000 unless defined $Maxrecurse; + + # + # expects an arrayref of values to be dumped. +@@ -89,6 +90,7 @@ + 'bless' => $Bless, # keyword to use for "bless" + # expdepth => $Expdepth, # cutoff depth for explicit dumping + maxdepth => $Maxdepth, # depth beyond which we give up ++ maxrecurse => $Maxrecurse, # depth beyond which we abort + useperl => $Useperl, # use the pure Perl implementation + sortkeys => $Sortkeys, # flag or filter for sorting hash keys + deparse => $Deparse, # use B::Deparse for coderefs +@@ -339,6 +341,12 @@ + return qq['$val']; + } + ++ # avoid recursing infinitely [perl #122111] ++ if ($s->{maxrecurse} > 0 ++ and $s->{level} >= $s->{maxrecurse}) { ++ die "Recursion limit of $s->{maxrecurse} exceeded"; ++ } ++ + # we have a blessed ref + if ($realpack and !$no_bless) { + $out = $s->{'bless'} . '( '; +@@ -650,6 +658,11 @@ + defined($v) ? (($s->{'maxdepth'} = $v), return $s) : $s->{'maxdepth'}; + } + ++sub Maxrecurse { ++ my($s, $v) = @_; ++ defined($v) ? (($s->{'maxrecurse'} = $v), return $s) : $s->{'maxrecurse'}; ++} ++ + sub Useperl { + my($s, $v) = @_; + defined($v) ? (($s->{'useperl'} = $v), return $s) : $s->{'useperl'}; +@@ -1024,6 +1037,16 @@ + + =item * + ++$Data::Dumper::Maxrecurse I $I->Maxrecurse(I<[NEWVAL]>) ++ ++Can be set to a positive integer that specifies the depth beyond which ++recursion into a structure will throw an exception. This is intended ++as a security measure to prevent perl running out of stack space when ++dumping an excessively deep structure. Can be set to 0 to remove the ++limit. Default is 1000. ++ ++=item * ++ + $Data::Dumper::Useperl I $I->Useperl(I<[NEWVAL]>) + + Can be set to a boolean value which controls whether the pure Perl +Index: perl-5.14.2/dist/Data-Dumper/Dumper.xs +=================================================================== +--- perl-5.14.2.orig/dist/Data-Dumper/Dumper.xs 2016-03-01 12:09:19.091083837 -0500 ++++ perl-5.14.2/dist/Data-Dumper/Dumper.xs 2016-03-01 12:09:19.091083837 -0500 +@@ -22,7 +22,7 @@ + SV *pad, SV *xpad, SV *apad, SV *sep, SV *pair, + SV *freezer, SV *toaster, + I32 purity, I32 deepcopy, I32 quotekeys, SV *bless, +- I32 maxdepth, SV *sortkeys); ++ I32 maxdepth, SV *sortkeys, IV maxrecurse); + + #ifndef HvNAME_get + #define HvNAME_get HvNAME +@@ -266,7 +266,7 @@ + DD_dump(pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval, HV *seenhv, + AV *postav, I32 *levelp, I32 indent, SV *pad, SV *xpad, + SV *apad, SV *sep, SV *pair, SV *freezer, SV *toaster, I32 purity, +- I32 deepcopy, I32 quotekeys, SV *bless, I32 maxdepth, SV *sortkeys) ++ I32 deepcopy, I32 quotekeys, SV *bless, I32 maxdepth, SV *sortkeys, IV maxrecurse) + { + char tmpbuf[128]; + U32 i; +@@ -443,6 +443,10 @@ + return 1; + } + ++ if (maxrecurse > 0 && *levelp >= maxrecurse) { ++ croak("Recursion limit of %" IVdf " exceeded", maxrecurse); ++ } ++ + if (realpack && !no_bless) { /* we have a blessed ref */ + STRLEN blesslen; + const char * const blessstr = SvPV(bless, blesslen); +@@ -489,7 +493,7 @@ + DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv, + postav, levelp, indent, pad, xpad, apad, sep, pair, + freezer, toaster, purity, deepcopy, quotekeys, bless, +- maxdepth, sortkeys); ++ maxdepth, sortkeys, maxrecurse); + sv_catpvn(retval, ")}", 2); + } /* plain */ + else { +@@ -497,7 +501,7 @@ + DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv, + postav, levelp, indent, pad, xpad, apad, sep, pair, + freezer, toaster, purity, deepcopy, quotekeys, bless, +- maxdepth, sortkeys); ++ maxdepth, sortkeys, maxrecurse); + } + SvREFCNT_dec(namesv); + } +@@ -509,7 +513,7 @@ + DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv, + postav, levelp, indent, pad, xpad, apad, sep, pair, + freezer, toaster, purity, deepcopy, quotekeys, bless, +- maxdepth, sortkeys); ++ maxdepth, sortkeys, maxrecurse); + SvREFCNT_dec(namesv); + } + else if (realtype == SVt_PVAV) { +@@ -582,7 +586,7 @@ + DD_dump(aTHX_ elem, iname, ilen, retval, seenhv, postav, + levelp, indent, pad, xpad, apad, sep, pair, + freezer, toaster, purity, deepcopy, quotekeys, bless, +- maxdepth, sortkeys); ++ maxdepth, sortkeys, maxrecurse); + if (ix < ixmax) + sv_catpvn(retval, ",", 1); + } +@@ -789,7 +793,7 @@ + DD_dump(aTHX_ hval, SvPVX_const(sname), SvCUR(sname), retval, seenhv, + postav, levelp, indent, pad, xpad, newapad, sep, pair, + freezer, toaster, purity, deepcopy, quotekeys, bless, +- maxdepth, sortkeys); ++ maxdepth, sortkeys, maxrecurse); + SvREFCNT_dec(sname); + Safefree(nkey_buffer); + if (indent >= 2) +@@ -969,7 +973,7 @@ + seenhv, postav, &nlevel, indent, pad, xpad, + newapad, sep, pair, freezer, toaster, purity, + deepcopy, quotekeys, bless, maxdepth, +- sortkeys); ++ sortkeys, maxrecurse); + SvREFCNT_dec(e); + } + } +@@ -1035,6 +1039,7 @@ + SV *val, *name, *pad, *xpad, *apad, *sep, *pair, *varname; + SV *freezer, *toaster, *bless, *sortkeys; + I32 purity, deepcopy, quotekeys, maxdepth = 0; ++ IV maxrecurse = 1000; + char tmpbuf[1024]; + I32 gimme = GIMME; + +@@ -1117,6 +1122,8 @@ + bless = *svp; + if ((svp = hv_fetch(hv, "maxdepth", 8, FALSE))) + maxdepth = SvIV(*svp); ++ if ((svp = hv_fetch(hv, "maxrecurse", 10, FALSE))) ++ maxrecurse = SvIV(*svp); + if ((svp = hv_fetch(hv, "sortkeys", 8, FALSE))) { + sortkeys = *svp; + if (! SvTRUE(sortkeys)) +@@ -1196,7 +1203,7 @@ + DD_dump(aTHX_ val, SvPVX_const(name), SvCUR(name), valstr, seenhv, + postav, &level, indent, pad, xpad, newapad, sep, pair, + freezer, toaster, purity, deepcopy, quotekeys, +- bless, maxdepth, sortkeys); ++ bless, maxdepth, sortkeys, maxrecurse); + SPAGAIN; + + if (indent >= 2 && !terse) +Index: perl-5.14.2/dist/Data-Dumper/t/recurse.t +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ perl-5.14.2/dist/Data-Dumper/t/recurse.t 2016-03-01 12:09:19.091083837 -0500 +@@ -0,0 +1,45 @@ ++#!perl ++ ++# Test the Maxrecurse option ++ ++use strict; ++use Test::More tests => 32; ++use Data::Dumper; ++ ++SKIP: { ++ skip "no XS available", 16 ++ if $Data::Dumper::Useperl; ++ local $Data::Dumper::Useperl = 1; ++ test_recursion(); ++} ++ ++test_recursion(); ++ ++sub test_recursion { ++ my $pp = $Data::Dumper::Useperl ? "pure perl" : "XS"; ++ $Data::Dumper::Purity = 1; # make sure this has no effect ++ $Data::Dumper::Indent = 0; ++ $Data::Dumper::Maxrecurse = 1; ++ is(eval { Dumper([]) }, '$VAR1 = [];', "$pp: maxrecurse 1, []"); ++ is(eval { Dumper([[]]) }, undef, "$pp: maxrecurse 1, [[]]"); ++ ok($@, "exception thrown"); ++ is(eval { Dumper({}) }, '$VAR1 = {};', "$pp: maxrecurse 1, {}"); ++ is(eval { Dumper({ a => 1 }) }, q($VAR1 = {'a' => 1};), ++ "$pp: maxrecurse 1, { a => 1 }"); ++ is(eval { Dumper({ a => {} }) }, undef, "$pp: maxrecurse 1, { a => {} }"); ++ ok($@, "exception thrown"); ++ is(eval { Dumper(\1) }, "\$VAR1 = \\1;", "$pp: maxrecurse 1, \\1"); ++ is(eval { Dumper(\\1) }, undef, "$pp: maxrecurse 1, \\1"); ++ ok($@, "exception thrown"); ++ $Data::Dumper::Maxrecurse = 3; ++ is(eval { Dumper(\1) }, "\$VAR1 = \\1;", "$pp: maxrecurse 3, \\1"); ++ is(eval { Dumper(\(my $s = {})) }, "\$VAR1 = \\{};", "$pp: maxrecurse 3, \\{}"); ++ is(eval { Dumper(\(my $s = { a => [] })) }, "\$VAR1 = \\{'a' => []};", ++ "$pp: maxrecurse 3, \\{ a => [] }"); ++ is(eval { Dumper(\(my $s = { a => [{}] })) }, undef, ++ "$pp: maxrecurse 3, \\{ a => [{}] }"); ++ ok($@, "exception thrown"); ++ $Data::Dumper::Maxrecurse = 0; ++ is(eval { Dumper([[[[[]]]]]) }, q($VAR1 = [[[[[]]]]];), ++ "$pp: check Maxrecurse doesn't set limit to 0 recursion"); ++} diff -Nru perl-5.14.2/debian/patches/CVE-2016-2381.patch perl-5.14.2/debian/patches/CVE-2016-2381.patch --- perl-5.14.2/debian/patches/CVE-2016-2381.patch 1970-01-01 00:00:00.000000000 +0000 +++ perl-5.14.2/debian/patches/CVE-2016-2381.patch 2016-03-01 16:50:52.000000000 +0000 @@ -0,0 +1,104 @@ +Backport of: + +From c709c3e2d95829957635f2a0c24fdc49237f1869 Mon Sep 17 00:00:00 2001 +From: Tony Cook +Date: Wed, 27 Jan 2016 11:52:15 +1100 +Subject: [PATCH 1/2] remove duplicate environment variables from environ + +If we see duplicate environment variables while iterating over +environ[]: + +a) make sure we use the same value in %ENV that getenv() returns. + +Previously on a duplicate, %ENV would have the last entry for the name +from environ[], but a typical getenv() would return the first entry. + +Rather than assuming all getenv() implementations return the first entry +explicitly call getenv() to ensure they agree. + +b) remove duplicate entries from environ + +Previously if there was a duplicate definition for a name in environ[] +setting that name in %ENV could result in an unsafe value being passed +to a child process, so ensure environ[] has no duplicates. +--- + perl.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 49 insertions(+), 2 deletions(-) + +Index: perl-5.14.2/perl.c +=================================================================== +--- perl-5.14.2.orig/perl.c 2016-03-01 11:02:04.479786697 -0500 ++++ perl-5.14.2/perl.c 2016-03-01 11:02:04.479786697 -0500 +@@ -4121,23 +4121,70 @@ + } + if (env) { + char *s, *old_var; ++ STRLEN nlen; + SV *sv; ++ HV *dups = newHV(); ++ + for (; *env; env++) { + old_var = *env; + + if (!(s = strchr(old_var,'=')) || s == old_var) + continue; ++ nlen = s - old_var; + + #if defined(MSDOS) && !defined(DJGPP) + *s = '\0'; + (void)strupr(old_var); + *s = '='; + #endif +- sv = newSVpv(s+1, 0); +- (void)hv_store(hv, old_var, s - old_var, sv, 0); ++ if (hv_exists(hv, old_var, nlen)) { ++ const char *name = savepvn(old_var, nlen); ++ ++ /* make sure we use the same value as getenv(), otherwise code that ++ uses getenv() (like setlocale()) might see a different value to %ENV ++ */ ++ sv = newSVpv(PerlEnv_getenv(name), 0); ++ ++ /* keep a count of the dups of this name so we can de-dup environ later */ ++ if (hv_exists(dups, name, nlen)) ++ ++SvIVX(*hv_fetch(dups, name, nlen, 0)); ++ else ++ (void)hv_store(dups, name, nlen, newSViv(1), 0); ++ ++ Safefree(name); ++ } ++ else { ++ sv = newSVpv(s+1, 0); ++ } ++ (void)hv_store(hv, old_var, nlen, sv, 0); + if (env_is_not_environ) + mg_set(sv); + } ++ if (HvKEYS(dups)) { ++ /* environ has some duplicate definitions, remove them */ ++ HE *entry; ++ hv_iterinit(dups); ++ while ((entry = hv_iternext_flags(dups, 0))) { ++ STRLEN nlen; ++ const char *name = HePV(entry, nlen); ++ IV count = SvIV(HeVAL(entry)); ++ IV i; ++ SV **valp = hv_fetch(hv, name, nlen, 0); ++ ++ assert(valp); ++ ++ /* try to remove any duplicate names, depending on the ++ * implementation used in my_setenv() the iteration might ++ * not be necessary, but let's be safe. ++ */ ++ for (i = 0; i < count; ++i) ++ my_setenv(name, 0); ++ ++ /* and set it back to the value we set $ENV{name} to */ ++ my_setenv(name, SvPV_nolen(*valp)); ++ } ++ } ++ SvREFCNT_dec(dups); + } + #endif /* USE_ENVIRON_ARRAY */ + #endif /* !PERL_MICRO */ diff -Nru perl-5.14.2/debian/patches/fixes/CVE-2012-5195.diff perl-5.14.2/debian/patches/fixes/CVE-2012-5195.diff --- perl-5.14.2/debian/patches/fixes/CVE-2012-5195.diff 1970-01-01 00:00:00.000000000 +0000 +++ perl-5.14.2/debian/patches/fixes/CVE-2012-5195.diff 2012-11-16 22:41:46.000000000 +0000 @@ -0,0 +1,32 @@ +From: Andy Dougherty +Date: Thu, 27 Sep 2012 13:52:18 +0000 (-0400) +Subject: avoid calling memset with a negative count +X-Git-Tag: v5.14.3-RC2~3 +X-Git-Url: http://perl5.git.perl.org/perl.git/commitdiff_plain/b675304e3fdbcce3ef853b06b6ebe870d99faa7e + +avoid calling memset with a negative count + +Poorly written perl code that allows an attacker to specify the count to +perl's 'x' string repeat operator can already cause a memory exhaustion +denial-of-service attack. A flaw in versions of perl before 5.15.5 can +escalate that into a heap buffer overrun; coupled with versions of glibc +before 2.16, it possibly allows the execution of arbitrary code. + +The flaw addressed to this commit has been assigned identifier +CVE-2012-5195. +--- + +diff --git a/util.c b/util.c +index 0ea39c6..230211e 100644 +--- a/util.c ++++ b/util.c +@@ -3319,6 +3319,9 @@ Perl_repeatcpy(register char *to, register const char *from, I32 len, register I + { + PERL_ARGS_ASSERT_REPEATCPY; + ++ if (count < 0) ++ Perl_croak_nocontext("%s",PL_memory_wrap); ++ + if (len == 1) + memset(to, *from, count); + else if (count) { diff -Nru perl-5.14.2/debian/patches/fixes/CVE-2012-5526.diff perl-5.14.2/debian/patches/fixes/CVE-2012-5526.diff --- perl-5.14.2/debian/patches/fixes/CVE-2012-5526.diff 1970-01-01 00:00:00.000000000 +0000 +++ perl-5.14.2/debian/patches/fixes/CVE-2012-5526.diff 2012-11-16 22:44:04.000000000 +0000 @@ -0,0 +1,65 @@ +From: Ryo Anazawa +Date: Wed, 14 Nov 2012 09:47:32 +0900 +Subject: [PATCH 1/4] CR escaping for P3P header + +Index: perl-5.14.2/cpan/CGI/lib/CGI.pm +=================================================================== +--- perl-5.14.2.orig/cpan/CGI/lib/CGI.pm 2011-09-26 02:44:34.000000000 -0700 ++++ perl-5.14.2/cpan/CGI/lib/CGI.pm 2012-11-16 14:43:54.000000000 -0800 +@@ -1550,8 +1550,17 @@ + 'EXPIRES','NPH','CHARSET', + 'ATTACHMENT','P3P'],@p); + ++ # Since $cookie and $p3p may be array references, ++ # we must stringify them before CR escaping is done. ++ my @cookie; ++ for (ref($cookie) eq 'ARRAY' ? @{$cookie} : $cookie) { ++ my $cs = UNIVERSAL::isa($_,'CGI::Cookie') ? $_->as_string : $_; ++ push(@cookie,$cs) if defined $cs and $cs ne ''; ++ } ++ $p3p = join ' ',@$p3p if ref($p3p) eq 'ARRAY'; ++ + # CR escaping for values, per RFC 822 +- for my $header ($type,$status,$cookie,$target,$expires,$nph,$charset,$attachment,$p3p,@other) { ++ for my $header ($type,$status,@cookie,$target,$expires,$nph,$charset,$attachment,$p3p,@other) { + if (defined $header) { + # From RFC 822: + # Unfolding is accomplished by regarding CRLF immediately +@@ -1595,18 +1604,9 @@ + + push(@header,"Status: $status") if $status; + push(@header,"Window-Target: $target") if $target; +- if ($p3p) { +- $p3p = join ' ',@$p3p if ref($p3p) eq 'ARRAY'; +- push(@header,qq(P3P: policyref="/w3c/p3p.xml", CP="$p3p")); +- } ++ push(@header,"P3P: policyref=\"/w3c/p3p.xml\", CP=\"$p3p\"") if $p3p; + # push all the cookies -- there may be several +- if ($cookie) { +- my(@cookie) = ref($cookie) && ref($cookie) eq 'ARRAY' ? @{$cookie} : $cookie; +- for (@cookie) { +- my $cs = UNIVERSAL::isa($_,'CGI::Cookie') ? $_->as_string : $_; +- push(@header,"Set-Cookie: $cs") if $cs ne ''; +- } +- } ++ push(@header,map {"Set-Cookie: $_"} @cookie); + # if the user indicates an expiration time, then we need + # both an Expires and a Date header (so that the browser is + # uses OUR clock) +Index: perl-5.14.2/cpan/CGI/t/headers.t +=================================================================== +--- perl-5.14.2.orig/cpan/CGI/t/headers.t 2011-09-08 00:39:37.000000000 -0700 ++++ perl-5.14.2/cpan/CGI/t/headers.t 2012-11-16 14:43:54.000000000 -0800 +@@ -22,6 +22,12 @@ + like $cgi->header( -type => "text/html".$CGI::CRLF." evil: stuff " ), + qr#Content-Type: text/html evil: stuff#, 'known header, with leading and trailing whitespace on the continuation line'; + ++eval { $cgi->header( -p3p => ["foo".$CGI::CRLF."bar"] ) }; ++like($@,qr/contains a newline/,'P3P header with CRLF embedded blows up'); ++ ++eval { $cgi->header( -cookie => ["foo".$CGI::CRLF."bar"] ) }; ++like($@,qr/contains a newline/,'Set-Cookie header with CRLF embedded blows up'); ++ + eval { $cgi->header( -foobar => "text/html".$CGI::CRLF."evil: stuff" ) }; + like($@,qr/contains a newline/,'unknown header with CRLF embedded blows up'); + diff -Nru perl-5.14.2/debian/patches/series perl-5.14.2/debian/patches/series --- perl-5.14.2/debian/patches/series 2011-11-28 20:05:38.000000000 +0000 +++ perl-5.14.2/debian/patches/series 2016-03-01 16:02:03.000000000 +0000 @@ -51,3 +51,10 @@ debian/hurd_test_skip_libc.diff debian/hurd_test_skip_pipe.diff debian/hurd_test_skip_io_pipe.diff +fixes/CVE-2012-5195.diff +fixes/CVE-2012-5526.diff +CVE-2013-1667.patch +CVE-2012-6329.patch +CVE-2013-7422.patch +CVE-2014-4330.patch +CVE-2016-2381.patch