Procházet zdrojové kódy

Dpkg::Control::Hash: Do not accept Armor Header Lines inside a paragraph

Make sure that no fields are injected before a signed block.

Although the only possible attack is to add fields not present in the
signed block, as otherwise a syntax error due to duplicate field is
triggered.
Guillem Jover před 13 roky
rodič
revize
afe626640a

+ 1 - 0
debian/changelog

@@ -9,6 +9,7 @@ dpkg (1.16.10) UNRELEASED; urgency=low
   * Fix OpenPGP armored signature parsing, to be resilient against doctored
     input, including source package control files. Closes: #695919
   * Make sure the OpenGPG armor contains a signature block, even on EOF.
+  * Do not accept Armor Header Lines inside a paragraph.
 
   [ Updated programs translations ]
   * Esperanto (Felipe Castro).

+ 3 - 1
scripts/Dpkg/Control/Hash.pm

@@ -169,6 +169,7 @@ sub parse {
     my ($self, $fh, $desc) = @_;
 
     my $paraborder = 1;
+    my $parabody = 0;
     my $cf; # Current field
     my $expect_pgp_sig = 0;
     my $pgp_signed = 0;
@@ -179,6 +180,7 @@ sub parse {
 	next if (m/^#/);
 	$paraborder = 0;
 	if (m/^(\S+?)\s*:\s*(.*)$/) {
+	    $parabody = 1;
 	    if (exists $self->{$1}) {
 		unless ($$self->{'allow_duplicate'}) {
 		    syntaxerr($desc, sprintf(_g("duplicate field %s found"), $1));
@@ -197,7 +199,7 @@ sub parse {
 	    $self->{$cf} .= "\n$line";
 	} elsif (m/^-----BEGIN PGP SIGNED MESSAGE-----$/) {
 	    $expect_pgp_sig = 1;
-	    if ($$self->{'allow_pgp'}) {
+	    if ($$self->{'allow_pgp'} and not $parabody) {
 		# Skip PGP headers
 		while (<$fh>) {
 		    last if m/^\s*$/;

+ 1 - 0
scripts/Makefile.am

@@ -233,6 +233,7 @@ test_data = \
 	t/700_Dpkg_Control/bogus-armor-double.dsc \
 	t/700_Dpkg_Control/bogus-armor-no-sig.dsc \
 	t/700_Dpkg_Control/bogus-armor-trail.dsc \
+	t/700_Dpkg_Control/bogus-armor-inline.dsc \
 	t/700_Dpkg_Control/bogus-armor-nested.dsc \
 	t/700_Dpkg_Control/bogus-armor-spaces.dsc \
 	t/750_Dpkg_Substvars/substvars1 \

+ 4 - 1
scripts/t/700_Dpkg_Control.t

@@ -13,7 +13,7 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-use Test::More tests => 21;
+use Test::More tests => 22;
 
 use strict;
 use warnings;
@@ -115,6 +115,9 @@ is($dsc, undef, 'Signed .dsc w/ OpenPGP armor missing signature');
 $dsc = parse_dsc("$datadir/bogus-armor-trail.dsc");
 is($dsc, undef, 'Signed .dsc w/ bogus OpenPGP armor trailer');
 
+$dsc = parse_dsc("$datadir/bogus-armor-inline.dsc");
+is($dsc, undef, 'Signed .dsc w/ bogus OpenPGP inline armor');
+
 $dsc = parse_dsc("$datadir/bogus-armor-double.dsc");
 ok(defined $dsc, 'Signed .dsc w/ two OpenPGP armor signatures');
 is($dsc->{Source}, 'pass', 'Signed spaced .dsc package name');

+ 9 - 0
scripts/t/700_Dpkg_Control/bogus-armor-inline.dsc

@@ -0,0 +1,9 @@
+Source: fail
+-----BEGIN PGP SIGNED MESSAGE-----
+    
+Binary: pass
+    
+-----BEGIN PGP SIGNATURE-----
+
+Valid signature here.
+-----END PGP SIGNATURE-----