e044dd6
diff --git a/scripts/Dpkg/Source/Patch.pm b/scripts/Dpkg/Source/Patch.pm
e044dd6
--- a/scripts/Dpkg/Source/Patch.pm
e044dd6
+++ b/scripts/Dpkg/Source/Patch.pm
e044dd6
@@ -322,8 +322,9 @@ sub analyze {
e044dd6
 	    error(_g("expected ^--- in line %d of diff `%s'"), $., $diff);
e044dd6
 	}
e044dd6
         $_ = strip_ts($_);
e044dd6
-        if ($_ eq '/dev/null' or s{^(\./)?[^/]+/}{$destdir/}) {
e044dd6
+        if ($_ eq '/dev/null' or s{^[^/]+/}{$destdir/}) {
e044dd6
             $fn = $_;
e044dd6
+	    error(_g("%s contains an insecure path: %s"), $diff, $_) if m{/\.\./};
e044dd6
         }
e044dd6
 	if (/\.dpkg-orig$/) {
e044dd6
 	    error(_g("diff `%s' patches file with name ending .dpkg-orig"), $diff);
e044dd6
@@ -336,8 +337,9 @@ sub analyze {
e044dd6
 	    error(_g("line after --- isn't as expected in diff `%s' (line %d)"), $diff, $.);
e044dd6
 	}
e044dd6
         $_ = strip_ts($_);
e044dd6
-        if ($_ eq '/dev/null' or s{^(\./)?[^/]+/}{$destdir/}) {
e044dd6
+        if ($_ eq '/dev/null' or s{^[^/]+/}{$destdir/}) {
e044dd6
             $fn2 = $_;
e044dd6
+	    error(_g("%s contains an insecure path: %s"), $diff, $_) if m{/\.\./};
e044dd6
         } else {
e044dd6
             unless (defined $fn) {
e044dd6
                 error(_g("none of the filenames in ---/+++ are relative in diff `%s' (line %d)"),
e044dd6
@@ -363,6 +365,17 @@ sub analyze {
e044dd6
 	if ($dirname =~ s{/[^/]+$}{} && not -d $dirname) {
e044dd6
 	    $dirtocreate{$dirname} = 1;
e044dd6
 	}
e044dd6
+
e044dd6
+	# Sanity check, refuse to patch through a symlink
e044dd6
+	$dirname = $fn;
e044dd6
+	while (1) {
e044dd6
+	    if (-l $dirname) {
e044dd6
+		error(_g("diff %s modifies file %s through a symlink: %s"),
e044dd6
+		      $diff, $fn, $dirname);
e044dd6
+	    }
e044dd6
+	    last unless $dirname =~ s{/[^/]+$}{};
e044dd6
+	}
e044dd6
+
e044dd6
 	if (-e $fn and not -f _) {
e044dd6
 	    error(_g("diff `%s' patches something which is not a plain file"), $diff);
e044dd6
 	}