ソースを参照

Dpkg::Source::Patch: Outright reject C-style filenames in patches

Because patch only started recognizing C-style filenames in diffs
in version 2.7, it's not safe to assume one behaviour or the other,
as the system might or might not have a recent enough version, or
a GNU patch program at all. There's also no reason we should be
supporting this kind of strange encoded filenames in patches, when
we have not done so up to now.

Let's just ban these types of diffs and be done with it.

Fixes: CVE-2014-0471
Closes: #746306
Guillem Jover 12 年 前
コミット
a12eb58959
共有2 個のファイルを変更した5 個の追加31 個の削除を含む
  1. 4 0
      debian/changelog
  2. 1 31
      scripts/Dpkg/Source/Patch.pm

+ 4 - 0
debian/changelog

@@ -1,5 +1,9 @@
 dpkg (1.17.9) UNRELEASED; urgency=low
 
+  [ Guillem Jover ]
+  * Do not allow patch files with C-style encoded filenames. Closes: #746306
+    Unconditionally fixes CVE-2014-0471.
+
   [ Updated scripts translations ]
   * French (Steve Petruzzello). Closes: #746350
   * German (Helge Kreutzmann).

+ 1 - 31
scripts/Dpkg/Source/Patch.pm

@@ -332,31 +332,6 @@ sub _getline {
     return $line;
 }
 
-my %ESCAPE = ((
-    'a' => "\a",
-    'b' => "\b",
-    'f' => "\f",
-    'n' => "\n",
-    'r' => "\r",
-    't' => "\t",
-    'v' => "\cK",
-    '\\' => '\\',
-    '"' => '"',
-), (
-    map { sprintf('%03o', $_) => chr($_) } (0..255)
-));
-
-sub _unescape {
-    my ($diff, $str) = @_;
-
-    if (exists $ESCAPE{$str}) {
-        return $ESCAPE{$str};
-    } else {
-        error(_g('diff %s patches file with unknown escape sequence \\%s'),
-              $diff, $str);
-    }
-}
-
 # Fetch the header filename ignoring the optional timestamp
 sub _fetch_filename {
     my ($diff, $header) = @_;
@@ -366,12 +341,7 @@ sub _fetch_filename {
 
     # Is it a C-style string?
     if ($header =~ m/^"/) {
-        $header =~ m/^"((?:[^\\"]|\\.)*)"/;
-        error(_g('diff %s patches file with unbalanced quote'), $diff)
-            unless defined $1;
-
-        $header = $1;
-        $header =~ s/\\([0-3][0-7]{2}|.)/_unescape($diff, $1)/eg;
+        error(_g('diff %s patches file with C-style encoded filename'), $diff);
     } else {
         # Tab is the official separator, it's always used when
         # filename contain spaces. Try it first, otherwise strip on space