[dpkg] 03/13: dpkg-deb: Fix directory traversal with --raw-extract

Mattia Rizzolo mattia at debian.org
Mon Jan 22 17:11:51 UTC 2018


This is an automated email from the git hooks/post-receive script.

mattia pushed a commit to branch pu/reproducible_builds
in repository dpkg.

commit b98f0117f0c5a6c23e27a10d18aa8eabd5c8e82a
Author: Guillem Jover <guillem at debian.org>
Date:   Sat Oct 28 03:27:46 2017 +0200

    dpkg-deb: Fix directory traversal with --raw-extract
    
    Guarantee that the DEBIAN pathname does not exist.
    
    Closes: #879982
    Reported-by: Jakub Wilk <jwilk at jwilk.net>
    (cherry picked from commit 5003d763fdd29fe9533b2927eb083d6e6d6d98d4)
---
 debian/changelog    |  3 +++
 dpkg-deb/dpkg-deb.h |  2 ++
 dpkg-deb/extract.c  | 16 ++++++++--------
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index e38a93a..6fb0124 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,5 +1,8 @@
 dpkg (1.19.0.5) UNRELEASED; urgency=medium
 
+  * Fix directory traversal with dpkg-deb --raw-extract, by guaranteeing
+    that the DEBIAN pathname does not exist. Closes: #879982
+    Reported by Jakub Wilk <jwilk at jwilk.net>.
   * Perl modules:
     - Dpkg::Vendor::Debian: Use proper %use_feature key. This was causing perl
       errors on paths not accapted for fixdebugpath.
diff --git a/dpkg-deb/dpkg-deb.h b/dpkg-deb/dpkg-deb.h
index 6fd8f2b..a5e8d39 100644
--- a/dpkg-deb/dpkg-deb.h
+++ b/dpkg-deb/dpkg-deb.h
@@ -54,6 +54,8 @@ enum dpkg_tar_options {
 	DPKG_TAR_PERMS = DPKG_BIT(2),
 	/** Do not set tar mtime on extract. */
 	DPKG_TAR_NOMTIME = DPKG_BIT(3),
+	/** Guarantee extraction into a new directory, abort if it exists. */
+	DPKG_TAR_CREATE_DIR = DPKG_BIT(4),
 };
 
 void extracthalf(const char *debar, const char *dir,
diff --git a/dpkg-deb/extract.c b/dpkg-deb/extract.c
index ddb8709..dba15de 100644
--- a/dpkg-deb/extract.c
+++ b/dpkg-deb/extract.c
@@ -336,15 +336,15 @@ extracthalf(const char *debar, const char *dir,
       unsetenv("TAR_OPTIONS");
 
       if (dir) {
-        if (chdir(dir)) {
-          if (errno != ENOENT)
-            ohshite(_("failed to chdir to directory"));
-
-          if (mkdir(dir, 0777))
+        if (mkdir(dir, 0777) != 0) {
+          if (errno != EEXIST)
             ohshite(_("failed to create directory"));
-          if (chdir(dir))
-            ohshite(_("failed to chdir to directory after creating it"));
+
+          if (taroption & DPKG_TAR_CREATE_DIR)
+            ohshite(_("unexpected pre-existing pathname %s"), dir);
         }
+        if (chdir(dir) != 0)
+          ohshite(_("failed to chdir to directory"));
       }
 
       command_exec(&cmd);
@@ -490,7 +490,7 @@ do_raw_extract(const char *const *argv)
     data_options |= DPKG_TAR_LIST;
 
   extracthalf(debar, dir, data_options, 0);
-  extracthalf(debar, control_dir, DPKG_TAR_EXTRACT, 1);
+  extracthalf(debar, control_dir, DPKG_TAR_EXTRACT | DPKG_TAR_CREATE_DIR, 1);
 
   free(control_dir);
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/dpkg.git



More information about the Reproducible-commits mailing list