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

Bug#700707: unblock: lintian/2.5.10.4



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Hi,

Please consider unblocking lintian/2.5.10.4, it includes the following
changes:

lintian (2.5.10.4) unstable; urgency=low

  * checks/init.d:
    + [NT] Fix regression where Lintian would not properly match
      init.d passed to update-rc.d.  Thanks to Michael Meskes for
      reporting.  (Closes: #698602)

  * lib/Lintian/Collect/Package.pm:
    + [NT] Ensure the "root" entry of indices do not contain itself.
      (Closes: #695866)
  * lib/Lintian/Util.pm:
    + [NT] Reject partially signed Deb822 files.  Most Deb822 files
      are not signed at all; but those that are should be completely
      covered by a signature.  (Closes: #696230)
    + [ADB] Fix a typo in the matching of expected delimiters for some
      signed messages; thanks Samuel Bronson.


I have attached a filtered debdiff (one without the test suite
changes).

 diffstat for lintian-2.5.10.3 lintian-2.5.10.4 (minus the test suite)

 checks/init.d                                     |   13 +
 debian/changelog                                  |   19 ++
 frontend/lintian                                  |    8 +
 lib/Lintian/Collect/Package.pm                    |    6 
 lib/Lintian/Util.pm                               |  152 ++++++++++++++++++++--
 [...]

The changes to Lintian::Util appear large at first, but the majority
of them are comments.

unblock lintian/2.5.10.4

Thanks for considering it,
~Niels
diffstat for lintian-2.5.10.3 lintian-2.5.10.4

 checks/init.d                                     |   13 +
 debian/changelog                                  |   19 ++
 frontend/lintian                                  |    8 +
 lib/Lintian/Collect/Package.pm                    |    6 
 lib/Lintian/Util.pm                               |  152 ++++++++++++++++++++--
 t/scripts/Lintian/Util/data/pgp-eof-missing-sign  |    5 
 t/scripts/Lintian/Util/data/pgp-leading-unsigned  |   14 ++
 t/scripts/Lintian/Util/data/pgp-malformed-header  |   11 +
 t/scripts/Lintian/Util/data/pgp-no-end-pgp-header |    7 +
 t/scripts/Lintian/Util/data/pgp-sig-before-start  |    7 +
 t/scripts/Lintian/Util/data/pgp-trailing-unsigned |   14 ++
 t/scripts/Lintian/Util/data/pgp-two-signatures    |   16 ++
 t/scripts/Lintian/Util/data/pgp-two-signed-msgs   |   19 ++
 t/scripts/Lintian/Util/data/pgp-unexpected-header |    6 
 t/scripts/Lintian/Util/dctrl-parser.t             |   52 +++++++
 15 files changed, 334 insertions(+), 15 deletions(-)

diff -Nru lintian-2.5.10.3/checks/init.d lintian-2.5.10.4/checks/init.d
--- lintian-2.5.10.3/checks/init.d	2012-12-11 19:03:17.000000000 +0100
+++ lintian-2.5.10.4/checks/init.d	2013-02-16 13:25:08.000000000 +0100
@@ -61,6 +61,11 @@
     );
 
 our $VIRTUAL_FACILITIES = Lintian::Data->new('init.d/virtual_facilities');
+# Regex to match names of init.d scripts; it is a bit more lax than
+# package names (e.g. allows "_").  We do not allow it to start with a
+# "dash" to avoid confusing it with a command-line option (also,
+# update-rc.d does not allow this).
+our $INITD_NAME_REGEX = qr/[\w\.\+][\w\-\.\+]*/;
 
 sub run {
 
@@ -88,7 +93,7 @@
         next if /$exclude_r/o;
         s/\#.*$//o;
         next unless /^(?:.+;|^\s*system[\s\(\']+)?\s*update-rc\.d\s+
-            (?:$opts_r)*($PKGNAME_REGEX)\s+($action_r)/xo;
+            (?:$opts_r)*($INITD_NAME_REGEX)\s+($action_r)/xo;
         my ($name,$opt) = ($1,$2);
         next if $opt eq 'remove';
         if ($initd_postinst{$name}++ == 1) {
@@ -108,7 +113,7 @@
         next if /$exclude_r/o;
         s/\#.*$//o;
         next unless m/update-rc\.d \s+
-                       (?:$opts_r)*($PKGNAME_REGEX) \s+
+                       (?:$opts_r)*($INITD_NAME_REGEX) \s+
                        ($action_r)/ox;
         my ($name,$opt) = ($1,$2);
         next if $opt eq 'remove';
@@ -122,7 +127,7 @@
     while (<IN>) {
         next if /$exclude_r/o;
         s/\#.*$//o;
-        next unless m/update-rc\.d\s+($opts_r)*($PKGNAME_REGEX)/o;
+        next unless m/update-rc\.d\s+($opts_r)*($INITD_NAME_REGEX)/o;
         if ($initd_postrm{$2}++ == 1) {
             tag 'duplicate-updaterc.d-calls-in-postrm', $2;
             next;
@@ -139,7 +144,7 @@
     while (<IN>) {
         next if /$exclude_r/o;
         s/\#.*$//o;
-        next unless m/update-rc\.d\s+($opts_r)*($PKGNAME_REGEX)/o;
+        next unless m/update-rc\.d\s+($opts_r)*($INITD_NAME_REGEX)/o;
         tag 'prerm-calls-updaterc.d', $2;
     }
     close(IN);
diff -Nru lintian-2.5.10.3/debian/changelog lintian-2.5.10.4/debian/changelog
--- lintian-2.5.10.3/debian/changelog	2012-12-11 20:14:08.000000000 +0100
+++ lintian-2.5.10.4/debian/changelog	2013-02-16 14:17:05.000000000 +0100
@@ -1,3 +1,22 @@
+lintian (2.5.10.4) unstable; urgency=low
+
+  * checks/init.d:
+    + [NT] Fix regression where Lintian would not properly match
+      init.d passed to update-rc.d.  Thanks to Michael Meskes for
+      reporting.  (Closes: #698602)
+
+  * lib/Lintian/Collect/Package.pm:
+    + [NT] Ensure the "root" entry of indices do not contain itself.
+      (Closes: #695866)
+  * lib/Lintian/Util.pm:
+    + [NT] Reject partially signed Deb822 files.  Most Deb822 files
+      are not signed at all; but those that are should be completely
+      covered by a signature.  (Closes: #696230)
+    + [ADB] Fix a typo in the matching of expected delimiters for some
+      signed messages; thanks Samuel Bronson.
+
+ -- Niels Thykier <niels@thykier.net>  Sat, 16 Feb 2013 14:17:03 +0100
+
 lintian (2.5.10.3) unstable; urgency=low
 
   * checks/scripts{,.desc}:
diff -Nru lintian-2.5.10.3/frontend/lintian lintian-2.5.10.4/frontend/lintian
--- lintian-2.5.10.3/frontend/lintian	2012-12-11 19:03:17.000000000 +0100
+++ lintian-2.5.10.4/frontend/lintian	2013-02-16 13:26:21.000000000 +0100
@@ -956,7 +956,13 @@
     # file?
     if (-f $arg) {
         if ($arg =~ m/\.(?:u?deb|dsc|changes)$/o){
-            $pool->add_file($arg);
+            eval {
+                $pool->add_file($arg);
+            };
+            if ($@) {
+                print STDERR "Skipping $arg: $@";
+                $exit_code = 2;
+            }
         } else {
             fail("bad package file name $arg (neither .deb, .udeb, .changes or .dsc file)");
         }
diff -Nru lintian-2.5.10.3/lib/Lintian/Collect/Package.pm lintian-2.5.10.4/lib/Lintian/Collect/Package.pm
--- lintian-2.5.10.3/lib/Lintian/Collect/Package.pm	2012-12-11 19:03:17.000000000 +0100
+++ lintian-2.5.10.4/lib/Lintian/Collect/Package.pm	2013-02-16 12:47:57.000000000 +0100
@@ -177,8 +177,10 @@
         $file{dirname} = $parent;
         $file{basename} = $base;
         $children{$parent} = [] unless exists $children{$parent};
-        push @{ $children{$parent} }, $name;
-
+        # Ensure the "root" is not its own child.  It is not really helpful
+        # from an analysis PoV and it creates ref cycles  (and by extension
+        # leaks like #695866).
+        push @{ $children{$parent} }, $name unless $parent eq $name;
     }
     @sorted = sort keys %idxh;
     foreach my $file (@sorted) {
diff -Nru lintian-2.5.10.3/lib/Lintian/Util.pm lintian-2.5.10.4/lib/Lintian/Util.pm
--- lintian-2.5.10.3/lib/Lintian/Util.pm	2012-12-11 19:03:17.000000000 +0100
+++ lintian-2.5.10.4/lib/Lintian/Util.pm	2013-02-16 13:27:17.000000000 +0100
@@ -227,8 +227,14 @@
 The default value for FLAGS is 0.
 
 If the file is empty (i.e. it contains no paragraphs), the method will
-contain an I<empty> list.  Lines looking like a GPG-signature is
-ignored when parsing the file.
+contain an I<empty> list.  The deb822 contents may be inside a
+I<signed> PGP message with a signature.
+
+visit_dpkg_paragraph will require the PGP headers to be correct (if
+present) and require that the entire file is covered by the signature.
+However, it will I<not> validate the signature (in fact, the contents
+of the PGP SIGNATURE part can be empty).  The signature should be
+validated separatedly.
 
 visit_dpkg_paragraph will pass paragraphs to CODE as they are
 completed.  If CODE can process the paragraphs as they are seen, very
@@ -295,6 +301,45 @@
 
 A comment line appeared and FLAGS contained DCTRL_NO_COMMENTS.
 
+=item PGP signature seen before start of signed message
+
+A "BEGIN PGP SIGNATURE" header is seen and a "BEGIN PGP MESSAGE" has
+not been seen yet.
+
+=item Two PGP signatures (first one at line %d)
+
+Two "BEGIN PGP SIGNATURE" headers are seen in the same file.
+
+=item Unexpected %s header
+
+A valid PGP header appears (e.g. "BEGIN PUBLIC KEY BLOCK").
+
+=item Malformed PGP header
+
+An invalid or malformed PGP header appears.
+
+=item Expected at most one signed message (previous at line %d)
+
+Two "BEGIN PGP MESSAGE" headers appears in the same message.
+
+=item End of file but expected a "END PGP SIGNATURE" header
+
+The file ended after a "BEGIN PGP SIGNATURE" header without being
+followed by a "END PGP SIGNATURE".
+
+=item PGP MESSAGE header must be first content if present
+
+The file had content before PGP MESSAGE.
+
+=item Data after the PGP SIGNATURE
+
+The file had data after the PGP SIGNATURE block ended.
+
+=item End of file before "BEGIN PGP SIGNATURE"
+
+The file had a "BEGIN PGP MESSAGE" header, but no signature was
+present.
+
 =back
 
 =cut
@@ -307,13 +352,13 @@
     my $open_section = 0;
     my $last_tag;
     my $debconf = $flags & DCTRL_DEBCONF_TEMPLATE;
+    my $signed = 0;
+    my $signature = 0;
 
     local $_;
     while (<$CONTROL>) {
         chomp;
 
-        # FIXME: comment lines are only allowed in debian/control and should
-        # be an error for other control files.
         if (/^\#/) {
             next unless $flags & DCTRL_NO_COMMENTS;
             die "syntax error at line $.: Comments are not allowed.\n";
@@ -328,18 +373,101 @@
                 $open_section = 0;
             }
         }
-        # pgp sig?
-        elsif (m/^-----BEGIN PGP SIGNATURE/) { # skip until end of signature
+        # pgp sig? Be strict here (due to #696230)
+        # According to http://tools.ietf.org/html/rfc4880#section-6.2
+        # The header MUST start at the beginning of the line and MUST NOT have
+        # any other text (except whitespace) after the header.
+        elsif (m/^-----BEGIN PGP SIGNATURE-----\s*$/) { # skip until end of signature
+            my $saw_end = 0;
+            if (not $signed or $signature) {
+                die "syntax error at line $.: PGP signature seen before start of signed message\n"
+                    if not $signed;
+                die "syntax error at line $.: Two PGP signatures (first one at line $signature)\n";
+            }
+            $signature = $.;
             while (<$CONTROL>) {
-                last if m/^-----END PGP SIGNATURE/o;
+                if (m/^-----END PGP SIGNATURE-----\s*$/o) {
+                    $saw_end = 1;
+                    last;
+                }
             }
+            # The "at line X" may seem a little weird, but it keeps the
+            # message format identical.
+            die "syntax error at line $.: End of file but expected a \"END PGP SIGNATURE\" header\n"
+                unless $saw_end;
         }
         # other pgp control?
-        elsif (m/^-----BEGIN PGP/) { # skip until the next blank line
+        elsif (m/^-----(?:BEGIN|END) PGP/) {
+            # At this point it could be a malformed PGP header or one
+            # of the following valid headers (RFC4880):
+            #  * BEGIN PGP MESSAGE
+            #    - Possibly a signed Debian CTRL, so okay (for now)
+            #  * BEGIN PGP {PUBLIC,PRIVATE} KEY BLOCK
+            #    - Valid header, but not a Debian CTRL file.
+            #  * BEGIN PGP MESSAGE, PART X{,/Y}
+            #    - Valid, but we don't support partial messages, so
+            #      bail on those.
+
+            unless (m/^-----BEGIN PGP SIGNED MESSAGE-----\s*$/) {
+                # Not a (full) PGP MESSAGE; reject.
+
+                my $key = qr/(?:BEGIN|END) PGP (?:PUBLIC|PRIVATE) KEY BLOCK/;
+                my $msgpart = qr{BEGIN PGP MESSAGE, PART \d+(?:/\d+)?};
+                my $msg = qr/(?:BEGIN|END) PGP (?:(?:COMPRESSED|ENCRYPTED) )?MESSAGE/;
+
+                if (m/^-----($key|$msgpart|$msg)-----\s*$/o) {
+                    die "syntax error at line $.: Unexpected $1 header\n";
+                } else {
+                    die "syntax error at line $.: Malformed PGP header\n";
+                }
+            } else {
+                if ($signed) {
+                    die "syntax error at line $.: Expected at most one signed message" .
+                        " (previous at line $signed)\n"
+                }
+                if ($sline > -1) {
+                    # NB: If you remove this, keep in mind that it may allow two paragraphs to
+                    # merge.  Consider:
+                    #
+                    # Field-P1: some-value
+                    # -----BEGIN PGP SIGANTURE----
+                    #
+                    # Field-P2: another value
+                    #
+                    # At the time of writing: If $open_section is
+                    # true, it will remain so until the empty line
+                    # after the PGP header.
+                    die "syntax error at line $.: PGP MESSAGE header must be first" .
+                        " content if present\n";
+                }
+                $signed = $.;
+            }
+
+            # skip until the next blank line
             while (<$CONTROL>) {
                 last if /^\s*$/o;
             }
         }
+        # did we see a signature already?  We allow all whitespace/comment lines
+        # outside the signature.
+        elsif ($signature) {
+            # Accept empty lines after the signature.
+            next if m/^\s*$/;
+
+            #NB: If you remove this, keep in mind that it may allow two paragraphs to
+            # merge.  Consider:
+            #
+            # Field-P1: some-value
+            # -----BEGIN PGP SIGANTURE----
+            # [...]
+            # -----END PGP SIGANTURE----
+            # Field-P2: another value
+            #
+            # At the time of writing: If $open_section is
+            # true, it will remain so until the empty line
+            # after the PGP header.
+            die "syntax error at line $.: Data after the PGP SIGNATURE\n";
+        }
         # new empty field?
         elsif (m/^([^: \t]+):\s*$/o) {
             $sline = $. if not $open_section;
@@ -395,6 +523,14 @@
     }
     # pass the last section (if not already done).
     $code->($section, $sline) if $open_section;
+
+    # Given the API, we cannot use this check to prevent any paragraphs from being
+    # emitted to the code argument, so we might as well just do this last.
+    if ($signed and not $signature) {
+        # The "at line X" may seem a little weird, but it keeps the
+        # message format identical.
+        die "syntax error at line $.: End of file before \"BEGIN PGP SIGNATURE\"\n";
+    }
 }
 
 =item read_dpkg_control (FILE[, FLAGS[, LINES]])
diff -Nru lintian-2.5.10.3/t/scripts/Lintian/Util/data/pgp-eof-missing-sign lintian-2.5.10.4/t/scripts/Lintian/Util/data/pgp-eof-missing-sign
diff -Nru lintian-2.5.10.3/t/scripts/Lintian/Util/data/pgp-leading-unsigned lintian-2.5.10.4/t/scripts/Lintian/Util/data/pgp-leading-unsigned
diff -Nru lintian-2.5.10.3/t/scripts/Lintian/Util/data/pgp-malformed-header lintian-2.5.10.4/t/scripts/Lintian/Util/data/pgp-malformed-header
diff -Nru lintian-2.5.10.3/t/scripts/Lintian/Util/data/pgp-no-end-pgp-header lintian-2.5.10.4/t/scripts/Lintian/Util/data/pgp-no-end-pgp-header
diff -Nru lintian-2.5.10.3/t/scripts/Lintian/Util/data/pgp-sig-before-start lintian-2.5.10.4/t/scripts/Lintian/Util/data/pgp-sig-before-start
diff -Nru lintian-2.5.10.3/t/scripts/Lintian/Util/data/pgp-trailing-unsigned lintian-2.5.10.4/t/scripts/Lintian/Util/data/pgp-trailing-unsigned
diff -Nru lintian-2.5.10.3/t/scripts/Lintian/Util/data/pgp-two-signatures lintian-2.5.10.4/t/scripts/Lintian/Util/data/pgp-two-signatures
diff -Nru lintian-2.5.10.3/t/scripts/Lintian/Util/data/pgp-two-signed-msgs lintian-2.5.10.4/t/scripts/Lintian/Util/data/pgp-two-signed-msgs
diff -Nru lintian-2.5.10.3/t/scripts/Lintian/Util/data/pgp-unexpected-header lintian-2.5.10.4/t/scripts/Lintian/Util/data/pgp-unexpected-header
diff -Nru lintian-2.5.10.3/t/scripts/Lintian/Util/dctrl-parser.t lintian-2.5.10.4/t/scripts/Lintian/Util/dctrl-parser.t

Reply to: