diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-02-20 15:57:45 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-02-20 16:06:53 +0100 |
| commit | a84db18fc71d09e801df0ebca048d82e90b32c6a (patch) | |
| tree | 1eda8cd659f78406f1b9f86d5e0b5757af20bad9 | |
| parent | 95121d98e6da12599246d8e25c3f300e422a06fb (diff) | |
| download | busybox-w32-a84db18fc71d09e801df0ebca048d82e90b32c6a.tar.gz busybox-w32-a84db18fc71d09e801df0ebca048d82e90b32c6a.tar.bz2 busybox-w32-a84db18fc71d09e801df0ebca048d82e90b32c6a.zip | |
tar,unzip: postpone creation of symlinks with "suspicious" targets
This mostly reverts commit bc9bbeb2b81001e8731cd2ae501c8fccc8d87cc7
"libarchive: do not extract unsafe symlinks unless $EXTRACT_UNSAFE_SYMLINKS=1"
Users report that it is somewhat too restrictive. See
https://bugs.busybox.net/show_bug.cgi?id=8411
In particular, this interferes with unpacking of busybox-based
filesystems with links like "sbin/applet" -> "../bin/busybox".
The change is made smaller by deleting ARCHIVE_EXTRACT_QUIET flag -
it is unused since 2010, and removing conditionals on it
allows commonalizing some error message codes.
function old new delta
create_or_remember_symlink - 94 +94
create_symlinks_from_list - 64 +64
tar_main 1002 1006 +4
unzip_main 2732 2724 -8
data_extract_all 984 891 -93
unsafe_symlink_target 147 - -147
------------------------------------------------------------------------------
(add/remove: 2/1 grow/shrink: 1/2 up/down: 162/-248) Total: -86 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | archival/libarchive/data_extract_all.c | 28 | ||||
| -rw-r--r-- | archival/libarchive/unsafe_symlink_target.c | 59 | ||||
| -rw-r--r-- | archival/tar.c | 2 | ||||
| -rw-r--r-- | archival/unzip.c | 25 | ||||
| -rw-r--r-- | include/bb_archive.h | 23 | ||||
| -rwxr-xr-x | testsuite/tar.tests | 10 |
6 files changed, 68 insertions, 79 deletions
diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c index d3a6df5e8..8fa69ffaf 100644 --- a/archival/libarchive/data_extract_all.c +++ b/archival/libarchive/data_extract_all.c | |||
| @@ -107,9 +107,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
| 107 | } | 107 | } |
| 108 | } | 108 | } |
| 109 | else if (existing_sb.st_mtime >= file_header->mtime) { | 109 | else if (existing_sb.st_mtime >= file_header->mtime) { |
| 110 | if (!(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) | 110 | if (!S_ISDIR(file_header->mode)) { |
| 111 | && !S_ISDIR(file_header->mode) | ||
| 112 | ) { | ||
| 113 | bb_error_msg("%s not created: newer or " | 111 | bb_error_msg("%s not created: newer or " |
| 114 | "same age file exists", dst_name); | 112 | "same age file exists", dst_name); |
| 115 | } | 113 | } |
| @@ -125,7 +123,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
| 125 | /* Handle hard links separately */ | 123 | /* Handle hard links separately */ |
| 126 | if (hard_link) { | 124 | if (hard_link) { |
| 127 | res = link(hard_link, dst_name); | 125 | res = link(hard_link, dst_name); |
| 128 | if (res != 0 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) { | 126 | if (res != 0) { |
| 129 | /* shared message */ | 127 | /* shared message */ |
| 130 | bb_perror_msg("can't create %slink '%s' to '%s'", | 128 | bb_perror_msg("can't create %slink '%s' to '%s'", |
| 131 | "hard", dst_name, hard_link | 129 | "hard", dst_name, hard_link |
| @@ -165,10 +163,9 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
| 165 | } | 163 | } |
| 166 | case S_IFDIR: | 164 | case S_IFDIR: |
| 167 | res = mkdir(dst_name, file_header->mode); | 165 | res = mkdir(dst_name, file_header->mode); |
| 168 | if ((res == -1) | 166 | if ((res != 0) |
| 169 | && (errno != EISDIR) /* btw, Linux doesn't return this */ | 167 | && (errno != EISDIR) /* btw, Linux doesn't return this */ |
| 170 | && (errno != EEXIST) | 168 | && (errno != EEXIST) |
| 171 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) | ||
| 172 | ) { | 169 | ) { |
| 173 | bb_perror_msg("can't make dir %s", dst_name); | 170 | bb_perror_msg("can't make dir %s", dst_name); |
| 174 | } | 171 | } |
| @@ -198,27 +195,16 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
| 198 | * | 195 | * |
| 199 | * Untarring bug.tar would otherwise place evil.py in '/tmp'. | 196 | * Untarring bug.tar would otherwise place evil.py in '/tmp'. |
| 200 | */ | 197 | */ |
| 201 | if (!unsafe_symlink_target(file_header->link_target)) { | 198 | create_or_remember_symlink(&archive_handle->symlink_placeholders, |
| 202 | res = symlink(file_header->link_target, dst_name); | 199 | file_header->link_target, |
| 203 | if (res != 0 | 200 | dst_name); |
| 204 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) | ||
| 205 | ) { | ||
| 206 | /* shared message */ | ||
| 207 | bb_perror_msg("can't create %slink '%s' to '%s'", | ||
| 208 | "sym", | ||
| 209 | dst_name, file_header->link_target | ||
| 210 | ); | ||
| 211 | } | ||
| 212 | } | ||
| 213 | break; | 201 | break; |
| 214 | case S_IFSOCK: | 202 | case S_IFSOCK: |
| 215 | case S_IFBLK: | 203 | case S_IFBLK: |
| 216 | case S_IFCHR: | 204 | case S_IFCHR: |
| 217 | case S_IFIFO: | 205 | case S_IFIFO: |
| 218 | res = mknod(dst_name, file_header->mode, file_header->device); | 206 | res = mknod(dst_name, file_header->mode, file_header->device); |
| 219 | if ((res == -1) | 207 | if (res != 0) { |
| 220 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) | ||
| 221 | ) { | ||
| 222 | bb_perror_msg("can't create node %s", dst_name); | 208 | bb_perror_msg("can't create node %s", dst_name); |
| 223 | } | 209 | } |
| 224 | break; | 210 | break; |
diff --git a/archival/libarchive/unsafe_symlink_target.c b/archival/libarchive/unsafe_symlink_target.c index 441ba8b24..8dcafeaa1 100644 --- a/archival/libarchive/unsafe_symlink_target.c +++ b/archival/libarchive/unsafe_symlink_target.c | |||
| @@ -5,44 +5,37 @@ | |||
| 5 | #include "libbb.h" | 5 | #include "libbb.h" |
| 6 | #include "bb_archive.h" | 6 | #include "bb_archive.h" |
| 7 | 7 | ||
| 8 | int FAST_FUNC unsafe_symlink_target(const char *target) | 8 | void FAST_FUNC create_or_remember_symlink(llist_t **symlink_placeholders, |
| 9 | const char *target, | ||
| 10 | const char *linkname) | ||
| 9 | { | 11 | { |
| 10 | const char *dot; | 12 | if (target[0] == '/' || strstr(target, "..")) { |
| 11 | 13 | llist_add_to(symlink_placeholders, | |
| 12 | if (target[0] == '/') { | 14 | xasprintf("%s%c%s", linkname, '\0', target) |
| 13 | const char *var; | 15 | ); |
| 14 | unsafe: | 16 | return; |
| 15 | var = getenv("EXTRACT_UNSAFE_SYMLINKS"); | 17 | } |
| 16 | if (var) { | 18 | if (symlink(target, linkname) != 0) { |
| 17 | if (LONE_CHAR(var, '1')) | 19 | /* shared message */ |
| 18 | return 0; /* pretend it's safe */ | 20 | bb_perror_msg_and_die("can't create %slink '%s' to '%s'", |
| 19 | return 1; /* "UNSAFE!" */ | 21 | "sym", linkname, target |
| 20 | } | ||
| 21 | bb_error_msg("skipping unsafe symlink to '%s' in archive," | ||
| 22 | " set %s=1 to extract", | ||
| 23 | target, | ||
| 24 | "EXTRACT_UNSAFE_SYMLINKS" | ||
| 25 | ); | 22 | ); |
| 26 | /* Prevent further messages */ | ||
| 27 | setenv("EXTRACT_UNSAFE_SYMLINKS", "0", 0); | ||
| 28 | return 1; /* "UNSAFE!" */ | ||
| 29 | } | 23 | } |
| 24 | } | ||
| 30 | 25 | ||
| 31 | dot = target; | 26 | void FAST_FUNC create_symlinks_from_list(llist_t *list) |
| 32 | for (;;) { | 27 | { |
| 33 | dot = strchr(dot, '.'); | 28 | while (list) { |
| 34 | if (!dot) | 29 | char *target; |
| 35 | return 0; /* safe target */ | ||
| 36 | 30 | ||
| 37 | /* Is it a path component starting with ".."? */ | 31 | target = list->data + strlen(list->data) + 1; |
| 38 | if ((dot[1] == '.') | 32 | if (symlink(target, list->data)) { |
| 39 | && (dot == target || dot[-1] == '/') | 33 | /* shared message */ |
| 40 | /* Is it exactly ".."? */ | 34 | bb_error_msg_and_die("can't create %slink '%s' to '%s'", |
| 41 | && (dot[2] == '/' || dot[2] == '\0') | 35 | "sym", |
| 42 | ) { | 36 | list->data, target |
| 43 | goto unsafe; | 37 | ); |
| 44 | } | 38 | } |
| 45 | /* NB: it can even be trailing ".", should only add 1 */ | 39 | list = list->link; |
| 46 | dot += 1; | ||
| 47 | } | 40 | } |
| 48 | } | 41 | } |
diff --git a/archival/tar.c b/archival/tar.c index 9ed3821d5..415ebde0d 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
| @@ -1244,6 +1244,8 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
| 1244 | while (get_header_tar(tar_handle) == EXIT_SUCCESS) | 1244 | while (get_header_tar(tar_handle) == EXIT_SUCCESS) |
| 1245 | bb_got_signal = EXIT_SUCCESS; /* saw at least one header, good */ | 1245 | bb_got_signal = EXIT_SUCCESS; /* saw at least one header, good */ |
| 1246 | 1246 | ||
| 1247 | create_symlinks_from_list(tar_handle->symlink_placeholders); | ||
| 1248 | |||
| 1247 | /* Check that every file that should have been extracted was */ | 1249 | /* Check that every file that should have been extracted was */ |
| 1248 | while (tar_handle->accept) { | 1250 | while (tar_handle->accept) { |
| 1249 | if (!find_list_entry(tar_handle->reject, tar_handle->accept->data) | 1251 | if (!find_list_entry(tar_handle->reject, tar_handle->accept->data) |
diff --git a/archival/unzip.c b/archival/unzip.c index da4b2a544..0d00d8dc9 100644 --- a/archival/unzip.c +++ b/archival/unzip.c | |||
| @@ -345,7 +345,9 @@ static void unzip_create_leading_dirs(const char *fn) | |||
| 345 | } | 345 | } |
| 346 | 346 | ||
| 347 | #if ENABLE_FEATURE_UNZIP_CDF | 347 | #if ENABLE_FEATURE_UNZIP_CDF |
| 348 | static void unzip_extract_symlink(zip_header_t *zip, const char *dst_fn) | 348 | static void unzip_extract_symlink(llist_t **symlink_placeholders, |
| 349 | zip_header_t *zip, | ||
| 350 | const char *dst_fn) | ||
| 349 | { | 351 | { |
| 350 | char *target; | 352 | char *target; |
| 351 | 353 | ||
| @@ -370,15 +372,9 @@ static void unzip_extract_symlink(zip_header_t *zip, const char *dst_fn) | |||
| 370 | target[xstate.mem_output_size] = '\0'; | 372 | target[xstate.mem_output_size] = '\0'; |
| 371 | #endif | 373 | #endif |
| 372 | } | 374 | } |
| 373 | if (!unsafe_symlink_target(target)) { | 375 | create_or_remember_symlink(symlink_placeholders, |
| 374 | //TODO: libbb candidate | 376 | target, |
| 375 | if (symlink(target, dst_fn)) { | 377 | dst_fn); |
| 376 | /* shared message */ | ||
| 377 | bb_perror_msg_and_die("can't create %slink '%s' to '%s'", | ||
| 378 | "sym", dst_fn, target | ||
| 379 | ); | ||
| 380 | } | ||
| 381 | } | ||
| 382 | free(target); | 378 | free(target); |
| 383 | } | 379 | } |
| 384 | #endif | 380 | #endif |
| @@ -490,6 +486,9 @@ int unzip_main(int argc, char **argv) | |||
| 490 | llist_t *zaccept = NULL; | 486 | llist_t *zaccept = NULL; |
| 491 | llist_t *zreject = NULL; | 487 | llist_t *zreject = NULL; |
| 492 | char *base_dir = NULL; | 488 | char *base_dir = NULL; |
| 489 | #if ENABLE_FEATURE_UNZIP_CDF | ||
| 490 | llist_t *symlink_placeholders = NULL; | ||
| 491 | #endif | ||
| 493 | int i; | 492 | int i; |
| 494 | char key_buf[80]; /* must match size used by my_fgets80 */ | 493 | char key_buf[80]; /* must match size used by my_fgets80 */ |
| 495 | 494 | ||
| @@ -954,7 +953,7 @@ int unzip_main(int argc, char **argv) | |||
| 954 | #if ENABLE_FEATURE_UNZIP_CDF | 953 | #if ENABLE_FEATURE_UNZIP_CDF |
| 955 | if (S_ISLNK(file_mode)) { | 954 | if (S_ISLNK(file_mode)) { |
| 956 | if (dst_fd != STDOUT_FILENO) /* not -p? */ | 955 | if (dst_fd != STDOUT_FILENO) /* not -p? */ |
| 957 | unzip_extract_symlink(&zip, dst_fn); | 956 | unzip_extract_symlink(&symlink_placeholders, &zip, dst_fn); |
| 958 | } else | 957 | } else |
| 959 | #endif | 958 | #endif |
| 960 | { | 959 | { |
| @@ -990,6 +989,10 @@ int unzip_main(int argc, char **argv) | |||
| 990 | total_entries++; | 989 | total_entries++; |
| 991 | } | 990 | } |
| 992 | 991 | ||
| 992 | #if ENABLE_FEATURE_UNZIP_CDF | ||
| 993 | create_symlinks_from_list(symlink_placeholders); | ||
| 994 | #endif | ||
| 995 | |||
| 993 | if ((opts & OPT_l) && quiet <= 1) { | 996 | if ((opts & OPT_l) && quiet <= 1) { |
| 994 | if (!verbose) { | 997 | if (!verbose) { |
| 995 | // " Length Date Time Name\n" | 998 | // " Length Date Time Name\n" |
diff --git a/include/bb_archive.h b/include/bb_archive.h index 8ed20d70e..a5c61e95b 100644 --- a/include/bb_archive.h +++ b/include/bb_archive.h | |||
| @@ -64,6 +64,9 @@ typedef struct archive_handle_t { | |||
| 64 | /* Currently processed file's header */ | 64 | /* Currently processed file's header */ |
| 65 | file_header_t *file_header; | 65 | file_header_t *file_header; |
| 66 | 66 | ||
| 67 | /* List of symlink placeholders */ | ||
| 68 | llist_t *symlink_placeholders; | ||
| 69 | |||
| 67 | /* Process the header component, e.g. tar -t */ | 70 | /* Process the header component, e.g. tar -t */ |
| 68 | void FAST_FUNC (*action_header)(const file_header_t *); | 71 | void FAST_FUNC (*action_header)(const file_header_t *); |
| 69 | 72 | ||
| @@ -119,15 +122,14 @@ typedef struct archive_handle_t { | |||
| 119 | #define ARCHIVE_RESTORE_DATE (1 << 0) | 122 | #define ARCHIVE_RESTORE_DATE (1 << 0) |
| 120 | #define ARCHIVE_CREATE_LEADING_DIRS (1 << 1) | 123 | #define ARCHIVE_CREATE_LEADING_DIRS (1 << 1) |
| 121 | #define ARCHIVE_UNLINK_OLD (1 << 2) | 124 | #define ARCHIVE_UNLINK_OLD (1 << 2) |
| 122 | #define ARCHIVE_EXTRACT_QUIET (1 << 3) | 125 | #define ARCHIVE_EXTRACT_NEWER (1 << 3) |
| 123 | #define ARCHIVE_EXTRACT_NEWER (1 << 4) | 126 | #define ARCHIVE_DONT_RESTORE_OWNER (1 << 4) |
| 124 | #define ARCHIVE_DONT_RESTORE_OWNER (1 << 5) | 127 | #define ARCHIVE_DONT_RESTORE_PERM (1 << 5) |
| 125 | #define ARCHIVE_DONT_RESTORE_PERM (1 << 6) | 128 | #define ARCHIVE_NUMERIC_OWNER (1 << 6) |
| 126 | #define ARCHIVE_NUMERIC_OWNER (1 << 7) | 129 | #define ARCHIVE_O_TRUNC (1 << 7) |
| 127 | #define ARCHIVE_O_TRUNC (1 << 8) | 130 | #define ARCHIVE_REMEMBER_NAMES (1 << 8) |
| 128 | #define ARCHIVE_REMEMBER_NAMES (1 << 9) | ||
| 129 | #if ENABLE_RPM | 131 | #if ENABLE_RPM |
| 130 | #define ARCHIVE_REPLACE_VIA_RENAME (1 << 10) | 132 | #define ARCHIVE_REPLACE_VIA_RENAME (1 << 9) |
| 131 | #endif | 133 | #endif |
| 132 | 134 | ||
| 133 | 135 | ||
| @@ -197,7 +199,10 @@ void seek_by_jump(int fd, off_t amount) FAST_FUNC; | |||
| 197 | void seek_by_read(int fd, off_t amount) FAST_FUNC; | 199 | void seek_by_read(int fd, off_t amount) FAST_FUNC; |
| 198 | 200 | ||
| 199 | const char *strip_unsafe_prefix(const char *str) FAST_FUNC; | 201 | const char *strip_unsafe_prefix(const char *str) FAST_FUNC; |
| 200 | int unsafe_symlink_target(const char *target) FAST_FUNC; | 202 | void create_or_remember_symlink(llist_t **symlink_placeholders, |
| 203 | const char *target, | ||
| 204 | const char *linkname) FAST_FUNC; | ||
| 205 | void create_symlinks_from_list(llist_t *list) FAST_FUNC; | ||
| 201 | 206 | ||
| 202 | void data_align(archive_handle_t *archive_handle, unsigned boundary) FAST_FUNC; | 207 | void data_align(archive_handle_t *archive_handle, unsigned boundary) FAST_FUNC; |
| 203 | const llist_t *find_list_entry(const llist_t *list, const char *filename) FAST_FUNC; | 208 | const llist_t *find_list_entry(const llist_t *list, const char *filename) FAST_FUNC; |
diff --git a/testsuite/tar.tests b/testsuite/tar.tests index b7cd74ca5..1675b07b1 100755 --- a/testsuite/tar.tests +++ b/testsuite/tar.tests | |||
| @@ -279,7 +279,7 @@ optional UUDECODE FEATURE_TAR_AUTODETECT FEATURE_SEAMLESS_BZ2 | |||
| 279 | testing "tar does not extract into symlinks" "\ | 279 | testing "tar does not extract into symlinks" "\ |
| 280 | >>/tmp/passwd && uudecode -o input && tar xf input 2>&1 && rm passwd; cat /tmp/passwd; echo \$? | 280 | >>/tmp/passwd && uudecode -o input && tar xf input 2>&1 && rm passwd; cat /tmp/passwd; echo \$? |
| 281 | " "\ | 281 | " "\ |
| 282 | tar: skipping unsafe symlink to '/tmp/passwd' in archive, set EXTRACT_UNSAFE_SYMLINKS=1 to extract | 282 | tar: can't create symlink 'passwd' to '/tmp/passwd' |
| 283 | 0 | 283 | 0 |
| 284 | " \ | 284 | " \ |
| 285 | "" "\ | 285 | "" "\ |
| @@ -299,7 +299,7 @@ optional UUDECODE FEATURE_TAR_AUTODETECT FEATURE_SEAMLESS_BZ2 | |||
| 299 | testing "tar -k does not extract into symlinks" "\ | 299 | testing "tar -k does not extract into symlinks" "\ |
| 300 | >>/tmp/passwd && uudecode -o input && tar xf input -k 2>&1 && rm passwd; cat /tmp/passwd; echo \$? | 300 | >>/tmp/passwd && uudecode -o input && tar xf input -k 2>&1 && rm passwd; cat /tmp/passwd; echo \$? |
| 301 | " "\ | 301 | " "\ |
| 302 | tar: skipping unsafe symlink to '/tmp/passwd' in archive, set EXTRACT_UNSAFE_SYMLINKS=1 to extract | 302 | tar: can't create symlink 'passwd' to '/tmp/passwd' |
| 303 | 0 | 303 | 0 |
| 304 | " \ | 304 | " \ |
| 305 | "" "\ | 305 | "" "\ |
| @@ -324,11 +324,11 @@ rm -rf etc usr | |||
| 324 | ' "\ | 324 | ' "\ |
| 325 | etc/ssl/certs/3b2716e5.0 | 325 | etc/ssl/certs/3b2716e5.0 |
| 326 | etc/ssl/certs/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem | 326 | etc/ssl/certs/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem |
| 327 | tar: skipping unsafe symlink to '/usr/share/ca-certificates/mozilla/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.crt' in archive, set EXTRACT_UNSAFE_SYMLINKS=1 to extract | ||
| 328 | etc/ssl/certs/f80cc7f6.0 | 327 | etc/ssl/certs/f80cc7f6.0 |
| 329 | usr/share/ca-certificates/mozilla/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.crt | 328 | usr/share/ca-certificates/mozilla/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.crt |
| 330 | 0 | 329 | 0 |
| 331 | etc/ssl/certs/3b2716e5.0 -> EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem | 330 | etc/ssl/certs/3b2716e5.0 -> EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem |
| 331 | etc/ssl/certs/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem -> /usr/share/ca-certificates/mozilla/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.crt | ||
| 332 | etc/ssl/certs/f80cc7f6.0 -> EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem | 332 | etc/ssl/certs/f80cc7f6.0 -> EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem |
| 333 | " \ | 333 | " \ |
| 334 | "" "" | 334 | "" "" |
| @@ -346,9 +346,9 @@ ls symlink/bb_test_evilfile | |||
| 346 | ' "\ | 346 | ' "\ |
| 347 | anything.txt | 347 | anything.txt |
| 348 | symlink | 348 | symlink |
| 349 | tar: skipping unsafe symlink to '/tmp' in archive, set EXTRACT_UNSAFE_SYMLINKS=1 to extract | ||
| 350 | symlink/bb_test_evilfile | 349 | symlink/bb_test_evilfile |
| 351 | 0 | 350 | tar: can't create symlink 'symlink' to '/tmp' |
| 351 | 1 | ||
| 352 | ls: /tmp/bb_test_evilfile: No such file or directory | 352 | ls: /tmp/bb_test_evilfile: No such file or directory |
| 353 | ls: bb_test_evilfile: No such file or directory | 353 | ls: bb_test_evilfile: No such file or directory |
| 354 | symlink/bb_test_evilfile | 354 | symlink/bb_test_evilfile |
