diff options
Diffstat (limited to 'archival/libarchive/get_header_tar.c')
-rw-r--r-- | archival/libarchive/get_header_tar.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index 2ab3c04b8..d26868bf8 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c | |||
@@ -147,6 +147,12 @@ static void process_pax_hdr(archive_handle_t *archive_handle, unsigned sz, int g | |||
147 | #endif | 147 | #endif |
148 | } | 148 | } |
149 | 149 | ||
150 | static void die_if_bad_fnamesize(off_t sz) | ||
151 | { | ||
152 | if ((uoff_t)sz > 0xfff) /* more than 4k?! no funny business please */ | ||
153 | bb_simple_error_msg_and_die("bad archive"); | ||
154 | } | ||
155 | |||
150 | char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | 156 | char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) |
151 | { | 157 | { |
152 | file_header_t *file_header = archive_handle->file_header; | 158 | file_header_t *file_header = archive_handle->file_header; |
@@ -331,8 +337,6 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
331 | file_header->name = xstrdup(tar.name); | 337 | file_header->name = xstrdup(tar.name); |
332 | } | 338 | } |
333 | 339 | ||
334 | /* Set bits 12-15 of the files mode */ | ||
335 | /* (typeflag was not trashed because chksum does not use getOctal) */ | ||
336 | switch (tar_typeflag) { | 340 | switch (tar_typeflag) { |
337 | case '1': /* hardlink */ | 341 | case '1': /* hardlink */ |
338 | /* we mark hardlinks as regular files with zero size and a link name */ | 342 | /* we mark hardlinks as regular files with zero size and a link name */ |
@@ -341,7 +345,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
341 | * ... For tar archives written by pre POSIX.1-1988 | 345 | * ... For tar archives written by pre POSIX.1-1988 |
342 | * implementations, the size field usually contains the size of | 346 | * implementations, the size field usually contains the size of |
343 | * the file and needs to be ignored as no data may follow this | 347 | * the file and needs to be ignored as no data may follow this |
344 | * header type. For POSIX.1- 1988 compliant archives, the size | 348 | * header type. For POSIX.1-1988 compliant archives, the size |
345 | * field needs to be 0. For POSIX.1-2001 compliant archives, | 349 | * field needs to be 0. For POSIX.1-2001 compliant archives, |
346 | * the size field may be non zero, indicating that file data is | 350 | * the size field may be non zero, indicating that file data is |
347 | * included in the archive. | 351 | * included in the archive. |
@@ -390,6 +394,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
390 | /* free: paranoia: tar with several consecutive longnames */ | 394 | /* free: paranoia: tar with several consecutive longnames */ |
391 | free(p_longname); | 395 | free(p_longname); |
392 | /* For paranoia reasons we allocate extra NUL char */ | 396 | /* For paranoia reasons we allocate extra NUL char */ |
397 | die_if_bad_fnamesize(file_header->size); | ||
393 | p_longname = xzalloc(file_header->size + 1); | 398 | p_longname = xzalloc(file_header->size + 1); |
394 | /* We read ASCIZ string, including NUL */ | 399 | /* We read ASCIZ string, including NUL */ |
395 | xread(archive_handle->src_fd, p_longname, file_header->size); | 400 | xread(archive_handle->src_fd, p_longname, file_header->size); |
@@ -400,6 +405,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
400 | goto again; | 405 | goto again; |
401 | case 'K': | 406 | case 'K': |
402 | free(p_linkname); | 407 | free(p_linkname); |
408 | die_if_bad_fnamesize(file_header->size); | ||
403 | p_linkname = xzalloc(file_header->size + 1); | 409 | p_linkname = xzalloc(file_header->size + 1); |
404 | xread(archive_handle->src_fd, p_linkname, file_header->size); | 410 | xread(archive_handle->src_fd, p_linkname, file_header->size); |
405 | archive_handle->offset += file_header->size; | 411 | archive_handle->offset += file_header->size; |