]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Don't try to read rediculously long names (#2259)
authorTim Kientzle <kientzle@acm.org>
Fri, 5 Jul 2024 10:05:41 +0000 (03:05 -0700)
committerGitHub <noreply@github.com>
Fri, 5 Jul 2024 10:05:41 +0000 (12:05 +0200)
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

libarchive/archive_read_support_format_rar5.c

index bd5a02179fb2e937c3d83d8e0aeeccda2e27f2c4..8907fdb2fce784f697ec9aaf660dac5feec5d1c3 100644 (file)
@@ -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)) {