-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
Hi I have devised a patch for this; currently Lintian ignores all patches outside debian/, with this it will accept one-level of indirection. That is symlink -> patch (but not symlink -> symlink -> patch). The patch can be extended to do that, but I could not wrap my head around during it correctly without relying on unpacked being present. Since failure here would give us another CVE I decided to keep it simple. That being said, I would still like a double check on this before I apply it. Thank you in advance, ~Niels -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iQIcBAEBCAAGBQJN25rcAAoJEAVLu599gGRCCj8P/0CNi1y2DrFtlynBUYx9Y7O2 AH4Gc8ArQDd5jJOaFFVWMSDYBaEt80+VD4765WEzNgAojxGFoCxdjuagzFVGkw49 Uzvq+QwvT3PreVDZ4rXRzcRc+4VLjNwna3EyU9wFkgVA+xtOCFbFr6o5A+f7SsOP QucBbPAAXVNMTMW0tnKQgBKxH/XtNemOlba3NPfvUjwMdc+xoYKEv1bKkBTVuM5D 0gXU2HRDOMH2XmyX+MTpZhMiB58c5fDHeMzGcrm4TkhAvs//l8J+wyKaKH8i0H8K jFcRgK5IGP1DZhaIsBI++Rylaaa3DEwlhqT+aTVXO0i526cPN3ne2fORLmkAaSt1 j8LB9hqX+DmcXa8nSbCbAy9WCwffYAljYmC7XzD+do8yyo6RUi81MQTRtA7KIUkc baBcxawDJ+7Uye3/dnsxH9T7AgUd+0W/6NbYuW1z1XZnnwa81f+GVrkl7gC1GI34 q+2BKCq0ElGD/F48LgkCA/qFUYzz5CKJSmAfPFZ3crc2GRrf1QuGBh8HFcY+Y7ej eydvhc1U+2GIJr3vuiAOmJQwZL/0pokRqGJuiVRAx6WKEYLO4j75CNYUSn5GVlci Kvrewn50uAlGI0dw0r3ytJTzJQWLNOoXQrAljkddPHOr2kwmnoocGUWNGGhdLcNg TQt2wz72iTuPFVB3OmlV =g9Ta -----END PGP SIGNATURE-----
>From b54102d5c418368833e977e17d6a4dfee593f0ab Mon Sep 17 00:00:00 2001 From: Niels Thykier <ni...@thykier.net> Date: Tue, 24 May 2011 13:36:25 +0200 Subject: [PATCH] Allow quilt patches to be symlinks outside debian/ in some cases Allow patches directly in debian/patches/ to be symlinks to other files, if it is a valid target in the source package. The logic in this patch does not handle symlinks to symlinks or if the original patch is outside debian/patches (e.g. p/my-patch.patch in the series file) --- checks/patch-systems | 76 ++++++++++++++++---- debian/changelog | 4 + .../debian/debian/patches/series | 3 + t/tests/patch-systems-quilt-general/tags | 1 + .../debian/debian/control.in | 15 ++++ .../debian/debian/patches/series | 1 + .../debian/debian/source/format | 1 + .../patch-systems-quilt-source-symlink-patch/desc | 6 ++ .../pre_build | 5 ++ .../upstream/README | 1 + .../upstream/source.patch | 6 ++ 11 files changed, 106 insertions(+), 13 deletions(-) create mode 100644 t/tests/patch-systems-quilt-source-symlink-patch/debian/debian/control.in create mode 100644 t/tests/patch-systems-quilt-source-symlink-patch/debian/debian/patches/series create mode 100644 t/tests/patch-systems-quilt-source-symlink-patch/debian/debian/source/format create mode 100644 t/tests/patch-systems-quilt-source-symlink-patch/desc create mode 100755 t/tests/patch-systems-quilt-source-symlink-patch/pre_build create mode 100644 t/tests/patch-systems-quilt-source-symlink-patch/tags create mode 100644 t/tests/patch-systems-quilt-source-symlink-patch/upstream/README create mode 100644 t/tests/patch-systems-quilt-source-symlink-patch/upstream/source.patch diff --git a/checks/patch-systems b/checks/patch-systems index 515561c..72ec09f 100644 --- a/checks/patch-systems +++ b/checks/patch-systems @@ -109,7 +109,7 @@ sub run { tag "dpatch-missing-description", $patch_file; } } - check_patch($patch_file); + check_patch($patch_file, "debfiles/patches/$patch_file"); } } } @@ -147,15 +147,33 @@ sub run { # Check each patch. foreach my $patch_file (@patches) { - next if ( -l "debfiles/patches/$patch_file" ); - unless (realpath("debfiles/patches/$patch_file") =~ m,^\Q$cwd\E/debfiles/,) { - next; + my $patch_path; + if ( $patch_file =~ m,/,o) { + # The patch itself is in another directory. + my $path = resolve_patch('debian/patches', $patch_file); + next unless $path; # cannot be safely resolved - bail + ## FIXME: According to #562155, quilt does not correctly + ## handle ../ patches, perhaps we should warn about that? + $patch_path = $path; + } else { + # Straight forward simple patch in d/patches/ + $patch_path = "debfiles/patches/$patch_file"; + if ( -l $patch_path ) { + my $target = readlink("debfiles/patches/$patch_file"); + my $path = resolve_patch('debian/patches', $target); + next unless $path; + $patch_path = $path; + } } - if (! -r "debfiles/patches/$patch_file") { + # Bail if this is a link - the logic above is not strong enough to + # handle a link to a link or a "../../path/to/symlink" in + # d/patches/series + next if -l $patch_path; + if (! -r $patch_path) { tag "quilt-series-references-non-existent-patch", $patch_file; next; } - if (open(PATCH_FILE, '<', "debfiles/patches/$patch_file")) { + if (open(PATCH_FILE, '<', $patch_path)) { my $has_description = 0; while (<PATCH_FILE>) { # stop if something looking like a patch starts: @@ -169,7 +187,7 @@ sub run { tag "quilt-patch-missing-description", $patch_file; } } - check_patch($patch_file); + check_patch($patch_file, $patch_path); } } } @@ -217,8 +235,8 @@ sub run { } # Checks on patches common to all build systems. -sub check_patch($) { - my $patch_file = shift; +sub check_patch { + my ($patch_file, $patch_path) = @_; # Use -p1 to strip off the first layer of directory in case the parent # directory in which the patches were generated was named "debian". @@ -226,17 +244,49 @@ sub check_patch($) { # in the debian/* directory, but as of 2010-01-01, all cases where the # first level of the patch path is "debian/" in the archive are false # positives. - open(DIFFSTAT, "-|", 'diffstat', '-p1', '-l', "debfiles/patches/$patch_file") - or fail("can't fork diffstat"); + open(DIFFSTAT, '-|', 'diffstat', '-p1', '-l', $patch_path) + or fail("cannot fork diffstat: $!"); while (<DIFFSTAT>) { chomp; - if (m|^(\./)?debian/|) { - tag "patch-modifying-debian-files", $patch_file, $_; + if (m|^(?:\./)?debian/|o) { + tag 'patch-modifying-debian-files', $patch_file, $_; } } close(DIFFSTAT) or fail("cannot close pipe to diffstat on $patch_file: $!"); } +# Resolve a patch in $dir pointing to $target +# - resolve_patch($dir, $target); +# - resolve_patch('debian/patches', 'p/my-patch.diff'); +# gives 'debfiles/patches/p/my-patch.diff' +# - resolve_patch('debian/patches', '../../my-patch.diff'); +# gives 'unpacked/my-patch.diff' (if unpacked is present) +# +# Returns a path into debfiles/ if the target is inside debian/ +# Returns a path into unpacked/ if the target is outside debian/ +# but can safely be resolved AND unpacked is a directory. +# Returns a non-truth value otherwise. +sub resolve_patch { + my ($dir, $target) = @_; + my $path = resolve_pkg_path($dir, $target); + return '' unless $path; # cannot be safely resolved - bail + if ($path =~ m,^debian/,o){ + # The patch is inside debian/, so we can find it in + # debfiles + $path =~ s,debian/,debfiles/,o; + } else { + # The patch is in the upstream part, which we cannot check + # unless 'unpacked' is here. + # - Usually it will be since debfiles depend on unpacked + # but if we are re-run in a lab without being allowed to use unpacked + # it might have been auto-removed. + return '' unless -d 'unpacked/'; + $path = "unpacked/$path"; + } + return $path; +} + + 1; # Local Variables: diff --git a/debian/changelog b/debian/changelog index 459ae78..380941f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -6,6 +6,10 @@ lintian (2.5.1) UNRELEASED; urgency=low * checks/java: + [NT] Sort the jar files by name, so they are checked in the same order. + * checks/patch-systems: + + [NT] Check symlinked patches that can safely be resolved. This + allows the use of symlinks in debian/patches/ to point to a patch + in the upstream part of the source package. (Closes: #563773) * collection/unpacked: + [NT] Added support for unpacking source packages using libdpkg-perl, diff --git a/t/tests/patch-systems-quilt-general/debian/debian/patches/series b/t/tests/patch-systems-quilt-general/debian/debian/patches/series index edea10a..9406f3d 100644 --- a/t/tests/patch-systems-quilt-general/debian/debian/patches/series +++ b/t/tests/patch-systems-quilt-general/debian/debian/patches/series @@ -3,4 +3,7 @@ some-other-file -p0 some-nonexistent-patch # this is to test for directory traversals # 'debian-patch' is a file in the laboratory +# - older versions of Lintian would read the +# file from the laboratory rather than +# realizing that the patch does not exist. ../../debian-patch diff --git a/t/tests/patch-systems-quilt-general/tags b/t/tests/patch-systems-quilt-general/tags index 38e023f..403605f 100644 --- a/t/tests/patch-systems-quilt-general/tags +++ b/t/tests/patch-systems-quilt-general/tags @@ -1,4 +1,5 @@ E: patch-systems-quilt-general source: patch-modifying-debian-files some-file debian/some-file +E: patch-systems-quilt-general source: quilt-series-references-non-existent-patch ../../debian-patch E: patch-systems-quilt-general source: quilt-series-references-non-existent-patch some-nonexistent-patch W: patch-systems-quilt-general source: dpatch-build-dep-but-no-patch-list W: patch-systems-quilt-general source: more-than-one-patch-system diff --git a/t/tests/patch-systems-quilt-source-symlink-patch/debian/debian/control.in b/t/tests/patch-systems-quilt-source-symlink-patch/debian/debian/control.in new file mode 100644 index 0000000..07c8950 --- /dev/null +++ b/t/tests/patch-systems-quilt-source-symlink-patch/debian/debian/control.in @@ -0,0 +1,15 @@ +Source: {$srcpkg} +Priority: extra +Section: {$section} +Maintainer: {$author} +Standards-Version: {$standards_version} +Build-Depends: debhelper (>= 7.0.50~), quilt + +Package: {$srcpkg} +Architecture: {$architecture} +Depends: $\{shlibs:Depends\}, $\{misc:Depends\} +Description: {$description} + This is a test package designed to exercise some feature or tag of + Lintian. It is part of the Lintian test suite and may do very odd + things. It should not be installed like a regular package. It may + be an empty package. diff --git a/t/tests/patch-systems-quilt-source-symlink-patch/debian/debian/patches/series b/t/tests/patch-systems-quilt-source-symlink-patch/debian/debian/patches/series new file mode 100644 index 0000000..860a818 --- /dev/null +++ b/t/tests/patch-systems-quilt-source-symlink-patch/debian/debian/patches/series @@ -0,0 +1 @@ +upstream-patch-symlink.patch diff --git a/t/tests/patch-systems-quilt-source-symlink-patch/debian/debian/source/format b/t/tests/patch-systems-quilt-source-symlink-patch/debian/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/t/tests/patch-systems-quilt-source-symlink-patch/debian/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/t/tests/patch-systems-quilt-source-symlink-patch/desc b/t/tests/patch-systems-quilt-source-symlink-patch/desc new file mode 100644 index 0000000..cac9934 --- /dev/null +++ b/t/tests/patch-systems-quilt-source-symlink-patch/desc @@ -0,0 +1,6 @@ +Testname: patch-systems-quilt-source-symlink-patch +Sequence: 6000 +Type: non-native +Version: 1.0-1 +Test-Against: quilt-series-references-non-existent-patch +Description: Test for valid symlink quilt patches diff --git a/t/tests/patch-systems-quilt-source-symlink-patch/pre_build b/t/tests/patch-systems-quilt-source-symlink-patch/pre_build new file mode 100755 index 0000000..1d8457d --- /dev/null +++ b/t/tests/patch-systems-quilt-source-symlink-patch/pre_build @@ -0,0 +1,5 @@ +#!/bin/sh + +# generate the symlink +DIR="$1" +ln -s ../../source.patch "$DIR/debian/patches/upstream-patch-symlink.patch" diff --git a/t/tests/patch-systems-quilt-source-symlink-patch/tags b/t/tests/patch-systems-quilt-source-symlink-patch/tags new file mode 100644 index 0000000..e69de29 diff --git a/t/tests/patch-systems-quilt-source-symlink-patch/upstream/README b/t/tests/patch-systems-quilt-source-symlink-patch/upstream/README new file mode 100644 index 0000000..e845566 --- /dev/null +++ b/t/tests/patch-systems-quilt-source-symlink-patch/upstream/README @@ -0,0 +1 @@ +README diff --git a/t/tests/patch-systems-quilt-source-symlink-patch/upstream/source.patch b/t/tests/patch-systems-quilt-source-symlink-patch/upstream/source.patch new file mode 100644 index 0000000..79bf224 --- /dev/null +++ b/t/tests/patch-systems-quilt-source-symlink-patch/upstream/source.patch @@ -0,0 +1,6 @@ +Description: Wanna-be patch from upstream + +--- /dev/null 2011-05-24 08:55:59.948027011 +0200 ++++ b/source-file.txt 2011-05-24 11:58:50.466426869 +0200 +@@ -0,0 +1 @@ ++Patch me, patch me! -- 1.7.4.4
0001-Allow-quilt-patches-to-be-symlinks-outside-debian-in.patch.sig
Description: Binary data