From: Tim Kientzle Date: Fri, 5 Jul 2024 10:05:41 +0000 (-0700) Subject: Don't try to read rediculously long names (#2259) X-Git-Tag: v3.7.5~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e45b0aa7eebddaaec8139cb1f0a4058f3c1e5369;p=thirdparty%2Flibarchive.git Don't try to read rediculously long names (#2259) The Rar5 reader would read the name size, then read the name, then check whether the name size was beyond the maximum size allowed. This can result in a very large memory allocation to read a name. Instead, check the name size before trying to read the name in order to avoid excessive allocation. OSS-Fuzz Issue: 70017 --- diff --git a/libarchive/archive_read_support_format_rar5.c b/libarchive/archive_read_support_format_rar5.c index bd5a02179..8907fdb2f 100644 --- a/libarchive/archive_read_support_format_rar5.c +++ b/libarchive/archive_read_support_format_rar5.c @@ -1448,9 +1448,6 @@ static int parse_file_extra_redir(struct archive_read* a, return ARCHIVE_EOF; *extra_data_size -= target_size + 1; - if(!read_ahead(a, target_size, &p)) - return ARCHIVE_EOF; - if(target_size > (MAX_NAME_IN_CHARS - 1)) { archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Link target is too long"); @@ -1463,6 +1460,9 @@ static int parse_file_extra_redir(struct archive_read* a, return ARCHIVE_FATAL; } + if(!read_ahead(a, target_size, &p)) + return ARCHIVE_EOF; + memcpy(target_utf8_buf, p, target_size); target_utf8_buf[target_size] = 0; @@ -1876,9 +1876,6 @@ static int process_head_file(struct archive_read* a, struct rar5* rar, if(!read_var_sized(a, &name_size, NULL)) return ARCHIVE_EOF; - if(!read_ahead(a, name_size, &p)) - return ARCHIVE_EOF; - if(name_size > (MAX_NAME_IN_CHARS - 1)) { archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Filename is too long"); @@ -1893,6 +1890,9 @@ static int process_head_file(struct archive_read* a, struct rar5* rar, return ARCHIVE_FATAL; } + if(!read_ahead(a, name_size, &p)) + return ARCHIVE_EOF; + memcpy(name_utf8_buf, p, name_size); name_utf8_buf[name_size] = 0; if(ARCHIVE_OK != consume(a, name_size)) {