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 44715ef25..353f68217 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c | |||
@@ -157,7 +157,7 @@ void FAST_FUNC fork_transformer(int fd, const char *transform_prog) | |||
157 | /* Used by e.g. rpm which gives us a fd without filename, | 157 | /* Used by e.g. rpm which gives us a fd without filename, |
158 | * thus we can't guess the format from filename's extension. | 158 | * thus we can't guess the format from filename's extension. |
159 | */ | 159 | */ |
160 | static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_compressed) | 160 | static transformer_state_t *setup_transformer_on_fd(int fd, int die_if_not_compressed) |
161 | { | 161 | { |
162 | transformer_state_t *xstate; | 162 | transformer_state_t *xstate; |
163 | 163 | ||
@@ -204,7 +204,7 @@ static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_comp | |||
204 | } | 204 | } |
205 | 205 | ||
206 | /* No known magic seen */ | 206 | /* No known magic seen */ |
207 | if (fail_if_not_compressed) | 207 | if (die_if_not_compressed) |
208 | bb_simple_error_msg_and_die("no gzip" | 208 | bb_simple_error_msg_and_die("no gzip" |
209 | IF_FEATURE_SEAMLESS_BZ2("/bzip2") | 209 | IF_FEATURE_SEAMLESS_BZ2("/bzip2") |
210 | IF_FEATURE_SEAMLESS_XZ("/xz") | 210 | IF_FEATURE_SEAMLESS_XZ("/xz") |
@@ -240,13 +240,15 @@ static void fork_transformer_and_free(transformer_state_t *xstate) | |||
240 | /* Used by e.g. rpm which gives us a fd without filename, | 240 | /* Used by e.g. rpm which gives us a fd without filename, |
241 | * thus we can't guess the format from filename's extension. | 241 | * thus we can't guess the format from filename's extension. |
242 | */ | 242 | */ |
243 | int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) | 243 | int FAST_FUNC setup_unzip_on_fd(int fd, int die_if_not_compressed) |
244 | { | 244 | { |
245 | transformer_state_t *xstate = setup_transformer_on_fd(fd, fail_if_not_compressed); | 245 | transformer_state_t *xstate = setup_transformer_on_fd(fd, die_if_not_compressed); |
246 | 246 | ||
247 | if (!xstate->xformer) { | 247 | if (!xstate->xformer) { |
248 | /* Not compressed */ | ||
249 | int retval = xstate->signature_skipped; /* never zero */ | ||
248 | free(xstate); | 250 | free(xstate); |
249 | return 1; | 251 | return retval; |
250 | } | 252 | } |
251 | 253 | ||
252 | fork_transformer_and_free(xstate); | 254 | fork_transformer_and_free(xstate); |
@@ -264,7 +266,7 @@ void FAST_FUNC setup_lzma_on_fd(int fd) | |||
264 | } | 266 | } |
265 | #endif | 267 | #endif |
266 | 268 | ||
267 | static transformer_state_t *open_transformer(const char *fname, int fail_if_not_compressed) | 269 | static transformer_state_t *open_transformer(const char *fname, int die_if_not_compressed) |
268 | { | 270 | { |
269 | transformer_state_t *xstate; | 271 | transformer_state_t *xstate; |
270 | int fd; | 272 | int fd; |
@@ -284,18 +286,18 @@ static transformer_state_t *open_transformer(const char *fname, int fail_if_not_ | |||
284 | } | 286 | } |
285 | } | 287 | } |
286 | 288 | ||
287 | xstate = setup_transformer_on_fd(fd, fail_if_not_compressed); | 289 | xstate = setup_transformer_on_fd(fd, die_if_not_compressed); |
288 | 290 | ||
289 | return xstate; | 291 | return xstate; |
290 | } | 292 | } |
291 | 293 | ||
292 | int FAST_FUNC open_zipped(const char *fname, int fail_if_not_compressed) | 294 | int FAST_FUNC open_zipped(const char *fname, int die_if_not_compressed) |
293 | { | 295 | { |
294 | int fd; | 296 | int fd; |
295 | transformer_state_t *xstate; | 297 | transformer_state_t *xstate; |
296 | 298 | ||
297 | xstate = open_transformer(fname, fail_if_not_compressed); | 299 | xstate = open_transformer(fname, die_if_not_compressed); |
298 | if (!xstate) | 300 | if (!xstate) /* open error */ |
299 | return -1; | 301 | return -1; |
300 | 302 | ||
301 | fd = xstate->src_fd; | 303 | fd = xstate->src_fd; |
@@ -326,7 +328,7 @@ void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_ | |||
326 | transformer_state_t *xstate; | 328 | transformer_state_t *xstate; |
327 | char *image; | 329 | char *image; |
328 | 330 | ||
329 | xstate = open_transformer(fname, /*fail_if_not_compressed:*/ 0); | 331 | xstate = open_transformer(fname, /*die_if_not_compressed:*/ 0); |
330 | if (!xstate) /* file open error */ | 332 | if (!xstate) /* file open error */ |
331 | return NULL; | 333 | return NULL; |
332 | 334 | ||
@@ -371,7 +373,7 @@ void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_ | |||
371 | int fd; | 373 | int fd; |
372 | char *image; | 374 | char *image; |
373 | 375 | ||
374 | fd = open_zipped(fname, /*fail_if_not_compressed:*/ 0); | 376 | fd = open_zipped(fname, /*die_if_not_compressed:*/ 0); |
375 | if (fd < 0) | 377 | if (fd < 0) |
376 | return NULL; | 378 | return NULL; |
377 | 379 | ||
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 | } |