diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-03-01 17:21:07 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-03-01 17:21:07 +0100 |
commit | 5e29e263888284b2451debd9e5cb138b48fd293a (patch) | |
tree | 9971260e354b6385f53bfe57408bf4bff184a78f | |
parent | 7d65abea092e917bc2320cbf1d5a2dccb2a8288f (diff) | |
download | busybox-w32-5e29e263888284b2451debd9e5cb138b48fd293a.tar.gz busybox-w32-5e29e263888284b2451debd9e5cb138b48fd293a.tar.bz2 busybox-w32-5e29e263888284b2451debd9e5cb138b48fd293a.zip |
tar: on extract, everything up to and including last ".." is stripped
function old new delta
get_header_tar 1493 1545 +52
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/libarchive/get_header_tar.c | 27 | ||||
-rw-r--r-- | include/archive.h | 2 | ||||
-rwxr-xr-x | testsuite/tar.tests | 17 |
3 files changed, 41 insertions, 5 deletions
diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index 2e0332792..6a1532c86 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c | |||
@@ -422,11 +422,28 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
422 | p_linkname = NULL; | 422 | p_linkname = NULL; |
423 | } | 423 | } |
424 | #endif | 424 | #endif |
425 | if (strncmp(file_header->name, "/../"+1, 3) == 0 | 425 | |
426 | || strstr(file_header->name, "/../") | 426 | /* Everything up to and including last ".." component is stripped */ |
427 | ) { | 427 | cp = file_header->name; |
428 | bb_error_msg_and_die("name with '..' encountered: '%s'", | 428 | while (1) { |
429 | file_header->name); | 429 | char *cp2; |
430 | if (strncmp(cp, "/../"+1, 3) == 0) { | ||
431 | cp += 3; | ||
432 | continue; | ||
433 | } | ||
434 | cp2 = strstr(cp, "/../"); | ||
435 | if (cp2) { | ||
436 | cp = cp2 + 4; | ||
437 | continue; | ||
438 | } | ||
439 | break; | ||
440 | } | ||
441 | if (cp != file_header->name) { | ||
442 | if (!(archive_handle->ah_flags & ARCHIVE_TAR__TRUNC_WARNED)) { | ||
443 | archive_handle->ah_flags |= ARCHIVE_TAR__TRUNC_WARNED; | ||
444 | bb_error_msg("removing leading '%.*s'", (int)(cp - file_header->name), file_header->name); | ||
445 | } | ||
446 | overlapping_strcpy(file_header->name, cp); | ||
430 | } | 447 | } |
431 | 448 | ||
432 | /* Strip trailing '/' in directories */ | 449 | /* Strip trailing '/' in directories */ |
diff --git a/include/archive.h b/include/archive.h index 49c478728..9fc77e542 100644 --- a/include/archive.h +++ b/include/archive.h | |||
@@ -118,6 +118,8 @@ typedef struct archive_handle_t { | |||
118 | #define ARCHIVE_DONT_RESTORE_PERM (1 << 6) | 118 | #define ARCHIVE_DONT_RESTORE_PERM (1 << 6) |
119 | #define ARCHIVE_NUMERIC_OWNER (1 << 7) | 119 | #define ARCHIVE_NUMERIC_OWNER (1 << 7) |
120 | #define ARCHIVE_O_TRUNC (1 << 8) | 120 | #define ARCHIVE_O_TRUNC (1 << 8) |
121 | /* Archiver specific. */ | ||
122 | #define ARCHIVE_TAR__TRUNC_WARNED (1 << 9) | ||
121 | 123 | ||
122 | 124 | ||
123 | /* POSIX tar Header Block, from POSIX 1003.1-1990 */ | 125 | /* POSIX tar Header Block, from POSIX 1003.1-1990 */ |
diff --git a/testsuite/tar.tests b/testsuite/tar.tests index 472064f7f..d41d10d57 100755 --- a/testsuite/tar.tests +++ b/testsuite/tar.tests | |||
@@ -168,6 +168,23 @@ Ok | |||
168 | " \ | 168 | " \ |
169 | "" "" | 169 | "" "" |
170 | 170 | ||
171 | # On extract, everything up to and including last ".." component is stripped | ||
172 | testing "tar strips /../ on extract" "\ | ||
173 | rm -rf input_* test.tar 2>/dev/null | ||
174 | mkdir input_dir | ||
175 | echo Ok >input_dir/file | ||
176 | tar cf test.tar ./../tar.tempdir/input_dir/../input_dir 2>&1 | ||
177 | rm -rf input_* 2>/dev/null | ||
178 | tar -vxf test.tar 2>&1 | ||
179 | cat input_dir/file 2>&1 | ||
180 | " "\ | ||
181 | tar: removing leading './../tar.tempdir/input_dir/../' | ||
182 | input_dir/ | ||
183 | input_dir/file | ||
184 | Ok | ||
185 | " \ | ||
186 | "" "" | ||
187 | |||
171 | 188 | ||
172 | cd .. && rm -rf tar.tempdir || exit 1 | 189 | cd .. && rm -rf tar.tempdir || exit 1 |
173 | 190 | ||