The following commit has been merged in the lenny branch:
commit d7bef0f124ea278948fceacb3e48e6846528d896
Author: Raphael Geissert <[email protected]>
Date:   Mon Jan 25 18:23:36 2010 -0600

    Fix CVE-2009-4013, missing control files sanitation
    
    Control field names and values were not sanitised before using them
    in certain operations that could lead to directory traversals.
    
    Patch systems' control files were not sanitised before using them
    in certain operations that could lead to directory traversals.
    
    An attacker could exploit these vulnerabilities to overwrite arbitrary
    files or disclose system information.

diff --git a/checks/fields b/checks/fields
index dc72f16..58139d9 100644
--- a/checks/fields
+++ b/checks/fields
@@ -880,8 +880,12 @@ if (open(FH, '<', 'fields/dm-upload-allowed')) {
 
 #----- Field checks (without checking the value)
 
-for my $field (glob("fields/*")) {
-       $field =~ s!^fields/!!;
+opendir(FIELDS, 'fields/')
+       or fail("cannot read fields/ directory: $!");
+for my $field (readdir FIELDS) {
+       next if ($field eq '.' || $field eq '..');
+
+       $field =~ s,:,/,g;
 
        next if ($field eq 'original-maintainer') and $version =~ /ubuntu/;
 
@@ -897,6 +901,7 @@ for my $field (glob("fields/*")) {
        tag "unknown-field-in-control", "$field"
            if ($type eq "udeb" && ! $known_udeb_fields{$field} && ! 
$known_obsolete_fields{$field});
 }
+closedir(FIELDS);
 
 }
 
diff --git a/checks/patch-systems b/checks/patch-systems
index 511a15d..f98f1d6 100644
--- a/checks/patch-systems
+++ b/checks/patch-systems
@@ -26,6 +26,7 @@ use common_data;
 use Dep;
 use Tags;
 use Util;
+use Cwd qw(realpath);
 
 sub run {
        my ($pkg, $type) = @_;
@@ -61,6 +62,8 @@ sub run {
        }
        my $quilt_format = ($format =~ /3\.\d+ \(quilt\)/) ? 1 : 0;
 
+       my $cwd = realpath('.');
+
        #----- dpatch
        if (Dep::implies($build_deps, Dep::parse("dpatch"))) {
                $uses_patch_system++;
@@ -100,6 +103,10 @@ sub run {
                                foreach my $patch_file (@patches) {
                                        $patch_file .= ".dpatch" if -e 
"debfiles/patches/$patch_file.dpatch"
                                                and not -e 
"debfiles/patches/$patch_file";
+                                       next if ( -l 
"debfiles/patches/$patch_file" );
+                                       unless 
(realpath("debfiles/patches/$patch_file") =~ m,^\Q$cwd\E/debfiles/,) {
+                                               next;
+                                       }
                                        if (! -r 
"debfiles/patches/$patch_file") {
                                                tag 
"dpatch-index-references-non-existent-patch", $patch_file;
                                                next;
@@ -152,6 +159,10 @@ 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;
+                                       }
                                        if (! -r 
"debfiles/patches/$patch_file") {
                                                tag 
"quilt-series-references-non-existent-patch", $patch_file;
                                                next;
diff --git a/collection/source-control-file b/collection/source-control-file
index 42d36ab..0e5203c 100755
--- a/collection/source-control-file
+++ b/collection/source-control-file
@@ -43,10 +43,12 @@ foreach (@control_data) {
     mkdir "control/$pkg_name", 0777
         or fail( "can't create dir control/$pkg_name: $!" );
     for my $field (keys %$_) {
+       my $value = $_->{$field};
+       $field =~ s,/,:,g;
         my $field_file = "control/$pkg_name/$field";
         open (F, '>', "$field_file")
             or fail("cannot open file $field_file for writing: $!");
-        print F $_->{$field},"\n";
+        print F $value,"\n";
         close F;
     }
 }
diff --git a/frontend/lintian b/frontend/lintian
index 1be2e9b..d2ab086 100755
--- a/frontend/lintian
+++ b/frontend/lintian
@@ -706,6 +706,9 @@ while (my $arg = shift) {
                next if $_ eq '';
 
                my ($md5sum,$size,$section,$priority,$file) = split(/\s+/o, $_);
+
+               next if ($file =~ m,/,);
+
                $files{$file}{md5} = $md5sum;
                $files{$file}{size} = $size;
 
@@ -1661,6 +1664,12 @@ sub get_src_info_from_lab {
 sub schedule_package {
     my ($type,$pkg,$ver,$file) = @_;
 
+    if ( $pkg =~ m,/, ) {
+       warn(sprintf("warning: bad name for %2\$s package '%1\$s', skipping\n",
+           $pkg, $type eq 'b' ? 'binary' : ($type eq 's' ? 'source': 'udeb')));
+       return;
+    }
+
     my $s = "$type $pkg $ver $file";
 
     if ( $already_scheduled{$s}++ ) {
diff --git a/unpack/unpack-binpkg-l1 b/unpack/unpack-binpkg-l1
index b2d8e6c..c0c6678 100755
--- a/unpack/unpack-binpkg-l1
+++ b/unpack/unpack-binpkg-l1
@@ -95,15 +95,19 @@ $data->{'source'} or ($data->{'source'} = 
$data->{'package'});
 
 # create control field files
 for my $field (keys %$data) {
+    my $value = $data->{$field};
+    $field =~ s,/,:,g;
     my $field_file = "$base_dir/fields/$field";
     open(F, '>', $field_file) or fail("cannot open file $field_file for 
writing: $!");
-    print F $data->{$field},"\n";
+    print F $value,"\n";
     close(F);
 }
 
-# create symlink to source package
-$data->{'source'} =~ s/\s*\(.*\)\s*$//;
-symlink("../../source/$data->{'source'}","$base_dir/source")
-    or fail("symlink: $!");
+if ($data->{'source'} !~ m,/,) {
+    # create symlink to source package
+    $data->{'source'} =~ s/\s*\(.*\)\s*$//;
+    symlink("../../source/$data->{'source'}","$base_dir/source")
+        or fail("symlink: $!");
+}
 
 exit 0;
diff --git a/unpack/unpack-srcpkg-l1 b/unpack/unpack-srcpkg-l1
index 4b9c237..eef79e6 100755
--- a/unpack/unpack-srcpkg-l1
+++ b/unpack/unpack-srcpkg-l1
@@ -49,9 +49,11 @@ mkdir("$base_dir/fields", 0777) or fail("mkdir 
$base_dir/fields: $!");
 
 # create control field files
 for my $field (keys %$data) {
+  my $value = $data->{$field};
+  $field =~ s,/,:,g;
   my $field_file = "$base_dir/fields/$field";
   open(F, '>', $field_file) or fail("cannot open file $field_file for writing: 
$!");
-  print F $data->{$field},"\n";
+  print F $value,"\n";
   close(F);
 }
 
@@ -62,12 +64,14 @@ symlink($file,"$base_dir/dsc") or fail("cannot symlink dsc 
file: $!");
 for my $fs (split(/\n/,$data->{'files'})) {
   next if $fs =~ /^\s*$/o;
   my @t = split(/\s+/o,$fs);
+  next if ($t[2] =~ m,/,);
   symlink("$dir/$t[2]","$base_dir/$t[2]") or fail("cannot symlink file $t[2]: 
$!");
 }
 
 # Create symbolic links to binary packages
 mkdir("$base_dir/binary", 0777) or fail("mkdir $base_dir/binary: $!");
 for my $bin (split(/,\s+/o,$data->{'binary'})) {
+  next if ($bin =~ m,/,);
   symlink("../../../binary/$bin", "$base_dir/binary/$bin") or fail("cannot 
symlink binary package $bin: $!");
 }
 

-- 
Debian package checker


-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]

Reply via email to