[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#702454: marked as done (unblock: perl/5.14.2-19)



Your message dated Wed, 06 Mar 2013 19:46:34 +0000
with message-id <1362599194.7567.3.camel@jacala.jungle.funky-badger.org>
and subject line Re: Bug#702454: unblock: perl/5.14.2-19
has caused the Debian Bug report #702454,
regarding unblock: perl/5.14.2-19
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
702454: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=702454
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package perl

Changes: 
 perl (5.14.2-19) unstable; urgency=high
 .
   * [SECURITY] CVE-2013-1667: fix a rehashing DoS opportunity
     against code that uses arbitrary user input as hash keys.
     (Closes: #702296)

unblock perl/5.14.2-19

-- System Information:
Debian Release: 7.0
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.2.0-4-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=fi_FI.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
diff -Nru perl-5.14.2/debian/changelog perl-5.14.2/debian/changelog
--- perl-5.14.2/debian/changelog	2013-02-09 15:31:34.000000000 +0200
+++ perl-5.14.2/debian/changelog	2013-03-05 21:38:31.000000000 +0200
@@ -1,3 +1,11 @@
+perl (5.14.2-19) unstable; urgency=high
+
+  * [SECURITY] CVE-2013-1667: fix a rehashing DoS opportunity
+    against code that uses arbitrary user input as hash keys.
+    (Closes: #702296)
+
+ -- Niko Tyni <ntyni@debian.org>  Tue, 05 Mar 2013 21:38:26 +0200
+
 perl (5.14.2-18) unstable; urgency=low
 
   * Fix a squeeze regression with STDIN and signal handlers.
diff -Nru perl-5.14.2/debian/patches/fixes/hsplit-rehash.diff perl-5.14.2/debian/patches/fixes/hsplit-rehash.diff
--- perl-5.14.2/debian/patches/fixes/hsplit-rehash.diff	1970-01-01 02:00:00.000000000 +0200
+++ perl-5.14.2/debian/patches/fixes/hsplit-rehash.diff	2013-03-05 21:38:04.000000000 +0200
@@ -0,0 +1,173 @@
+From 5d86bf622ad5ac2cc69da54d76000a4618518410 Mon Sep 17 00:00:00 2001
+From: Yves Orton <demerphq@gmail.com>
+Date: Tue, 12 Feb 2013 10:53:05 +0100
+Subject: 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)
+
+Bug-Debian: http://bugs.debian.org/702296
+Origin: upstream, http://perl5.git.perl.org/perl.git/commit/d59e31fc729d8a39a774f03bc6bc457029a7aef2
+Patch-Name: fixes/hsplit-rehash.diff
+---
+ 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;
diff -Nru perl-5.14.2/debian/patches/series perl-5.14.2/debian/patches/series
--- perl-5.14.2/debian/patches/series	2013-02-09 15:29:12.000000000 +0200
+++ perl-5.14.2/debian/patches/series	2013-03-05 21:38:04.000000000 +0200
@@ -76,3 +76,4 @@
 fixes/digest-sha-doublefree.diff
 fixes/64bitint-signedness-wraparound.diff
 fixes/stdin-sigchld.diff
+fixes/hsplit-rehash.diff

--- End Message ---
--- Begin Message ---
On Wed, 2013-03-06 at 20:59 +0200, Niko Tyni wrote:
>  perl (5.14.2-19) unstable; urgency=high
>  .
>    * [SECURITY] CVE-2013-1667: fix a rehashing DoS opportunity
>      against code that uses arbitrary user input as hash keys.
>      (Closes: #702296)

Unblocked a little earlier this evening. :) Thanks.

Regards,

Adam

--- End Message ---

Reply to: