aboutsummaryrefslogtreecommitdiff
path: root/archival/tar.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-07-24 17:20:13 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-07-24 17:20:13 +0200
commitb920a38dc0a87f5884444d4731a8b887b5e16018 (patch)
tree5d845976a9471e705183db9afbbe7885e9070b52 /archival/tar.c
parentc810978552bc0133ba723ababaa178c8d53256e1 (diff)
downloadbusybox-w32-b920a38dc0a87f5884444d4731a8b887b5e16018.tar.gz
busybox-w32-b920a38dc0a87f5884444d4731a8b887b5e16018.tar.bz2
busybox-w32-b920a38dc0a87f5884444d4731a8b887b5e16018.zip
tar: postpone creation of symlinks with "suspicious" targets. Closes 8411
function old new delta data_extract_all 968 1038 +70 tar_main 952 986 +34 scan_tree 258 262 +4 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 108/0) Total: 108 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'archival/tar.c')
-rw-r--r--archival/tar.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/archival/tar.c b/archival/tar.c
index 0fc574dfd..280ded4e1 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -22,24 +22,6 @@
22 * 22 *
23 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 23 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
24 */ 24 */
25/* TODO: security with -C DESTDIR option can be enhanced.
26 * Consider tar file created via:
27 * $ tar cvf bug.tar anything.txt
28 * $ ln -s /tmp symlink
29 * $ tar --append -f bug.tar symlink
30 * $ rm symlink
31 * $ mkdir symlink
32 * $ tar --append -f bug.tar symlink/evil.py
33 *
34 * This will result in an archive which contains:
35 * $ tar --list -f bug.tar
36 * anything.txt
37 * symlink
38 * symlink/evil.py
39 *
40 * Untarring it puts evil.py in '/tmp' even if the -C DESTDIR is given.
41 * This doesn't feel right, and IIRC GNU tar doesn't do that.
42 */
43 25
44//config:config TAR 26//config:config TAR
45//config: bool "tar (40 kb)" 27//config: bool "tar (40 kb)"
@@ -296,6 +278,23 @@ static void chksum_and_xwrite(int fd, struct tar_header_t* hp)
296 xwrite(fd, hp, sizeof(*hp)); 278 xwrite(fd, hp, sizeof(*hp));
297} 279}
298 280
281static void replace_symlink_placeholders(llist_t *list)
282{
283 while (list) {
284 char *target;
285
286 target = list->data + strlen(list->data) + 1;
287 if (symlink(target, list->data)) {
288 /* shared message */
289 bb_error_msg_and_die("can't create %slink '%s' to '%s'",
290 "sym",
291 list->data, target
292 );
293 }
294 list = list->link;
295 }
296}
297
299#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS 298#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
300static void writeLongname(int fd, int type, const char *name, int dir) 299static void writeLongname(int fd, int type, const char *name, int dir)
301{ 300{
@@ -1252,6 +1251,8 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
1252 while (get_header_tar(tar_handle) == EXIT_SUCCESS) 1251 while (get_header_tar(tar_handle) == EXIT_SUCCESS)
1253 bb_got_signal = EXIT_SUCCESS; /* saw at least one header, good */ 1252 bb_got_signal = EXIT_SUCCESS; /* saw at least one header, good */
1254 1253
1254 replace_symlink_placeholders(tar_handle->symlink_placeholders);
1255
1255 /* Check that every file that should have been extracted was */ 1256 /* Check that every file that should have been extracted was */
1256 while (tar_handle->accept) { 1257 while (tar_handle->accept) {
1257 if (!find_list_entry(tar_handle->reject, tar_handle->accept->data) 1258 if (!find_list_entry(tar_handle->reject, tar_handle->accept->data)