X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=archival%2Ftar.c;h=280ded4e14e325811e2cf976a050bac6e7ba4b27;hb=619d9b5e6848a72350126ea9c1e413fd133181e3;hp=fcabb01261be225d65e815042157f787f5f11689;hpb=4eed2c6c5092ed95b8ee6d994106c54a9fc6ed3e;p=oweals%2Fbusybox.git diff --git a/archival/tar.c b/archival/tar.c index fcabb0126..280ded4e1 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -22,32 +22,14 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ -/* TODO: security with -C DESTDIR option can be enhanced. - * Consider tar file created via: - * $ tar cvf bug.tar anything.txt - * $ ln -s /tmp symlink - * $ tar --append -f bug.tar symlink - * $ rm symlink - * $ mkdir symlink - * $ tar --append -f bug.tar symlink/evil.py - * - * This will result in an archive which contains: - * $ tar --list -f bug.tar - * anything.txt - * symlink - * symlink/evil.py - * - * Untarring it puts evil.py in '/tmp' even if the -C DESTDIR is given. - * This doesn't feel right, and IIRC GNU tar doesn't do that. - */ //config:config TAR //config: bool "tar (40 kb)" //config: default y //config: help -//config: tar is an archiving program. It's commonly used with gzip to -//config: create compressed archives. It's probably the most widely used -//config: UNIX archive program. +//config: tar is an archiving program. It's commonly used with gzip to +//config: create compressed archives. It's probably the most widely used +//config: UNIX archive program. //config: //config:config FEATURE_TAR_LONG_OPTIONS //config: bool "Enable long options" @@ -64,35 +46,35 @@ //config: default y //config: depends on TAR && (FEATURE_SEAMLESS_Z || FEATURE_SEAMLESS_GZ || FEATURE_SEAMLESS_BZ2 || FEATURE_SEAMLESS_LZMA || FEATURE_SEAMLESS_XZ) //config: help -//config: With this option tar can automatically detect compressed -//config: tarballs. Currently it works only on files (not pipes etc). +//config: With this option tar can automatically detect compressed +//config: tarballs. Currently it works only on files (not pipes etc). //config: //config:config FEATURE_TAR_FROM //config: bool "Enable -X (exclude from) and -T (include from) options)" //config: default y //config: depends on TAR //config: help -//config: If you enable this option you'll be able to specify -//config: a list of files to include or exclude from an archive. +//config: If you enable this option you'll be able to specify +//config: a list of files to include or exclude from an archive. //config: //config:config FEATURE_TAR_OLDGNU_COMPATIBILITY //config: bool "Support old tar header format" //config: default y //config: depends on TAR || DPKG //config: help -//config: This option is required to unpack archives created in -//config: the old GNU format; help to kill this old format by -//config: repacking your ancient archives with the new format. +//config: This option is required to unpack archives created in +//config: the old GNU format; help to kill this old format by +//config: repacking your ancient archives with the new format. //config: //config:config FEATURE_TAR_OLDSUN_COMPATIBILITY //config: bool "Enable untarring of tarballs with checksums produced by buggy Sun tar" //config: default y //config: depends on TAR || DPKG //config: help -//config: This option is required to unpack archives created by some old -//config: version of Sun's tar (it was calculating checksum using signed -//config: arithmetic). It is said to be fixed in newer Sun tar, but "old" -//config: tarballs still exist. +//config: This option is required to unpack archives created by some old +//config: version of Sun's tar (it was calculating checksum using signed +//config: arithmetic). It is said to be fixed in newer Sun tar, but "old" +//config: tarballs still exist. //config: //config:config FEATURE_TAR_GNU_EXTENSIONS //config: bool "Support GNU tar extensions (long filenames)" @@ -104,18 +86,18 @@ //config: default y //config: depends on TAR && FEATURE_TAR_LONG_OPTIONS //config: help -//config: If you enable this option you'll be able to instruct tar to send -//config: the contents of each extracted file to the standard input of an -//config: external program. +//config: If you enable this option you'll be able to instruct tar to send +//config: the contents of each extracted file to the standard input of an +//config: external program. //config: //config:config FEATURE_TAR_UNAME_GNAME //config: bool "Enable use of user and group names" //config: default y //config: depends on TAR //config: help -//config: Enable use of user and group names in tar. This affects contents -//config: listings (-t) and preserving permissions when unpacking (-p). -//config: +200 bytes. +//config: Enable use of user and group names in tar. This affects contents +//config: listings (-t) and preserving permissions when unpacking (-p). +//config: +200 bytes. //config: //config:config FEATURE_TAR_NOPRESERVE_TIME //config: bool "Enable -m (do not preserve time) GNU option" @@ -127,8 +109,8 @@ //config: default n //config: depends on TAR && SELINUX //config: help -//config: With this option busybox supports restoring SELinux labels -//config: when extracting files from tar archives. +//config: With this option busybox supports restoring SELinux labels +//config: when extracting files from tar archives. //applet:IF_TAR(APPLET(tar, BB_DIR_BIN, BB_SUID_DROP)) //kbuild:lib-$(CONFIG_TAR) += tar.o @@ -296,6 +278,23 @@ static void chksum_and_xwrite(int fd, struct tar_header_t* hp) xwrite(fd, hp, sizeof(*hp)); } +static void replace_symlink_placeholders(llist_t *list) +{ + while (list) { + char *target; + + target = list->data + strlen(list->data) + 1; + if (symlink(target, list->data)) { + /* shared message */ + bb_error_msg_and_die("can't create %slink '%s' to '%s'", + "sym", + list->data, target + ); + } + list = list->link; + } +} + #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS static void writeLongname(int fd, int type, const char *name, int dir) { @@ -1252,6 +1251,8 @@ int tar_main(int argc UNUSED_PARAM, char **argv) while (get_header_tar(tar_handle) == EXIT_SUCCESS) bb_got_signal = EXIT_SUCCESS; /* saw at least one header, good */ + replace_symlink_placeholders(tar_handle->symlink_placeholders); + /* Check that every file that should have been extracted was */ while (tar_handle->accept) { if (!find_list_entry(tar_handle->reject, tar_handle->accept->data)