Rebuild dpkg for 7.0.
[packages/centos6/dpkg.git] / fedora-fix-CVE-2010-1679_CVE-2011-0402.patch
1 diff -ruN dpkg-1.15.5.6ubuntu4/scripts/Dpkg/Source/Archive.pm dpkg-1.15.5.6ubuntu4.5//scripts/Dpkg/Source/Archive.pm
2 --- dpkg-1.15.5.6ubuntu4/scripts/Dpkg/Source/Archive.pm 2010-04-15 13:38:58.000000000 +0200
3 +++ dpkg-1.15.5.6ubuntu4.5//scripts/Dpkg/Source/Archive.pm      2011-01-06 21:08:30.000000000 +0200
4 @@ -119,7 +119,7 @@
5      # Call tar extraction process
6      $fork_opts{"delete_env"} = [ "TAR_OPTIONS" ];
7      $fork_opts{'exec'} = [ 'tar', '--no-same-owner', '--no-same-permissions',
8 -                           @{$opts{"options"}}, '-xkf', '-' ];
9 +                           @{$opts{"options"}}, '-xf', '-' ];
10      fork_and_exec(%fork_opts);
11      $self->cleanup_after_open();
12  
13 @@ -142,7 +142,7 @@
14      closedir(D);
15      my $done = 0;
16      erasedir($dest);
17 -    if (scalar(@entries) == 1 && -d "$tmp/$entries[0]") {
18 +    if (scalar(@entries) == 1 && ! -l "$tmp/$entries[0]" && -d _) {
19         rename("$tmp/$entries[0]", $dest) ||
20                 syserr(_g("Unable to rename %s to %s"),
21                        "$tmp/$entries[0]", $dest);
22 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
23 --- dpkg-1.15.5.6ubuntu4/scripts/Dpkg/Source/Package/V2.pm      2010-04-15 13:38:58.000000000 +0200
24 +++ dpkg-1.15.5.6ubuntu4.5//scripts/Dpkg/Source/Package/V2.pm   2011-01-06 21:08:30.000000000 +0200
25 @@ -115,7 +115,12 @@
26      # Extract main tarball
27      info(_g("unpacking %s"), $tarfile);
28      my $tar = Dpkg::Source::Archive->new(filename => "$dscdir$tarfile");
29 -    $tar->extract($newdirectory, no_fixperms => 1);
30 +    $tar->extract($newdirectory, no_fixperms => 1,
31 +                  options => [ "--anchored", "--no-wildcards-match-slash",
32 +                               "--exclude", "*/.pc", "--exclude", ".pc" ]);
33 +    # The .pc exclusion is only needed for 3.0 (quilt) and to avoid
34 +    # having an upstream tarball provide a directory with symlinks
35 +    # that would be blindly followed when applying the patches
36  
37      # Extract additional orig tarballs
38      foreach my $subdir (keys %origtar) {
39 diff -ruN dpkg-1.15.5.6ubuntu4/scripts/Dpkg/Source/Patch.pm dpkg-1.15.5.6ubuntu4.5//scripts/Dpkg/Source/Patch.pm
40 --- dpkg-1.15.5.6ubuntu4/scripts/Dpkg/Source/Patch.pm   2010-04-15 13:38:58.000000000 +0200
41 +++ dpkg-1.15.5.6ubuntu4.5//scripts/Dpkg/Source/Patch.pm        2011-01-06 21:08:30.000000000 +0200
42 @@ -313,11 +313,42 @@
43          $header =~ s/\s.*// unless ($header =~ s/\t.*//);
44          return $header;
45      }
46 +
47 +    sub intuit_file_patched {
48 +       my ($old, $new) = @_;
49 +       return $new unless defined $old;
50 +       return $old unless defined $new;
51 +       return $new if -e $new and not -e $old;
52 +       return $old if -e $old and not -e $new;
53 +       # We don't consider the case where both files are non-existent and
54 +       # where patch picks the one with the fewest directories to create
55 +       # since dpkg-source will pre-create the required directories
56 +       #
57 +       # Precalculate metrics used by patch
58 +       my ($tmp_o, $tmp_n) = ($old, $new);
59 +       my ($len_o, $len_n) = (length($old), length($new));
60 +       $tmp_o =~ s{[/\\]+}{/}g;
61 +       $tmp_n =~ s{[/\\]+}{/}g;
62 +       my $nb_comp_o = ($tmp_o =~ tr{/}{/});
63 +       my $nb_comp_n = ($tmp_n =~ tr{/}{/});
64 +       $tmp_o =~ s{^.*/}{};
65 +       $tmp_n =~ s{^.*/}{};
66 +       my ($blen_o, $blen_n) = (length($tmp_o), length($tmp_n));
67 +       # Decide like patch would
68 +       if ($nb_comp_o != $nb_comp_n) {
69 +           return ($nb_comp_o < $nb_comp_n) ? $old : $new;
70 +       } elsif ($blen_o != $blen_n) {
71 +           return ($blen_o < $blen_n) ? $old : $new;
72 +       } elsif ($len_o != $len_n) {
73 +           return ($len_o < $len_n) ? $old : $new;
74 +       }
75 +       return $old;
76 +    }
77      $_ = getline($diff_handle);
78  
79    HUNK:
80      while (defined($_) || not eof($diff_handle)) {
81 -       my ($fn, $fn2);
82 +       my (%path, %fn);
83         # skip comments leading up to patch (if any)
84         until (/^--- /) {
85             last HUNK if not defined($_ = getline($diff_handle));
86 @@ -327,11 +358,8 @@
87         unless(s/^--- //) {
88             error(_g("expected ^--- in line %d of diff `%s'"), $., $diff);
89         }
90 -        $_ = strip_ts($_);
91 -        if ($_ eq '/dev/null' or s{^[^/]+/}{$destdir/}) {
92 -            $fn = $_;
93 -           error(_g("%s contains an insecure path: %s"), $diff, $_) if m{/\.\./};
94 -        }
95 +        $path{'old'} = $_ = strip_ts($_);
96 +       $fn{'old'} = $_ if $_ ne '/dev/null' and s{^[^/]*/+}{$destdir/};
97         if (/\.dpkg-orig$/) {
98             error(_g("diff `%s' patches file with name ending .dpkg-orig"), $diff);
99         }
100 @@ -342,46 +370,47 @@
101         unless (s/^\+\+\+ //) {
102             error(_g("line after --- isn't as expected in diff `%s' (line %d)"), $diff, $.);
103         }
104 -        $_ = strip_ts($_);
105 -        if ($_ eq '/dev/null' or s{^[^/]+/}{$destdir/}) {
106 -            $fn2 = $_;
107 -           error(_g("%s contains an insecure path: %s"), $diff, $_) if m{/\.\./};
108 -        } else {
109 -            unless (defined $fn) {
110 -                error(_g("none of the filenames in ---/+++ are relative in diff `%s' (line %d)"),
111 -                      $diff, $.);
112 -            }
113 -        }
114 +        $path{'new'} = $_ = strip_ts($_);
115 +       $fn{'new'} = $_ if $_ ne '/dev/null' and s{^[^/]*/+}{$destdir/};
116 +
117 +       unless (defined $fn{'old'} or defined $fn{'new'}) {
118 +           error(_g("none of the filenames in ---/+++ are valid in diff '%s' (line %d)"),
119 +                 $diff, $.);
120 +       }
121  
122 -        if (defined($fn) and $fn eq '/dev/null') {
123 +       # Safety checks on both filenames that patch could use
124 +       foreach my $key ("old", "new") {
125 +           next unless defined $fn{$key};
126 +           if ($path{$key} =~ m{/\.\./}) {
127 +               error(_g("%s contains an insecure path: %s"), $diff, $path{$key});
128 +           }
129 +           my $path = $fn{$key};
130 +           while (1) {
131 +               if (-l $path) {
132 +                   error(_g("diff %s modifies file %s through a symlink: %s"),
133 +                         $diff, $fn{$key}, $path);
134 +               }
135 +               last unless $path =~ s{/+[^/]*$}{};
136 +               last if length($path) <= length($destdir); # $destdir is assumed safe
137 +           }
138 +       }
139 +
140 +        if ($path{'old'} eq '/dev/null' and $path{'new'} eq '/dev/null') {
141              error(_g("original and modified files are /dev/null in diff `%s' (line %d)"),
142 -                  $diff, $.) if (defined($fn2) and $fn2 eq '/dev/null');
143 -            $fn = $fn2;
144 -        } elsif (defined($fn2) and $fn2 ne '/dev/null') {
145 -            $fn = $fn2 unless defined $fn;
146 -            $fn = $fn2 if ((not -e $fn) and -e $fn2);
147 -        } elsif (defined($fn2) and $fn2 eq '/dev/null') {
148 +                  $diff, $.);
149 +        } elsif ($path{'new'} eq '/dev/null') {
150              error(_g("file removal without proper filename in diff `%s' (line %d)"),
151 -                  $diff, $. - 1) unless defined $fn;
152 +                  $diff, $. - 1) unless defined $fn{'old'};
153              warning(_g("diff %s removes a non-existing file %s (line %d)"),
154 -                    $diff, $fn, $.) unless -e $fn;
155 +                    $diff, $fn{'old'}, $.) unless -e $fn{'old'};
156          }
157 +       my $fn = intuit_file_patched($fn{'old'}, $fn{'new'});
158  
159         my $dirname = $fn;
160         if ($dirname =~ s{/[^/]+$}{} && not -d $dirname) {
161             $dirtocreate{$dirname} = 1;
162         }
163  
164 -       # Sanity check, refuse to patch through a symlink
165 -       $dirname = $fn;
166 -       while (1) {
167 -           if (-l $dirname) {
168 -               error(_g("diff %s modifies file %s through a symlink: %s"),
169 -                     $diff, $fn, $dirname);
170 -           }
171 -           last unless $dirname =~ s{/[^/]+$}{};
172 -       }
173 -
174         if (-e $fn and not -f _) {
175             error(_g("diff `%s' patches something which is not a plain file"), $diff);
176         }