diff options
author | Guillem Jover <guillem@debian.org> | 2017-10-28 03:27:46 +0200 |
---|---|---|
committer | Guillem Jover <guillem@debian.org> | 2018-01-16 10:55:30 +0100 |
commit | 5003d763fdd29fe9533b2927eb083d6e6d6d98d4 (patch) | |
tree | 785a9a929dc8f8b6e432d260ff1fd7d9b26e5828 | |
parent | fe186374cd2a287723fe227fe37ea4a5373822c0 (diff) | |
download | dpkg-5003d763fdd29fe9533b2927eb083d6e6d6d98d4.tar.gz |
dpkg-deb: Fix directory traversal with --raw-extract
Guarantee that the DEBIAN pathname does not exist.
Closes: #879982
Reported-by: Jakub Wilk <jwilk@jwilk.net>
-rw-r--r-- | debian/changelog | 3 | ||||
-rw-r--r-- | dpkg-deb/dpkg-deb.h | 2 | ||||
-rw-r--r-- | dpkg-deb/extract.c | 16 |
3 files changed, 13 insertions, 8 deletions
diff --git a/debian/changelog b/debian/changelog index 8ed5546f1..03893d071 100644 --- a/debian/changelog +++ b/debian/changelog @@ -13,6 +13,9 @@ dpkg (1.19.1) UNRELEASED; urgency=medium be needed. Reported by Niels Thykier <niels@thykier.net>. * Add color support to dpkg-maintscript-helper (a shell script). * Fix warning by including <sys/sysmacros.h> for makedev() in libdpkg. + * Fix directory traversal with dpkg-deb --raw-extract, by guaranteeing + that the DEBIAN pathname does not exist. Closes: #879982 + Reported by Jakub Wilk <jwilk@jwilk.net>. * Perl modules: - Check that $tarname is defined before use in Dpkg::Source::Package::V1. Thanks to Christoph Biedl <debian.axhn@manchmal.in-ulm.de>. diff --git a/dpkg-deb/dpkg-deb.h b/dpkg-deb/dpkg-deb.h index 6fd8f2b0a..a5e8d39ce 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 ddb8709cd..dba15dedb 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); |