aboutsummaryrefslogtreecommitdiff
path: root/archival/libarchive
diff options
context:
space:
mode:
Diffstat (limited to 'archival/libarchive')
-rw-r--r--archival/libarchive/data_extract_all.c8
-rw-r--r--archival/libarchive/open_transformer.c26
-rw-r--r--archival/libarchive/unsafe_prefix.c6
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 */
160static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_compressed) 160static 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 */
243int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) 243int 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
267static transformer_state_t *open_transformer(const char *fname, int fail_if_not_compressed) 269static 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
292int FAST_FUNC open_zipped(const char *fname, int fail_if_not_compressed) 294int 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 }