]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Fix two leaks in tar header parsing (#2377)
authorTim Kientzle <kientzle@acm.org>
Sat, 12 Oct 2024 11:54:23 +0000 (04:54 -0700)
committerGitHub <noreply@github.com>
Sat, 12 Oct 2024 11:54:23 +0000 (13:54 +0200)
OSS-Fuzz found two places where an error return would bypass cleaning up
a local allocation.

Credit: OSS-Fuzz

libarchive/archive_read_support_format_tar.c

index 4a3d717832df22ac184f5235e2d0356e06003dfa..a0ff8b1dbb256c3739705b7db576b0da1308c818 100644 (file)
@@ -1036,16 +1036,14 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
        int64_t type;
        char *acl, *p;
 
-       /*
-        * read_body_to_string adds a NUL terminator, but we need a little
-        * more to make sure that we don't overrun acl_text later.
-        */
        header = (const struct archive_entry_header_ustar *)h;
        size = (size_t)tar_atol(header->size, sizeof(header->size));
        archive_string_init(&acl_text);
        err = read_body_to_string(a, tar, &acl_text, h, unconsumed);
-       if (err != ARCHIVE_OK)
+       if (err != ARCHIVE_OK) {
+               archive_string_free(&acl_text);
                return (err);
+       }
 
        /* TODO: Examine the first characters to see if this
         * is an AIX ACL descriptor.  We'll likely never support
@@ -1899,6 +1897,7 @@ header_pax_extension(struct archive_read *a, struct tar *tar,
                name_length = p - name_start;
                p++; // Skip '='
 
+               // Save the name before we consume it
                archive_strncpy(&attr_name, name_start, name_length);
 
                ext_size -= p - attr_start;
@@ -1912,6 +1911,9 @@ header_pax_extension(struct archive_read *a, struct tar *tar,
                r = pax_attribute(a, tar, entry, attr_name.s, archive_strlen(&attr_name), value_length - 1, unconsumed);
                ext_size -= value_length - 1;
 
+               // Release the allocated attr_name (either here or before every return in this function)
+               archive_string_free(&attr_name);
+
                if (r < ARCHIVE_WARN) {
                        *unconsumed += ext_size + ext_padding;
                        return (r);
@@ -1937,7 +1939,6 @@ header_pax_extension(struct archive_read *a, struct tar *tar,
                *unconsumed += 1;
                tar_flush_unconsumed(a, unconsumed);
        }
-       archive_string_free(&attr_name);
        *unconsumed += ext_size + ext_padding;
 
        /*