diff options
Diffstat (limited to 'archival/libarchive')
-rw-r--r-- | archival/libarchive/data_extract_all.c | 8 | ||||
-rw-r--r-- | archival/libarchive/open_transformer.c | 26 | ||||
-rw-r--r-- | archival/libarchive/unsafe_prefix.c | 6 |
3 files changed, 27 insertions, 13 deletions
diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c index 049c2c156..8a69711c1 100644 --- a/archival/libarchive/data_extract_all.c +++ b/archival/libarchive/data_extract_all.c | |||
@@ -65,6 +65,14 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
65 | } while (--n != 0); | 65 | } while (--n != 0); |
66 | } | 66 | } |
67 | #endif | 67 | #endif |
68 | #if ENABLE_FEATURE_PATH_TRAVERSAL_PROTECTION | ||
69 | /* Strip leading "/" and up to last "/../" path component */ | ||
70 | dst_name = (char *)strip_unsafe_prefix(dst_name); | ||
71 | #endif | ||
72 | // ^^^ This may be a problem if some applets do need to extract absolute names. | ||
73 | // (Probably will need to invent ARCHIVE_ALLOW_UNSAFE_NAME flag). | ||
74 | // You might think that rpm needs it, but in my tests rpm's internal cpio | ||
75 | // archive has names like "./usr/bin/FOO", not "/usr/bin/FOO". | ||
68 | 76 | ||
69 | if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) { | 77 | if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) { |
70 | char *slash = strrchr(dst_name, '/'); | 78 | char *slash = strrchr(dst_name, '/'); |
diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c index 3d202ad26..a949c4509 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c | |||
@@ -164,7 +164,7 @@ void FAST_FUNC fork_transformer(int fd, const char *transform_prog) | |||
164 | /* Used by e.g. rpm which gives us a fd without filename, | 164 | /* Used by e.g. rpm which gives us a fd without filename, |
165 | * thus we can't guess the format from filename's extension. | 165 | * thus we can't guess the format from filename's extension. |
166 | */ | 166 | */ |
167 | static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_compressed) | 167 | static transformer_state_t *setup_transformer_on_fd(int fd, int die_if_not_compressed) |
168 | { | 168 | { |
169 | transformer_state_t *xstate; | 169 | transformer_state_t *xstate; |
170 | 170 | ||
@@ -211,7 +211,7 @@ static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_comp | |||
211 | } | 211 | } |
212 | 212 | ||
213 | /* No known magic seen */ | 213 | /* No known magic seen */ |
214 | if (fail_if_not_compressed) | 214 | if (die_if_not_compressed) |
215 | bb_simple_error_msg_and_die("no gzip" | 215 | bb_simple_error_msg_and_die("no gzip" |
216 | IF_FEATURE_SEAMLESS_BZ2("/bzip2") | 216 | IF_FEATURE_SEAMLESS_BZ2("/bzip2") |
217 | IF_FEATURE_SEAMLESS_XZ("/xz") | 217 | IF_FEATURE_SEAMLESS_XZ("/xz") |
@@ -247,13 +247,15 @@ static void fork_transformer_and_free(transformer_state_t *xstate) | |||
247 | /* Used by e.g. rpm which gives us a fd without filename, | 247 | /* Used by e.g. rpm which gives us a fd without filename, |
248 | * thus we can't guess the format from filename's extension. | 248 | * thus we can't guess the format from filename's extension. |
249 | */ | 249 | */ |
250 | int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) | 250 | int FAST_FUNC setup_unzip_on_fd(int fd, int die_if_not_compressed) |
251 | { | 251 | { |
252 | transformer_state_t *xstate = setup_transformer_on_fd(fd, fail_if_not_compressed); | 252 | transformer_state_t *xstate = setup_transformer_on_fd(fd, die_if_not_compressed); |
253 | 253 | ||
254 | if (!xstate->xformer) { | 254 | if (!xstate->xformer) { |
255 | /* Not compressed */ | ||
256 | int retval = xstate->signature_skipped; /* never zero */ | ||
255 | free(xstate); | 257 | free(xstate); |
256 | return 1; | 258 | return retval; |
257 | } | 259 | } |
258 | 260 | ||
259 | fork_transformer_and_free(xstate); | 261 | fork_transformer_and_free(xstate); |
@@ -271,7 +273,7 @@ void FAST_FUNC setup_lzma_on_fd(int fd) | |||
271 | } | 273 | } |
272 | #endif | 274 | #endif |
273 | 275 | ||
274 | static transformer_state_t *open_transformer(const char *fname, int fail_if_not_compressed) | 276 | static transformer_state_t *open_transformer(const char *fname, int die_if_not_compressed) |
275 | { | 277 | { |
276 | transformer_state_t *xstate; | 278 | transformer_state_t *xstate; |
277 | int fd; | 279 | int fd; |
@@ -291,18 +293,18 @@ static transformer_state_t *open_transformer(const char *fname, int fail_if_not_ | |||
291 | } | 293 | } |
292 | } | 294 | } |
293 | 295 | ||
294 | xstate = setup_transformer_on_fd(fd, fail_if_not_compressed); | 296 | xstate = setup_transformer_on_fd(fd, die_if_not_compressed); |
295 | 297 | ||
296 | return xstate; | 298 | return xstate; |
297 | } | 299 | } |
298 | 300 | ||
299 | int FAST_FUNC open_zipped(const char *fname, int fail_if_not_compressed) | 301 | int FAST_FUNC open_zipped(const char *fname, int die_if_not_compressed) |
300 | { | 302 | { |
301 | int fd; | 303 | int fd; |
302 | transformer_state_t *xstate; | 304 | transformer_state_t *xstate; |
303 | 305 | ||
304 | xstate = open_transformer(fname, fail_if_not_compressed); | 306 | xstate = open_transformer(fname, die_if_not_compressed); |
305 | if (!xstate) | 307 | if (!xstate) /* open error */ |
306 | return -1; | 308 | return -1; |
307 | 309 | ||
308 | fd = xstate->src_fd; | 310 | fd = xstate->src_fd; |
@@ -333,7 +335,7 @@ void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_ | |||
333 | transformer_state_t *xstate; | 335 | transformer_state_t *xstate; |
334 | char *image; | 336 | char *image; |
335 | 337 | ||
336 | xstate = open_transformer(fname, /*fail_if_not_compressed:*/ 0); | 338 | xstate = open_transformer(fname, /*die_if_not_compressed:*/ 0); |
337 | if (!xstate) /* file open error */ | 339 | if (!xstate) /* file open error */ |
338 | return NULL; | 340 | return NULL; |
339 | 341 | ||
@@ -378,7 +380,7 @@ void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_ | |||
378 | int fd; | 380 | int fd; |
379 | char *image; | 381 | char *image; |
380 | 382 | ||
381 | fd = open_zipped(fname, /*fail_if_not_compressed:*/ 0); | 383 | fd = open_zipped(fname, /*die_if_not_compressed:*/ 0); |
382 | if (fd < 0) | 384 | if (fd < 0) |
383 | return NULL; | 385 | return NULL; |
384 | 386 | ||
diff --git a/archival/libarchive/unsafe_prefix.c b/archival/libarchive/unsafe_prefix.c index 33e487bf9..667081195 100644 --- a/archival/libarchive/unsafe_prefix.c +++ b/archival/libarchive/unsafe_prefix.c | |||
@@ -14,7 +14,11 @@ const char* FAST_FUNC strip_unsafe_prefix(const char *str) | |||
14 | cp++; | 14 | cp++; |
15 | continue; | 15 | continue; |
16 | } | 16 | } |
17 | if (is_prefixed_with(cp, "/../"+1)) { | 17 | /* We are called lots of times. |
18 | * is_prefixed_with(cp, "../") is slower than open-coding it, | ||
19 | * with minimal code growth (~few bytes). | ||
20 | */ | ||
21 | if (cp[0] == '.' && cp[1] == '.' && cp[2] == '/') { | ||
18 | cp += 3; | 22 | cp += 3; |
19 | continue; | 23 | continue; |
20 | } | 24 | } |