diff options
author | Denys Vlasenko | 2021-10-11 19:28:39 +0200 |
---|---|---|
committer | Denys Vlasenko | 2021-10-11 19:28:39 +0200 |
commit | 6ba1f2d0bcdddb96c43ff9fec34758a4e2b4a467 (patch) | |
tree | 1961565061f829aabe0664af7ef076909e6ded72 | |
parent | aec8fbfb834dfcf46b7c967d6572c9adcb72b620 (diff) | |
download | busybox-6ba1f2d0bcdddb96c43ff9fec34758a4e2b4a467.zip busybox-6ba1f2d0bcdddb96c43ff9fec34758a4e2b4a467.tar.gz |
tar: prevent malicious archives with enormous long name sizes OOMing the machine
function old new delta
get_header_tar 1707 1752 +45
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/libarchive/get_header_tar.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index a142290..d26868b 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 #endif } +static void die_if_bad_fnamesize(off_t sz) +{ + if ((uoff_t)sz > 0xfff) /* more than 4k?! no funny business please */ + bb_simple_error_msg_and_die("bad archive"); +} + char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) { file_header_t *file_header = archive_handle->file_header; @@ -331,7 +337,6 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) file_header->name = xstrdup(tar.name); } - /* Set bits 12-15 of the files mode */ switch (tar_typeflag) { case '1': /* hardlink */ /* we mark hardlinks as regular files with zero size and a link name */ @@ -389,7 +394,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) /* free: paranoia: tar with several consecutive longnames */ free(p_longname); /* For paranoia reasons we allocate extra NUL char */ -//FIXME: disallow huge sizes: + die_if_bad_fnamesize(file_header->size); p_longname = xzalloc(file_header->size + 1); /* We read ASCIZ string, including NUL */ xread(archive_handle->src_fd, p_longname, file_header->size); @@ -400,7 +405,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) goto again; case 'K': free(p_linkname); -//FIXME: disallow huge sizes: + die_if_bad_fnamesize(file_header->size); p_linkname = xzalloc(file_header->size + 1); xread(archive_handle->src_fd, p_linkname, file_header->size); archive_handle->offset += file_header->size; |