diff options
Diffstat (limited to 'archival')
-rw-r--r-- | archival/dpkg.c | 11 | ||||
-rw-r--r-- | archival/dpkg_deb.c | 6 | ||||
-rw-r--r-- | archival/gzip.c | 61 | ||||
-rw-r--r-- | archival/libarchive/Kbuild.src | 6 | ||||
-rw-r--r-- | archival/libarchive/filter_accept_list_reassign.c | 10 | ||||
-rw-r--r-- | archival/libarchive/get_header_cpio.c | 2 | ||||
-rw-r--r-- | archival/libarchive/get_header_tar.c | 36 | ||||
-rw-r--r-- | archival/libarchive/get_header_tar_xz.c | 21 | ||||
-rw-r--r-- | archival/libarchive/unpack_ar_archive.c | 2 | ||||
-rw-r--r-- | archival/libarchive/unsafe_prefix.c | 36 | ||||
-rw-r--r-- | archival/unzip.c | 35 |
11 files changed, 167 insertions, 59 deletions
diff --git a/archival/dpkg.c b/archival/dpkg.c index 2893cfc2d..151f0ca43 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c | |||
@@ -1472,12 +1472,16 @@ static void init_archive_deb_control(archive_handle_t *ar_handle) | |||
1472 | tar_handle->src_fd = ar_handle->src_fd; | 1472 | tar_handle->src_fd = ar_handle->src_fd; |
1473 | 1473 | ||
1474 | /* We don't care about data.tar.* or debian-binary, just control.tar.* */ | 1474 | /* We don't care about data.tar.* or debian-binary, just control.tar.* */ |
1475 | llist_add_to(&(ar_handle->accept), (char*)"control.tar"); | ||
1475 | #if ENABLE_FEATURE_SEAMLESS_GZ | 1476 | #if ENABLE_FEATURE_SEAMLESS_GZ |
1476 | llist_add_to(&(ar_handle->accept), (char*)"control.tar.gz"); | 1477 | llist_add_to(&(ar_handle->accept), (char*)"control.tar.gz"); |
1477 | #endif | 1478 | #endif |
1478 | #if ENABLE_FEATURE_SEAMLESS_BZ2 | 1479 | #if ENABLE_FEATURE_SEAMLESS_BZ2 |
1479 | llist_add_to(&(ar_handle->accept), (char*)"control.tar.bz2"); | 1480 | llist_add_to(&(ar_handle->accept), (char*)"control.tar.bz2"); |
1480 | #endif | 1481 | #endif |
1482 | #if ENABLE_FEATURE_SEAMLESS_XZ | ||
1483 | llist_add_to(&(ar_handle->accept), (char*)"control.tar.xz"); | ||
1484 | #endif | ||
1481 | 1485 | ||
1482 | /* Assign the tar handle as a subarchive of the ar handle */ | 1486 | /* Assign the tar handle as a subarchive of the ar handle */ |
1483 | ar_handle->dpkg__sub_archive = tar_handle; | 1487 | ar_handle->dpkg__sub_archive = tar_handle; |
@@ -1492,12 +1496,19 @@ static void init_archive_deb_data(archive_handle_t *ar_handle) | |||
1492 | tar_handle->src_fd = ar_handle->src_fd; | 1496 | tar_handle->src_fd = ar_handle->src_fd; |
1493 | 1497 | ||
1494 | /* We don't care about control.tar.* or debian-binary, just data.tar.* */ | 1498 | /* We don't care about control.tar.* or debian-binary, just data.tar.* */ |
1499 | llist_add_to(&(ar_handle->accept), (char*)"data.tar"); | ||
1495 | #if ENABLE_FEATURE_SEAMLESS_GZ | 1500 | #if ENABLE_FEATURE_SEAMLESS_GZ |
1496 | llist_add_to(&(ar_handle->accept), (char*)"data.tar.gz"); | 1501 | llist_add_to(&(ar_handle->accept), (char*)"data.tar.gz"); |
1497 | #endif | 1502 | #endif |
1498 | #if ENABLE_FEATURE_SEAMLESS_BZ2 | 1503 | #if ENABLE_FEATURE_SEAMLESS_BZ2 |
1499 | llist_add_to(&(ar_handle->accept), (char*)"data.tar.bz2"); | 1504 | llist_add_to(&(ar_handle->accept), (char*)"data.tar.bz2"); |
1500 | #endif | 1505 | #endif |
1506 | #if ENABLE_FEATURE_SEAMLESS_LZMA | ||
1507 | llist_add_to(&(ar_handle->accept), (char*)"data.tar.lzma"); | ||
1508 | #endif | ||
1509 | #if ENABLE_FEATURE_SEAMLESS_XZ | ||
1510 | llist_add_to(&(ar_handle->accept), (char*)"data.tar.xz"); | ||
1511 | #endif | ||
1501 | 1512 | ||
1502 | /* Assign the tar handle as a subarchive of the ar handle */ | 1513 | /* Assign the tar handle as a subarchive of the ar handle */ |
1503 | ar_handle->dpkg__sub_archive = tar_handle; | 1514 | ar_handle->dpkg__sub_archive = tar_handle; |
diff --git a/archival/dpkg_deb.c b/archival/dpkg_deb.c index 13f9db991..0285273fe 100644 --- a/archival/dpkg_deb.c +++ b/archival/dpkg_deb.c | |||
@@ -70,6 +70,8 @@ int dpkg_deb_main(int argc, char **argv) | |||
70 | ar_archive->dpkg__sub_archive = tar_archive; | 70 | ar_archive->dpkg__sub_archive = tar_archive; |
71 | ar_archive->filter = filter_accept_list_reassign; | 71 | ar_archive->filter = filter_accept_list_reassign; |
72 | 72 | ||
73 | llist_add_to(&ar_archive->accept, (char*)"data.tar"); | ||
74 | llist_add_to(&control_tar_llist, (char*)"control.tar"); | ||
73 | #if ENABLE_FEATURE_SEAMLESS_GZ | 75 | #if ENABLE_FEATURE_SEAMLESS_GZ |
74 | llist_add_to(&ar_archive->accept, (char*)"data.tar.gz"); | 76 | llist_add_to(&ar_archive->accept, (char*)"data.tar.gz"); |
75 | llist_add_to(&control_tar_llist, (char*)"control.tar.gz"); | 77 | llist_add_to(&control_tar_llist, (char*)"control.tar.gz"); |
@@ -82,6 +84,10 @@ int dpkg_deb_main(int argc, char **argv) | |||
82 | llist_add_to(&ar_archive->accept, (char*)"data.tar.lzma"); | 84 | llist_add_to(&ar_archive->accept, (char*)"data.tar.lzma"); |
83 | llist_add_to(&control_tar_llist, (char*)"control.tar.lzma"); | 85 | llist_add_to(&control_tar_llist, (char*)"control.tar.lzma"); |
84 | #endif | 86 | #endif |
87 | #if ENABLE_FEATURE_SEAMLESS_XZ | ||
88 | llist_add_to(&ar_archive->accept, (char*)"data.tar.xz"); | ||
89 | llist_add_to(&control_tar_llist, (char*)"control.tar.xz"); | ||
90 | #endif | ||
85 | 91 | ||
86 | opt_complementary = "c--efXx:e--cfXx:f--ceXx:X--cefx:x--cefX"; | 92 | opt_complementary = "c--efXx:e--cfXx:f--ceXx:X--cefx:x--cefX"; |
87 | opt = getopt32(argv, "cefXx"); | 93 | opt = getopt32(argv, "cefXx"); |
diff --git a/archival/gzip.c b/archival/gzip.c index a93d2175a..bc1f9c60b 100644 --- a/archival/gzip.c +++ b/archival/gzip.c | |||
@@ -417,19 +417,46 @@ static void flush_outbuf(void) | |||
417 | #define put_8bit(c) \ | 417 | #define put_8bit(c) \ |
418 | do { \ | 418 | do { \ |
419 | G1.outbuf[G1.outcnt++] = (c); \ | 419 | G1.outbuf[G1.outcnt++] = (c); \ |
420 | if (G1.outcnt == OUTBUFSIZ) flush_outbuf(); \ | 420 | if (G1.outcnt == OUTBUFSIZ) \ |
421 | flush_outbuf(); \ | ||
421 | } while (0) | 422 | } while (0) |
422 | 423 | ||
423 | /* Output a 16 bit value, lsb first */ | 424 | /* Output a 16 bit value, lsb first */ |
424 | static void put_16bit(ush w) | 425 | static void put_16bit(ush w) |
425 | { | 426 | { |
426 | if (G1.outcnt < OUTBUFSIZ - 2) { | 427 | /* GCC 4.2.1 won't optimize out redundant loads of G1.outcnt |
427 | G1.outbuf[G1.outcnt++] = w; | 428 | * (probably because of fear of aliasing with G1.outbuf[] |
428 | G1.outbuf[G1.outcnt++] = w >> 8; | 429 | * stores), do it explicitly: |
429 | } else { | 430 | */ |
430 | put_8bit(w); | 431 | unsigned outcnt = G1.outcnt; |
431 | put_8bit(w >> 8); | 432 | uch *dst = &G1.outbuf[outcnt]; |
433 | |||
434 | #if BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN | ||
435 | if (outcnt < OUTBUFSIZ-2) { | ||
436 | /* Common case */ | ||
437 | ush *dst16 = (void*) dst; | ||
438 | *dst16 = w; /* unalinged LSB 16-bit store */ | ||
439 | G1.outcnt = outcnt + 2; | ||
440 | return; | ||
432 | } | 441 | } |
442 | *dst = (uch)w; | ||
443 | w >>= 8; | ||
444 | #else | ||
445 | *dst = (uch)w; | ||
446 | w >>= 8; | ||
447 | if (outcnt < OUTBUFSIZ-2) { | ||
448 | /* Common case */ | ||
449 | dst[1] = w; | ||
450 | G1.outcnt = outcnt + 2; | ||
451 | return; | ||
452 | } | ||
453 | #endif | ||
454 | |||
455 | /* Slowpath: we will need to do flush_outbuf() */ | ||
456 | G1.outcnt = ++outcnt; | ||
457 | if (outcnt == OUTBUFSIZ) | ||
458 | flush_outbuf(); | ||
459 | put_8bit(w); | ||
433 | } | 460 | } |
434 | 461 | ||
435 | static void put_32bit(ulg n) | 462 | static void put_32bit(ulg n) |
@@ -2007,7 +2034,7 @@ static void ct_init(void) | |||
2007 | * IN assertions: the input and output buffers are cleared. | 2034 | * IN assertions: the input and output buffers are cleared. |
2008 | */ | 2035 | */ |
2009 | 2036 | ||
2010 | static void zip(ulg time_stamp) | 2037 | static void zip(void) |
2011 | { | 2038 | { |
2012 | ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */ | 2039 | ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */ |
2013 | 2040 | ||
@@ -2018,7 +2045,7 @@ static void zip(ulg time_stamp) | |||
2018 | /* compression method: 8 (DEFLATED) */ | 2045 | /* compression method: 8 (DEFLATED) */ |
2019 | /* general flags: 0 */ | 2046 | /* general flags: 0 */ |
2020 | put_32bit(0x00088b1f); | 2047 | put_32bit(0x00088b1f); |
2021 | put_32bit(time_stamp); | 2048 | put_32bit(0); /* Unix timestamp */ |
2022 | 2049 | ||
2023 | /* Write deflated file to zip file */ | 2050 | /* Write deflated file to zip file */ |
2024 | G1.crc = ~0; | 2051 | G1.crc = ~0; |
@@ -2044,8 +2071,6 @@ static void zip(ulg time_stamp) | |||
2044 | static | 2071 | static |
2045 | IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_state_t *xstate UNUSED_PARAM) | 2072 | IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_state_t *xstate UNUSED_PARAM) |
2046 | { | 2073 | { |
2047 | struct stat s; | ||
2048 | |||
2049 | /* Clear input and output buffers */ | 2074 | /* Clear input and output buffers */ |
2050 | G1.outcnt = 0; | 2075 | G1.outcnt = 0; |
2051 | #ifdef DEBUG | 2076 | #ifdef DEBUG |
@@ -2077,9 +2102,23 @@ IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_state_t *xstate UNUSED | |||
2077 | G2.bl_desc.max_length = MAX_BL_BITS; | 2102 | G2.bl_desc.max_length = MAX_BL_BITS; |
2078 | //G2.bl_desc.max_code = 0; | 2103 | //G2.bl_desc.max_code = 0; |
2079 | 2104 | ||
2105 | #if 0 | ||
2106 | /* Saving of timestamp is disabled. Why? | ||
2107 | * - it is not Y2038-safe. | ||
2108 | * - some people want deterministic results | ||
2109 | * (normally they'd use -n, but our -n is a nop). | ||
2110 | * - it's bloat. | ||
2111 | * Per RFC 1952, gzfile.time=0 is "no timestamp". | ||
2112 | * If users will demand this to be reinstated, | ||
2113 | * implement -n "don't save timestamp". | ||
2114 | */ | ||
2115 | struct stat s; | ||
2080 | s.st_ctime = 0; | 2116 | s.st_ctime = 0; |
2081 | fstat(STDIN_FILENO, &s); | 2117 | fstat(STDIN_FILENO, &s); |
2082 | zip(s.st_ctime); | 2118 | zip(s.st_ctime); |
2119 | #else | ||
2120 | zip(); | ||
2121 | #endif | ||
2083 | return 0; | 2122 | return 0; |
2084 | } | 2123 | } |
2085 | 2124 | ||
diff --git a/archival/libarchive/Kbuild.src b/archival/libarchive/Kbuild.src index 968fdf8ab..b7faaf77f 100644 --- a/archival/libarchive/Kbuild.src +++ b/archival/libarchive/Kbuild.src | |||
@@ -30,11 +30,13 @@ COMMON_FILES:= \ | |||
30 | DPKG_FILES:= \ | 30 | DPKG_FILES:= \ |
31 | unpack_ar_archive.o \ | 31 | unpack_ar_archive.o \ |
32 | filter_accept_list_reassign.o \ | 32 | filter_accept_list_reassign.o \ |
33 | unsafe_prefix.o \ | ||
33 | get_header_ar.o \ | 34 | get_header_ar.o \ |
34 | get_header_tar.o \ | 35 | get_header_tar.o \ |
35 | get_header_tar_gz.o \ | 36 | get_header_tar_gz.o \ |
36 | get_header_tar_bz2.o \ | 37 | get_header_tar_bz2.o \ |
37 | get_header_tar_lzma.o \ | 38 | get_header_tar_lzma.o \ |
39 | get_header_tar_xz.o \ | ||
38 | 40 | ||
39 | INSERT | 41 | INSERT |
40 | 42 | ||
@@ -43,7 +45,7 @@ lib-$(CONFIG_DPKG_DEB) += $(DPKG_FILES) | |||
43 | 45 | ||
44 | lib-$(CONFIG_AR) += get_header_ar.o unpack_ar_archive.o | 46 | lib-$(CONFIG_AR) += get_header_ar.o unpack_ar_archive.o |
45 | lib-$(CONFIG_CPIO) += get_header_cpio.o | 47 | lib-$(CONFIG_CPIO) += get_header_cpio.o |
46 | lib-$(CONFIG_TAR) += get_header_tar.o | 48 | lib-$(CONFIG_TAR) += get_header_tar.o unsafe_prefix.o |
47 | lib-$(CONFIG_FEATURE_TAR_TO_COMMAND) += data_extract_to_command.o | 49 | lib-$(CONFIG_FEATURE_TAR_TO_COMMAND) += data_extract_to_command.o |
48 | lib-$(CONFIG_LZOP) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o | 50 | lib-$(CONFIG_LZOP) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o |
49 | lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o | 51 | lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o |
@@ -52,7 +54,7 @@ lib-$(CONFIG_UNLZMA) += open_transformer.o decompress_unlzma. | |||
52 | lib-$(CONFIG_UNXZ) += open_transformer.o decompress_unxz.o | 54 | lib-$(CONFIG_UNXZ) += open_transformer.o decompress_unxz.o |
53 | lib-$(CONFIG_GUNZIP) += open_transformer.o decompress_gunzip.o | 55 | lib-$(CONFIG_GUNZIP) += open_transformer.o decompress_gunzip.o |
54 | lib-$(CONFIG_UNCOMPRESS) += open_transformer.o decompress_uncompress.o | 56 | lib-$(CONFIG_UNCOMPRESS) += open_transformer.o decompress_uncompress.o |
55 | lib-$(CONFIG_UNZIP) += open_transformer.o decompress_gunzip.o | 57 | lib-$(CONFIG_UNZIP) += open_transformer.o decompress_gunzip.o unsafe_prefix.o |
56 | lib-$(CONFIG_RPM2CPIO) += open_transformer.o decompress_gunzip.o get_header_cpio.o | 58 | lib-$(CONFIG_RPM2CPIO) += open_transformer.o decompress_gunzip.o get_header_cpio.o |
57 | lib-$(CONFIG_RPM) += open_transformer.o decompress_gunzip.o get_header_cpio.o | 59 | lib-$(CONFIG_RPM) += open_transformer.o decompress_gunzip.o get_header_cpio.o |
58 | 60 | ||
diff --git a/archival/libarchive/filter_accept_list_reassign.c b/archival/libarchive/filter_accept_list_reassign.c index 3d19abe44..b9acfbc05 100644 --- a/archival/libarchive/filter_accept_list_reassign.c +++ b/archival/libarchive/filter_accept_list_reassign.c | |||
@@ -28,6 +28,10 @@ char FAST_FUNC filter_accept_list_reassign(archive_handle_t *archive_handle) | |||
28 | name_ptr++; | 28 | name_ptr++; |
29 | 29 | ||
30 | /* Modify the subarchive handler based on the extension */ | 30 | /* Modify the subarchive handler based on the extension */ |
31 | if (strcmp(name_ptr, "tar") == 0) { | ||
32 | archive_handle->dpkg__action_data_subarchive = get_header_tar; | ||
33 | return EXIT_SUCCESS; | ||
34 | } | ||
31 | if (ENABLE_FEATURE_SEAMLESS_GZ | 35 | if (ENABLE_FEATURE_SEAMLESS_GZ |
32 | && strcmp(name_ptr, "gz") == 0 | 36 | && strcmp(name_ptr, "gz") == 0 |
33 | ) { | 37 | ) { |
@@ -46,6 +50,12 @@ char FAST_FUNC filter_accept_list_reassign(archive_handle_t *archive_handle) | |||
46 | archive_handle->dpkg__action_data_subarchive = get_header_tar_lzma; | 50 | archive_handle->dpkg__action_data_subarchive = get_header_tar_lzma; |
47 | return EXIT_SUCCESS; | 51 | return EXIT_SUCCESS; |
48 | } | 52 | } |
53 | if (ENABLE_FEATURE_SEAMLESS_XZ | ||
54 | && strcmp(name_ptr, "xz") == 0 | ||
55 | ) { | ||
56 | archive_handle->dpkg__action_data_subarchive = get_header_tar_xz; | ||
57 | return EXIT_SUCCESS; | ||
58 | } | ||
49 | } | 59 | } |
50 | return EXIT_FAILURE; | 60 | return EXIT_FAILURE; |
51 | } | 61 | } |
diff --git a/archival/libarchive/get_header_cpio.c b/archival/libarchive/get_header_cpio.c index 1a0058b63..7861d1f6f 100644 --- a/archival/libarchive/get_header_cpio.c +++ b/archival/libarchive/get_header_cpio.c | |||
@@ -37,7 +37,7 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle) | |||
37 | } | 37 | } |
38 | archive_handle->offset += 110; | 38 | archive_handle->offset += 110; |
39 | 39 | ||
40 | if (strncmp(&cpio_header[0], "07070", 5) != 0 | 40 | if (!is_prefixed_with(&cpio_header[0], "07070") |
41 | || (cpio_header[5] != '1' && cpio_header[5] != '2') | 41 | || (cpio_header[5] != '1' && cpio_header[5] != '2') |
42 | ) { | 42 | ) { |
43 | bb_error_msg_and_die("unsupported cpio format, use newc or crc"); | 43 | bb_error_msg_and_die("unsupported cpio format, use newc or crc"); |
diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index ba43bb073..2dbcdb50c 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c | |||
@@ -17,36 +17,6 @@ | |||
17 | typedef uint32_t aliased_uint32_t FIX_ALIASING; | 17 | 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 | |||
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 | |||
50 | /* NB: _DESTROYS_ str[len] character! */ | 20 | /* NB: _DESTROYS_ str[len] character! */ |
51 | static unsigned long long getOctal(char *str, int len) | 21 | static unsigned long long getOctal(char *str, int len) |
52 | { | 22 | { |
@@ -135,7 +105,7 @@ static void process_pax_hdr(archive_handle_t *archive_handle, unsigned sz, int g | |||
135 | value = end + 1; | 105 | value = end + 1; |
136 | 106 | ||
137 | #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS | 107 | #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS |
138 | if (!global && strncmp(value, "path=", sizeof("path=") - 1) == 0) { | 108 | if (!global && is_prefixed_with(value, "path=")) { |
139 | value += sizeof("path=") - 1; | 109 | value += sizeof("path=") - 1; |
140 | free(archive_handle->tar__longname); | 110 | free(archive_handle->tar__longname); |
141 | archive_handle->tar__longname = xstrdup(value); | 111 | archive_handle->tar__longname = xstrdup(value); |
@@ -148,7 +118,7 @@ static void process_pax_hdr(archive_handle_t *archive_handle, unsigned sz, int g | |||
148 | * This is what Red Hat's patched version of tar uses. | 118 | * This is what Red Hat's patched version of tar uses. |
149 | */ | 119 | */ |
150 | # define SELINUX_CONTEXT_KEYWORD "RHT.security.selinux" | 120 | # define SELINUX_CONTEXT_KEYWORD "RHT.security.selinux" |
151 | if (strncmp(value, SELINUX_CONTEXT_KEYWORD"=", sizeof(SELINUX_CONTEXT_KEYWORD"=") - 1) == 0) { | 121 | if (is_prefixed_with(value, SELINUX_CONTEXT_KEYWORD"=")) { |
152 | value += sizeof(SELINUX_CONTEXT_KEYWORD"=") - 1; | 122 | value += sizeof(SELINUX_CONTEXT_KEYWORD"=") - 1; |
153 | free(archive_handle->tar__sctx[global]); | 123 | free(archive_handle->tar__sctx[global]); |
154 | archive_handle->tar__sctx[global] = xstrdup(value); | 124 | archive_handle->tar__sctx[global] = xstrdup(value); |
@@ -232,7 +202,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
232 | 202 | ||
233 | /* Check header has valid magic, "ustar" is for the proper tar, | 203 | /* Check header has valid magic, "ustar" is for the proper tar, |
234 | * five NULs are for the old tar format */ | 204 | * five NULs are for the old tar format */ |
235 | if (strncmp(tar.magic, "ustar", 5) != 0 | 205 | if (!is_prefixed_with(tar.magic, "ustar") |
236 | && (!ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY | 206 | && (!ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY |
237 | || memcmp(tar.magic, "\0\0\0\0", 5) != 0) | 207 | || memcmp(tar.magic, "\0\0\0\0", 5) != 0) |
238 | ) { | 208 | ) { |
diff --git a/archival/libarchive/get_header_tar_xz.c b/archival/libarchive/get_header_tar_xz.c new file mode 100644 index 000000000..7bf3b3b56 --- /dev/null +++ b/archival/libarchive/get_header_tar_xz.c | |||
@@ -0,0 +1,21 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
4 | */ | ||
5 | |||
6 | #include "libbb.h" | ||
7 | #include "bb_archive.h" | ||
8 | |||
9 | char FAST_FUNC get_header_tar_xz(archive_handle_t *archive_handle) | ||
10 | { | ||
11 | /* Can't lseek over pipes */ | ||
12 | archive_handle->seek = seek_by_read; | ||
13 | |||
14 | fork_transformer_with_sig(archive_handle->src_fd, unpack_xz_stream, "unxz"); | ||
15 | archive_handle->offset = 0; | ||
16 | while (get_header_tar(archive_handle) == EXIT_SUCCESS) | ||
17 | continue; | ||
18 | |||
19 | /* Can only do one file at a time */ | ||
20 | return EXIT_FAILURE; | ||
21 | } | ||
diff --git a/archival/libarchive/unpack_ar_archive.c b/archival/libarchive/unpack_ar_archive.c index 214d17e23..0bc030349 100644 --- a/archival/libarchive/unpack_ar_archive.c +++ b/archival/libarchive/unpack_ar_archive.c | |||
@@ -12,7 +12,7 @@ void FAST_FUNC unpack_ar_archive(archive_handle_t *ar_archive) | |||
12 | char magic[7]; | 12 | char magic[7]; |
13 | 13 | ||
14 | xread(ar_archive->src_fd, magic, AR_MAGIC_LEN); | 14 | xread(ar_archive->src_fd, magic, AR_MAGIC_LEN); |
15 | if (strncmp(magic, AR_MAGIC, AR_MAGIC_LEN) != 0) { | 15 | if (!is_prefixed_with(magic, AR_MAGIC)) { |
16 | bb_error_msg_and_die("invalid ar magic"); | 16 | bb_error_msg_and_die("invalid ar magic"); |
17 | } | 17 | } |
18 | ar_archive->offset += AR_MAGIC_LEN; | 18 | ar_archive->offset += AR_MAGIC_LEN; |
diff --git a/archival/libarchive/unsafe_prefix.c b/archival/libarchive/unsafe_prefix.c new file mode 100644 index 000000000..9994f4d94 --- /dev/null +++ b/archival/libarchive/unsafe_prefix.c | |||
@@ -0,0 +1,36 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
4 | */ | ||
5 | |||
6 | #include "libbb.h" | ||
7 | #include "bb_archive.h" | ||
8 | |||
9 | const char* FAST_FUNC strip_unsafe_prefix(const char *str) | ||
10 | { | ||
11 | const char *cp = str; | ||
12 | while (1) { | ||
13 | char *cp2; | ||
14 | if (*cp == '/') { | ||
15 | cp++; | ||
16 | continue; | ||
17 | } | ||
18 | if (is_prefixed_with(cp, "/../"+1)) { | ||
19 | cp += 3; | ||
20 | continue; | ||
21 | } | ||
22 | cp2 = strstr(cp, "/../"); | ||
23 | if (!cp2) | ||
24 | break; | ||
25 | cp = cp2 + 4; | ||
26 | } | ||
27 | if (cp != str) { | ||
28 | static smallint warned = 0; | ||
29 | if (!warned) { | ||
30 | warned = 1; | ||
31 | bb_error_msg("removing leading '%.*s' from member names", | ||
32 | (int)(cp - str), str); | ||
33 | } | ||
34 | } | ||
35 | return cp; | ||
36 | } | ||
diff --git a/archival/unzip.c b/archival/unzip.c index 1ef026a9f..d370203e8 100644 --- a/archival/unzip.c +++ b/archival/unzip.c | |||
@@ -599,14 +599,18 @@ int unzip_main(int argc, char **argv) | |||
599 | /* Skip extra header bytes */ | 599 | /* Skip extra header bytes */ |
600 | unzip_skip(zip_header.formatted.extra_len); | 600 | unzip_skip(zip_header.formatted.extra_len); |
601 | 601 | ||
602 | /* Guard against "/abspath", "/../" and similar attacks */ | ||
603 | overlapping_strcpy(dst_fn, strip_unsafe_prefix(dst_fn)); | ||
604 | |||
602 | /* Filter zip entries */ | 605 | /* Filter zip entries */ |
603 | if (find_list_entry(zreject, dst_fn) | 606 | if (find_list_entry(zreject, dst_fn) |
604 | || (zaccept && !find_list_entry(zaccept, dst_fn)) | 607 | || (zaccept && !find_list_entry(zaccept, dst_fn)) |
605 | ) { /* Skip entry */ | 608 | ) { /* Skip entry */ |
606 | i = 'n'; | 609 | i = 'n'; |
607 | 610 | ||
608 | } else { /* Extract entry */ | 611 | } else { |
609 | if (listing) { /* List entry */ | 612 | if (listing) { |
613 | /* List entry */ | ||
610 | unsigned dostime = zip_header.formatted.modtime | (zip_header.formatted.moddate << 16); | 614 | unsigned dostime = zip_header.formatted.modtime | (zip_header.formatted.moddate << 16); |
611 | if (!verbose) { | 615 | if (!verbose) { |
612 | // " Length Date Time Name\n" | 616 | // " Length Date Time Name\n" |
@@ -642,9 +646,11 @@ int unzip_main(int argc, char **argv) | |||
642 | total_size += zip_header.formatted.cmpsize; | 646 | total_size += zip_header.formatted.cmpsize; |
643 | } | 647 | } |
644 | i = 'n'; | 648 | i = 'n'; |
645 | } else if (dst_fd == STDOUT_FILENO) { /* Extracting to STDOUT */ | 649 | } else if (dst_fd == STDOUT_FILENO) { |
650 | /* Extracting to STDOUT */ | ||
646 | i = -1; | 651 | i = -1; |
647 | } else if (last_char_is(dst_fn, '/')) { /* Extract directory */ | 652 | } else if (last_char_is(dst_fn, '/')) { |
653 | /* Extract directory */ | ||
648 | if (stat(dst_fn, &stat_buf) == -1) { | 654 | if (stat(dst_fn, &stat_buf) == -1) { |
649 | if (errno != ENOENT) { | 655 | if (errno != ENOENT) { |
650 | bb_perror_msg_and_die("can't stat '%s'", dst_fn); | 656 | bb_perror_msg_and_die("can't stat '%s'", dst_fn); |
@@ -658,22 +664,27 @@ int unzip_main(int argc, char **argv) | |||
658 | } | 664 | } |
659 | } else { | 665 | } else { |
660 | if (!S_ISDIR(stat_buf.st_mode)) { | 666 | if (!S_ISDIR(stat_buf.st_mode)) { |
661 | bb_error_msg_and_die("'%s' exists but is not directory", dst_fn); | 667 | bb_error_msg_and_die("'%s' exists but is not a %s", |
668 | dst_fn, "directory"); | ||
662 | } | 669 | } |
663 | } | 670 | } |
664 | i = 'n'; | 671 | i = 'n'; |
665 | 672 | ||
666 | } else { /* Extract file */ | 673 | } else { |
674 | /* Extract file */ | ||
667 | check_file: | 675 | check_file: |
668 | if (stat(dst_fn, &stat_buf) == -1) { /* File does not exist */ | 676 | if (stat(dst_fn, &stat_buf) == -1) { |
677 | /* File does not exist */ | ||
669 | if (errno != ENOENT) { | 678 | if (errno != ENOENT) { |
670 | bb_perror_msg_and_die("can't stat '%s'", dst_fn); | 679 | bb_perror_msg_and_die("can't stat '%s'", dst_fn); |
671 | } | 680 | } |
672 | i = 'y'; | 681 | i = 'y'; |
673 | } else { /* File already exists */ | 682 | } else { |
683 | /* File already exists */ | ||
674 | if (overwrite == O_NEVER) { | 684 | if (overwrite == O_NEVER) { |
675 | i = 'n'; | 685 | i = 'n'; |
676 | } else if (S_ISREG(stat_buf.st_mode)) { /* File is regular file */ | 686 | } else if (S_ISREG(stat_buf.st_mode)) { |
687 | /* File is regular file */ | ||
677 | if (overwrite == O_ALWAYS) { | 688 | if (overwrite == O_ALWAYS) { |
678 | i = 'y'; | 689 | i = 'y'; |
679 | } else { | 690 | } else { |
@@ -681,8 +692,10 @@ int unzip_main(int argc, char **argv) | |||
681 | my_fgets80(key_buf); | 692 | my_fgets80(key_buf); |
682 | i = key_buf[0]; | 693 | i = key_buf[0]; |
683 | } | 694 | } |
684 | } else { /* File is not regular file */ | 695 | } else { |
685 | bb_error_msg_and_die("'%s' exists but is not regular file", dst_fn); | 696 | /* File is not regular file */ |
697 | bb_error_msg_and_die("'%s' exists but is not a %s", | ||
698 | dst_fn, "regular file"); | ||
686 | } | 699 | } |
687 | } | 700 | } |
688 | } | 701 | } |