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: