[Reproducible-commits] [dpkg] 02/04: Dpkg::Source::Patch: add more sanity checks on patches

Holger Levsen holger at layer-acht.org
Tue May 3 08:43:04 UTC 2016


This is an automated email from the git hooks/post-receive script.

holger pushed a commit to annotated tag 1.14.29
in repository dpkg.

commit 3bfdbb5825a2dcbf6b102c3b44f1239fca48fa7e
Author: Raphaël Hertzog <hertzog at debian.org>
Date:   Fri Mar 5 18:19:33 2010 +0100

    Dpkg::Source::Patch: add more sanity checks on patches
    
    patch will happily accept filenames like "../../../../stuff" and modify
    files outside of the expected destination directory. To avoid problems
    we error out when we detect a filename that contains "/../". Any leading
    "../" is not a problem since patches are applied with -p1 and it's
    stripped.
    
    We also verify that the file to be modified is not accessed through a
    symlink as a compromised source package could also provide a symlink in
    the orig.tar.gz that points outside of the destination directory.
---
 debian/changelog             |  7 ++++++-
 scripts/Dpkg/Source/Patch.pm | 17 +++++++++++++++--
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 2d401b1..b293c8d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,11 @@
 dpkg (1.14.29) UNRELEASED; urgency=low
 
-  *
+  * Modify dpkg-source to error out when it would apply patches containing
+    insecure paths (with "/../") and also error out when it would apply a
+    patch through a symlink. Those checks are required as patch will happily
+    modify files outside of the target directory and unpacking a source package
+    should not be able to have any side-effect outside of the target
+    directory. Fixes CVE-2010-0396.
 
  -- Raphael Hertzog <hertzog at debian.org>  Fri, 05 Mar 2010 20:41:39 +0100
 
diff --git a/scripts/Dpkg/Source/Patch.pm b/scripts/Dpkg/Source/Patch.pm
index a205f28..079440a 100644
--- a/scripts/Dpkg/Source/Patch.pm
+++ b/scripts/Dpkg/Source/Patch.pm
@@ -316,8 +316,9 @@ sub analyze {
 	    error(_g("expected ^--- in line %d of diff `%s'"), $., $diff);
 	}
         $_ = strip_ts($_);
-        if ($_ eq '/dev/null' or s{^(\./)?[^/]+/}{$destdir/}) {
+        if ($_ eq '/dev/null' or s{^[^/]+/}{$destdir/}) {
             $fn = $_;
+	    error(_g("%s contains an insecure path: %s"), $diff, $_) if m{/\.\./};
         }
 	if (/\.dpkg-orig$/) {
 	    error(_g("diff `%s' patches file with name ending .dpkg-orig"), $diff);
@@ -330,8 +331,9 @@ sub analyze {
 	    error(_g("line after --- isn't as expected in diff `%s' (line %d)"), $diff, $.);
 	}
         $_ = strip_ts($_);
-        if ($_ eq '/dev/null' or s{^(\./)?[^/]+/}{$destdir/}) {
+        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)"),
@@ -357,6 +359,17 @@ sub analyze {
 	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);
 	}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/dpkg.git



More information about the Reproducible-commits mailing list