diff options
author | Ron Yorston <rmy@pobox.com> | 2012-03-22 13:56:39 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2012-03-22 13:56:39 +0000 |
commit | 811c449748d5bd0505f8510e5582892f94ac0cda (patch) | |
tree | 2640249cb2a9605c7cd59467b9861b205e9bcc8a /archival | |
parent | c0d4367d6b581eb5989c02815880cf0fa2851ae8 (diff) | |
parent | 19311bfa7b8e8c6effa9c375de9b0eb4338bee12 (diff) | |
download | busybox-w32-811c449748d5bd0505f8510e5582892f94ac0cda.tar.gz busybox-w32-811c449748d5bd0505f8510e5582892f94ac0cda.tar.bz2 busybox-w32-811c449748d5bd0505f8510e5582892f94ac0cda.zip |
Merge commit '19311bfa7b8e8c6effa9c375de9b0eb4338bee12' into merge
Conflicts:
coreutils/ls.c
shell/ash.c
Diffstat (limited to 'archival')
-rw-r--r-- | archival/libarchive/data_extract_to_command.c | 8 | ||||
-rw-r--r-- | archival/libarchive/get_header_tar.c | 38 | ||||
-rw-r--r-- | archival/tar.c | 14 |
3 files changed, 41 insertions, 19 deletions
diff --git a/archival/libarchive/data_extract_to_command.c b/archival/libarchive/data_extract_to_command.c index 2bbab7641..0e977049d 100644 --- a/archival/libarchive/data_extract_to_command.c +++ b/archival/libarchive/data_extract_to_command.c | |||
@@ -99,8 +99,12 @@ void FAST_FUNC data_extract_to_command(archive_handle_t *archive_handle) | |||
99 | close(p[1]); | 99 | close(p[1]); |
100 | xdup2(p[0], STDIN_FILENO); | 100 | xdup2(p[0], STDIN_FILENO); |
101 | signal(SIGPIPE, SIG_DFL); | 101 | signal(SIGPIPE, SIG_DFL); |
102 | execl(DEFAULT_SHELL, DEFAULT_SHELL_SHORT_NAME, "-c", archive_handle->tar__to_command, NULL); | 102 | execl(archive_handle->tar__to_command_shell, |
103 | bb_perror_msg_and_die("can't execute '%s'", DEFAULT_SHELL); | 103 | archive_handle->tar__to_command_shell, |
104 | "-c", | ||
105 | archive_handle->tar__to_command, | ||
106 | NULL); | ||
107 | bb_perror_msg_and_die("can't execute '%s'", archive_handle->tar__to_command_shell); | ||
104 | } | 108 | } |
105 | close(p[0]); | 109 | close(p[0]); |
106 | /* Our caller is expected to do signal(SIGPIPE, SIG_IGN) | 110 | /* Our caller is expected to do signal(SIGPIPE, SIG_IGN) |
diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index 2e0332792..f73cd338e 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c | |||
@@ -18,6 +18,35 @@ typedef uint32_t aliased_uint32_t FIX_ALIASING; | |||
18 | typedef off_t aliased_off_t FIX_ALIASING; | 18 | typedef off_t aliased_off_t FIX_ALIASING; |
19 | 19 | ||
20 | 20 | ||
21 | const char* FAST_FUNC strip_unsafe_prefix(const char *str) | ||
22 | { | ||
23 | const char *cp = str; | ||
24 | while (1) { | ||
25 | char *cp2; | ||
26 | if (*cp == '/') { | ||
27 | cp++; | ||
28 | continue; | ||
29 | } | ||
30 | if (strncmp(cp, "/../"+1, 3) == 0) { | ||
31 | cp += 3; | ||
32 | continue; | ||
33 | } | ||
34 | cp2 = strstr(cp, "/../"); | ||
35 | if (!cp2) | ||
36 | break; | ||
37 | cp = cp2 + 4; | ||
38 | } | ||
39 | if (cp != str) { | ||
40 | static smallint warned = 0; | ||
41 | if (!warned) { | ||
42 | warned = 1; | ||
43 | bb_error_msg("removing leading '%.*s' from member names", | ||
44 | (int)(cp - str), str); | ||
45 | } | ||
46 | } | ||
47 | return cp; | ||
48 | } | ||
49 | |||
21 | /* NB: _DESTROYS_ str[len] character! */ | 50 | /* NB: _DESTROYS_ str[len] character! */ |
22 | static unsigned long long getOctal(char *str, int len) | 51 | static unsigned long long getOctal(char *str, int len) |
23 | { | 52 | { |
@@ -422,12 +451,9 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
422 | p_linkname = NULL; | 451 | p_linkname = NULL; |
423 | } | 452 | } |
424 | #endif | 453 | #endif |
425 | if (strncmp(file_header->name, "/../"+1, 3) == 0 | 454 | |
426 | || strstr(file_header->name, "/../") | 455 | /* Everything up to and including last ".." component is stripped */ |
427 | ) { | 456 | overlapping_strcpy(file_header->name, strip_unsafe_prefix(file_header->name)); |
428 | bb_error_msg_and_die("name with '..' encountered: '%s'", | ||
429 | file_header->name); | ||
430 | } | ||
431 | 457 | ||
432 | /* Strip trailing '/' in directories */ | 458 | /* Strip trailing '/' in directories */ |
433 | /* Must be done after mode is set as '/' is used to check if it's a directory */ | 459 | /* Must be done after mode is set as '/' is used to check if it's a directory */ |
diff --git a/archival/tar.c b/archival/tar.c index 74d6fca91..52f3c364c 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -397,17 +397,8 @@ static int FAST_FUNC writeFileToTarball(const char *fileName, struct stat *statb | |||
397 | 397 | ||
398 | DBG("writeFileToTarball('%s')", fileName); | 398 | DBG("writeFileToTarball('%s')", fileName); |
399 | 399 | ||
400 | /* Strip leading '/' (must be before memorizing hardlink's name) */ | 400 | /* Strip leading '/' and such (must be before memorizing hardlink's name) */ |
401 | header_name = fileName; | 401 | header_name = strip_unsafe_prefix(fileName); |
402 | while (header_name[0] == '/') { | ||
403 | static smallint warned; | ||
404 | |||
405 | if (!warned) { | ||
406 | bb_error_msg("removing leading '/' from member names"); | ||
407 | warned = 1; | ||
408 | } | ||
409 | header_name++; | ||
410 | } | ||
411 | 402 | ||
412 | if (header_name[0] == '\0') | 403 | if (header_name[0] == '\0') |
413 | return TRUE; | 404 | return TRUE; |
@@ -981,6 +972,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
981 | putenv((char*)"TAR_FILETYPE=f"); | 972 | putenv((char*)"TAR_FILETYPE=f"); |
982 | signal(SIGPIPE, SIG_IGN); | 973 | signal(SIGPIPE, SIG_IGN); |
983 | tar_handle->action_data = data_extract_to_command; | 974 | tar_handle->action_data = data_extract_to_command; |
975 | IF_FEATURE_TAR_TO_COMMAND(tar_handle->tar__to_command_shell = xstrdup(get_shell_name());) | ||
984 | } | 976 | } |
985 | 977 | ||
986 | if (opt & OPT_KEEP_OLD) | 978 | if (opt & OPT_KEEP_OLD) |