X-Git-Url: https://review.fuel-infra.org/gitweb?a=blobdiff_plain;f=fedora-fix-CVE-2010-1679_CVE-2011-0402.patch;fp=fedora-fix-CVE-2010-1679_CVE-2011-0402.patch;h=26ce08d151afca93dc3ce8526264184356f38323;hb=7873dbf84dcb4924fa288ea1a5756cf9962bdb65;hp=0000000000000000000000000000000000000000;hpb=e67ebab51c40c917c67af3cc22e50b8645ead389;p=packages%2Fcentos6%2Fdpkg.git diff --git a/fedora-fix-CVE-2010-1679_CVE-2011-0402.patch b/fedora-fix-CVE-2010-1679_CVE-2011-0402.patch new file mode 100644 index 0000000..26ce08d --- /dev/null +++ b/fedora-fix-CVE-2010-1679_CVE-2011-0402.patch @@ -0,0 +1,176 @@ +diff -ruN dpkg-1.15.5.6ubuntu4/scripts/Dpkg/Source/Archive.pm dpkg-1.15.5.6ubuntu4.5//scripts/Dpkg/Source/Archive.pm +--- dpkg-1.15.5.6ubuntu4/scripts/Dpkg/Source/Archive.pm 2010-04-15 13:38:58.000000000 +0200 ++++ dpkg-1.15.5.6ubuntu4.5//scripts/Dpkg/Source/Archive.pm 2011-01-06 21:08:30.000000000 +0200 +@@ -119,7 +119,7 @@ + # Call tar extraction process + $fork_opts{"delete_env"} = [ "TAR_OPTIONS" ]; + $fork_opts{'exec'} = [ 'tar', '--no-same-owner', '--no-same-permissions', +- @{$opts{"options"}}, '-xkf', '-' ]; ++ @{$opts{"options"}}, '-xf', '-' ]; + fork_and_exec(%fork_opts); + $self->cleanup_after_open(); + +@@ -142,7 +142,7 @@ + closedir(D); + my $done = 0; + erasedir($dest); +- if (scalar(@entries) == 1 && -d "$tmp/$entries[0]") { ++ if (scalar(@entries) == 1 && ! -l "$tmp/$entries[0]" && -d _) { + rename("$tmp/$entries[0]", $dest) || + syserr(_g("Unable to rename %s to %s"), + "$tmp/$entries[0]", $dest); +diff -ruN dpkg-1.15.5.6ubuntu4/scripts/Dpkg/Source/Package/V2.pm dpkg-1.15.5.6ubuntu4.5//scripts/Dpkg/Source/Package/V2.pm +--- dpkg-1.15.5.6ubuntu4/scripts/Dpkg/Source/Package/V2.pm 2010-04-15 13:38:58.000000000 +0200 ++++ dpkg-1.15.5.6ubuntu4.5//scripts/Dpkg/Source/Package/V2.pm 2011-01-06 21:08:30.000000000 +0200 +@@ -115,7 +115,12 @@ + # Extract main tarball + info(_g("unpacking %s"), $tarfile); + my $tar = Dpkg::Source::Archive->new(filename => "$dscdir$tarfile"); +- $tar->extract($newdirectory, no_fixperms => 1); ++ $tar->extract($newdirectory, no_fixperms => 1, ++ options => [ "--anchored", "--no-wildcards-match-slash", ++ "--exclude", "*/.pc", "--exclude", ".pc" ]); ++ # The .pc exclusion is only needed for 3.0 (quilt) and to avoid ++ # having an upstream tarball provide a directory with symlinks ++ # that would be blindly followed when applying the patches + + # Extract additional orig tarballs + foreach my $subdir (keys %origtar) { +diff -ruN dpkg-1.15.5.6ubuntu4/scripts/Dpkg/Source/Patch.pm dpkg-1.15.5.6ubuntu4.5//scripts/Dpkg/Source/Patch.pm +--- dpkg-1.15.5.6ubuntu4/scripts/Dpkg/Source/Patch.pm 2010-04-15 13:38:58.000000000 +0200 ++++ dpkg-1.15.5.6ubuntu4.5//scripts/Dpkg/Source/Patch.pm 2011-01-06 21:08:30.000000000 +0200 +@@ -313,11 +313,42 @@ + $header =~ s/\s.*// unless ($header =~ s/\t.*//); + return $header; + } ++ ++ sub intuit_file_patched { ++ my ($old, $new) = @_; ++ return $new unless defined $old; ++ return $old unless defined $new; ++ return $new if -e $new and not -e $old; ++ return $old if -e $old and not -e $new; ++ # We don't consider the case where both files are non-existent and ++ # where patch picks the one with the fewest directories to create ++ # since dpkg-source will pre-create the required directories ++ # ++ # Precalculate metrics used by patch ++ my ($tmp_o, $tmp_n) = ($old, $new); ++ my ($len_o, $len_n) = (length($old), length($new)); ++ $tmp_o =~ s{[/\\]+}{/}g; ++ $tmp_n =~ s{[/\\]+}{/}g; ++ my $nb_comp_o = ($tmp_o =~ tr{/}{/}); ++ my $nb_comp_n = ($tmp_n =~ tr{/}{/}); ++ $tmp_o =~ s{^.*/}{}; ++ $tmp_n =~ s{^.*/}{}; ++ my ($blen_o, $blen_n) = (length($tmp_o), length($tmp_n)); ++ # Decide like patch would ++ if ($nb_comp_o != $nb_comp_n) { ++ return ($nb_comp_o < $nb_comp_n) ? $old : $new; ++ } elsif ($blen_o != $blen_n) { ++ return ($blen_o < $blen_n) ? $old : $new; ++ } elsif ($len_o != $len_n) { ++ return ($len_o < $len_n) ? $old : $new; ++ } ++ return $old; ++ } + $_ = getline($diff_handle); + + HUNK: + while (defined($_) || not eof($diff_handle)) { +- my ($fn, $fn2); ++ my (%path, %fn); + # skip comments leading up to patch (if any) + until (/^--- /) { + last HUNK if not defined($_ = getline($diff_handle)); +@@ -327,11 +358,8 @@ + unless(s/^--- //) { + error(_g("expected ^--- in line %d of diff `%s'"), $., $diff); + } +- $_ = strip_ts($_); +- if ($_ eq '/dev/null' or s{^[^/]+/}{$destdir/}) { +- $fn = $_; +- error(_g("%s contains an insecure path: %s"), $diff, $_) if m{/\.\./}; +- } ++ $path{'old'} = $_ = strip_ts($_); ++ $fn{'old'} = $_ if $_ ne '/dev/null' and s{^[^/]*/+}{$destdir/}; + if (/\.dpkg-orig$/) { + error(_g("diff `%s' patches file with name ending .dpkg-orig"), $diff); + } +@@ -342,46 +370,47 @@ + unless (s/^\+\+\+ //) { + error(_g("line after --- isn't as expected in diff `%s' (line %d)"), $diff, $.); + } +- $_ = strip_ts($_); +- if ($_ eq '/dev/null' or s{^[^/]+/}{$destdir/}) { +- $fn2 = $_; +- error(_g("%s contains an insecure path: %s"), $diff, $_) if m{/\.\./}; +- } else { +- unless (defined $fn) { +- error(_g("none of the filenames in ---/+++ are relative in diff `%s' (line %d)"), +- $diff, $.); +- } +- } ++ $path{'new'} = $_ = strip_ts($_); ++ $fn{'new'} = $_ if $_ ne '/dev/null' and s{^[^/]*/+}{$destdir/}; ++ ++ unless (defined $fn{'old'} or defined $fn{'new'}) { ++ error(_g("none of the filenames in ---/+++ are valid in diff '%s' (line %d)"), ++ $diff, $.); ++ } + +- if (defined($fn) and $fn eq '/dev/null') { ++ # Safety checks on both filenames that patch could use ++ foreach my $key ("old", "new") { ++ next unless defined $fn{$key}; ++ if ($path{$key} =~ m{/\.\./}) { ++ error(_g("%s contains an insecure path: %s"), $diff, $path{$key}); ++ } ++ my $path = $fn{$key}; ++ while (1) { ++ if (-l $path) { ++ error(_g("diff %s modifies file %s through a symlink: %s"), ++ $diff, $fn{$key}, $path); ++ } ++ last unless $path =~ s{/+[^/]*$}{}; ++ last if length($path) <= length($destdir); # $destdir is assumed safe ++ } ++ } ++ ++ if ($path{'old'} eq '/dev/null' and $path{'new'} eq '/dev/null') { + error(_g("original and modified files are /dev/null in diff `%s' (line %d)"), +- $diff, $.) if (defined($fn2) and $fn2 eq '/dev/null'); +- $fn = $fn2; +- } elsif (defined($fn2) and $fn2 ne '/dev/null') { +- $fn = $fn2 unless defined $fn; +- $fn = $fn2 if ((not -e $fn) and -e $fn2); +- } elsif (defined($fn2) and $fn2 eq '/dev/null') { ++ $diff, $.); ++ } elsif ($path{'new'} eq '/dev/null') { + error(_g("file removal without proper filename in diff `%s' (line %d)"), +- $diff, $. - 1) unless defined $fn; ++ $diff, $. - 1) unless defined $fn{'old'}; + warning(_g("diff %s removes a non-existing file %s (line %d)"), +- $diff, $fn, $.) unless -e $fn; ++ $diff, $fn{'old'}, $.) unless -e $fn{'old'}; + } ++ my $fn = intuit_file_patched($fn{'old'}, $fn{'new'}); + + my $dirname = $fn; + if ($dirname =~ s{/[^/]+$}{} && not -d $dirname) { + $dirtocreate{$dirname} = 1; + } + +- # Sanity check, refuse to patch through a symlink +- $dirname = $fn; +- while (1) { +- if (-l $dirname) { +- error(_g("diff %s modifies file %s through a symlink: %s"), +- $diff, $fn, $dirname); +- } +- last unless $dirname =~ s{/[^/]+$}{}; +- } +- + if (-e $fn and not -f _) { + error(_g("diff `%s' patches something which is not a plain file"), $diff); + }