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

Ubuntu dpkg 1.15.8.7ubuntu2



This e-mail has been sent due to an upload to Ubuntu that contains Ubuntu
changes.  It contains the difference between the new version and the
previous version of the same source package in Ubuntu.
Format: 1.8
Date: Thu, 06 Jan 2011 12:48:51 -0800
Source: dpkg
Binary: libdpkg-dev dpkg dpkg-dev libdpkg-perl dselect
Architecture: source
Version: 1.15.8.7ubuntu2
Distribution: natty
Urgency: low
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Changed-By: Kees Cook <kees@ubuntu.com>
Description: 
 dpkg       - Debian package management system
 dpkg-dev   - Debian package development tools
 dselect    - Debian package management front-end
 libdpkg-dev - Debian package management static library
 libdpkg-perl - Dpkg perl modules
Changes: 
 dpkg (1.15.8.7ubuntu2) natty; urgency=low
 .
   * SECURITY UPDATE: relative directory and symlink following in source pkgs.
     - scripts/Dpkg/Source/Archive.pm, scripts/Dpkg/Source/Patch.pm,
       scripts/Dpkg/Source/Package/V2.pm: applied fixes from Raphael Hertzog,
       thanks to Raphael Geissert.
     - CVE-2010-1679
Checksums-Sha1: 
 f50fa9a26a0ec1ab7a0b8919d8b1107e50b35526 1353 dpkg_1.15.8.7ubuntu2.dsc
 53f911d567ada1590302c2181275ce14b71cbe0b 5294707 dpkg_1.15.8.7ubuntu2.tar.bz2
Checksums-Sha256: 
 dbf00a1806f61bd917db78861d58fa835bd1df1226a609abc3a112ed4ba591e6 1353 dpkg_1.15.8.7ubuntu2.dsc
 c8be2e30be90b3af181d24010b2dc8590f2c8a149a11d0e34262fccfce55224a 5294707 dpkg_1.15.8.7ubuntu2.tar.bz2
Files: 
 32e576013bf93f9b04e1d6bd46ca0334 1353 admin required dpkg_1.15.8.7ubuntu2.dsc
 ed4d2e4d6b2ac46aed8efc565a609e4f 5294707 admin required dpkg_1.15.8.7ubuntu2.tar.bz2
Original-Maintainer: Dpkg Developers <debian-dpkg@lists.debian.org>
diff -pruN 1.15.8.7ubuntu1/debian/changelog 1.15.8.7ubuntu2/debian/changelog
--- 1.15.8.7ubuntu1/debian/changelog	2010-12-20 17:41:51.000000000 +0000
+++ 1.15.8.7ubuntu2/debian/changelog	2011-01-06 20:49:20.000000000 +0000
@@ -1,3 +1,13 @@
+dpkg (1.15.8.7ubuntu2) natty; urgency=low
+
+  * SECURITY UPDATE: relative directory and symlink following in source pkgs.
+    - scripts/Dpkg/Source/Archive.pm, scripts/Dpkg/Source/Patch.pm,
+      scripts/Dpkg/Source/Package/V2.pm: applied fixes from Raphael Hertzog,
+      thanks to Raphael Geissert.
+    - CVE-2010-1679
+
+ -- Kees Cook <kees@ubuntu.com>  Thu, 06 Jan 2011 12:48:51 -0800
+
 dpkg (1.15.8.7ubuntu1) natty; urgency=low
 
   * Resynchronise with Debian.  Remaining changes:
diff -pruN 1.15.8.7ubuntu1/scripts/Dpkg/Source/Archive.pm 1.15.8.7ubuntu2/scripts/Dpkg/Source/Archive.pm
--- 1.15.8.7ubuntu1/scripts/Dpkg/Source/Archive.pm	2010-09-27 01:25:04.000000000 +0100
+++ 1.15.8.7ubuntu2/scripts/Dpkg/Source/Archive.pm	2011-01-06 20:49:32.000000000 +0000
@@ -147,7 +147,7 @@ sub extract {
     closedir(D);
     my $done = 0;
     erasedir($dest);
-    if (scalar(@entries) == 1 && -d "$tmp/$entries[0]") {
+    if (scalar(@entries) == 1 && ! -l "$tmp/$entries[0]" && -d _) {
 	rename("$tmp/$entries[0]", $dest) ||
 		syserr(_g("Unable to rename %s to %s"),
 		       "$tmp/$entries[0]", $dest);
diff -pruN 1.15.8.7ubuntu1/scripts/Dpkg/Source/Package/V2.pm 1.15.8.7ubuntu2/scripts/Dpkg/Source/Package/V2.pm
--- 1.15.8.7ubuntu1/scripts/Dpkg/Source/Package/V2.pm	2010-10-11 15:49:25.000000000 +0100
+++ 1.15.8.7ubuntu2/scripts/Dpkg/Source/Package/V2.pm	2011-01-06 20:49:32.000000000 +0000
@@ -133,7 +133,12 @@ sub do_extract {
     # Extract main tarball
     info(_g("unpacking %s"), $tarfile);
     my $tar = Dpkg::Source::Archive->new(filename => "$dscdir$tarfile");
-    $tar->extract($newdirectory, no_fixperms => 1);
+    $tar->extract($newdirectory, no_fixperms => 1,
+                  options => [ "--anchored", "--no-wildcards-match-slash",
+                               "--exclude", "*/.pc", "--exclude", ".pc" ]);
+    # The .pc exclusion is only needed for 3.0 (quilt) and to avoid
+    # having an upstream tarball provide a directory with symlinks
+    # that would be blindly followed when applying the patches
 
     # Extract additional orig tarballs
     foreach my $subdir (keys %origtar) {
diff -pruN 1.15.8.7ubuntu1/scripts/Dpkg/Source/Patch.pm 1.15.8.7ubuntu2/scripts/Dpkg/Source/Patch.pm
--- 1.15.8.7ubuntu1/scripts/Dpkg/Source/Patch.pm	2010-08-01 17:41:23.000000000 +0100
+++ 1.15.8.7ubuntu2/scripts/Dpkg/Source/Patch.pm	2011-01-06 20:49:32.000000000 +0000
@@ -307,11 +307,41 @@ sub analyze {
         $header =~ s/\s.*// unless ($header =~ s/\t.*//);
         return $header;
     }
+    sub intuit_file_patched {
+	my ($old, $new) = @_;
+	return $new unless defined $old;
+	return $old unless defined $new;
+	return $new if -e $new and not -e $old;
+	return $old if -e $old and not -e $new;
+	# We don't consider the case where both files are non-existent and
+	# where patch picks the one with the fewest directories to create
+	# since dpkg-source will pre-create the required directories
+	#
+	# Precalculate metrics used by patch
+	my ($tmp_o, $tmp_n) = ($old, $new);
+	my ($len_o, $len_n) = (length($old), length($new));
+	$tmp_o =~ s{[/\\]+}{/}g;
+	$tmp_n =~ s{[/\\]+}{/}g;
+	my $nb_comp_o = ($tmp_o =~ tr{/}{/});
+	my $nb_comp_n = ($tmp_n =~ tr{/}{/});
+	$tmp_o =~ s{^.*/}{};
+	$tmp_n =~ s{^.*/}{};
+	my ($blen_o, $blen_n) = (length($tmp_o), length($tmp_n));
+	# Decide like patch would
+	if ($nb_comp_o != $nb_comp_n) {
+	    return ($nb_comp_o < $nb_comp_n) ? $old : $new;
+	} elsif ($blen_o != $blen_n) {
+	    return ($blen_o < $blen_n) ? $old : $new;
+	} elsif ($len_o != $len_n) {
+	    return ($len_o < $len_n) ? $old : $new;
+	}
+	return $old;
+    }
     $_ = getline($self);
 
   HUNK:
     while (defined($_) || not eof($self)) {
-	my ($fn, $fn2);
+	my (%path, %fn);
 	# skip comments leading up to patch (if any)
 	until (/^--- /) {
 	    last HUNK if not defined($_ = getline($self));
@@ -321,11 +351,8 @@ sub analyze {
 	unless(s/^--- //) {
 	    error(_g("expected ^--- in line %d of diff `%s'"), $., $diff);
 	}
-        $_ = strip_ts($_);
-        if ($_ eq '/dev/null' or s{^[^/]+/}{$destdir/}) {
-            $fn = $_;
-	    error(_g("%s contains an insecure path: %s"), $diff, $_) if m{/\.\./};
-        }
+        $path{'old'} = $_ = strip_ts($_);
+	$fn{'old'} = $_ if $_ ne '/dev/null' and s{^[^/]*/+}{$destdir/};
 	if (/\.dpkg-orig$/) {
 	    error(_g("diff `%s' patches file with name ending .dpkg-orig"), $diff);
 	}
@@ -336,46 +363,47 @@ sub analyze {
 	unless (s/^\+\+\+ //) {
 	    error(_g("line after --- isn't as expected in diff `%s' (line %d)"), $diff, $.);
 	}
-        $_ = strip_ts($_);
-        if ($_ eq '/dev/null' or s{^[^/]+/}{$destdir/}) {
-            $fn2 = $_;
-	    error(_g("%s contains an insecure path: %s"), $diff, $_) if m{/\.\./};
-        } else {
-            unless (defined $fn) {
-                error(_g("none of the filenames in ---/+++ are relative in diff `%s' (line %d)"),
-                      $diff, $.);
-            }
-        }
+        $path{'new'} = $_ = strip_ts($_);
+	$fn{'new'} = $_ if $_ ne '/dev/null' and s{^[^/]*/+}{$destdir/};
+
+	unless (defined $fn{'old'} or defined $fn{'new'}) {
+	    error(_g("none of the filenames in ---/+++ are valid in diff '%s' (line %d)"),
+		  $diff, $.);
+	}
+
+	# Safety checks on both filenames that patch could use
+	foreach my $key ("old", "new") {
+	    next unless defined $fn{$key};
+	    if ($path{$key} =~ m{/\.\./}) {
+		error(_g("%s contains an insecure path: %s"), $diff, $path{$key});
+	    }
+	    my $path = $fn{$key};
+	    while (1) {
+		if (-l $path) {
+		    error(_g("diff %s modifies file %s through a symlink: %s"),
+			  $diff, $fn{$key}, $path);
+		}
+		last unless $path =~ s{/+[^/]*$}{};
+		last if length($path) <= length($destdir); # $destdir is assumed safe
+	    }
+	}
 
-        if (defined($fn) and $fn eq '/dev/null') {
+        if ($path{'old'} eq '/dev/null' and $path{'new'} eq '/dev/null') {
             error(_g("original and modified files are /dev/null in diff `%s' (line %d)"),
-                  $diff, $.) if (defined($fn2) and $fn2 eq '/dev/null');
-            $fn = $fn2;
-        } elsif (defined($fn2) and $fn2 ne '/dev/null') {
-            $fn = $fn2 unless defined $fn;
-            $fn = $fn2 if ((not -e $fn) and -e $fn2);
-        } elsif (defined($fn2) and $fn2 eq '/dev/null') {
+                  $diff, $.);
+        } elsif ($path{'new'} eq '/dev/null') {
             error(_g("file removal without proper filename in diff `%s' (line %d)"),
-                  $diff, $. - 1) unless defined $fn;
+                  $diff, $. - 1) unless defined $fn{'old'};
             warning(_g("diff %s removes a non-existing file %s (line %d)"),
-                    $diff, $fn, $.) unless -e $fn;
+                    $diff, $fn{'old'}, $.) unless -e $fn{'old'};
         }
+	my $fn = intuit_file_patched($fn{'old'}, $fn{'new'});
 
 	my $dirname = $fn;
 	if ($dirname =~ s{/[^/]+$}{} && not -d $dirname) {
 	    $dirtocreate{$dirname} = 1;
 	}
 
-	# Sanity check, refuse to patch through a symlink
-	$dirname = $fn;
-	while (1) {
-	    if (-l $dirname) {
-		error(_g("diff %s modifies file %s through a symlink: %s"),
-		      $diff, $fn, $dirname);
-	    }
-	    last unless $dirname =~ s{/[^/]+$}{};
-	}
-
 	if (-e $fn and not -f _) {
 	    error(_g("diff `%s' patches something which is not a plain file"), $diff);
 	}

Reply to: