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: