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 /dpkg-deb | |
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>
Diffstat (limited to 'dpkg-deb')
-rw-r--r-- | dpkg-deb/dpkg-deb.h | 2 | ||||
-rw-r--r-- | dpkg-deb/extract.c | 16 |
2 files changed, 10 insertions, 8 deletions
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); |