]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
tar: Always treat negative sizes as error 2644/head
authorTobias Stoeckmann <tobias@stoeckmann.org>
Tue, 27 May 2025 18:30:01 +0000 (20:30 +0200)
committerTobias Stoeckmann <tobias@stoeckmann.org>
Tue, 27 May 2025 18:46:51 +0000 (20:46 +0200)
If a pax global header specifies a negative size, it is possible to
reduce variable `unconsumed` by 512 bytes, leading to a re-reading
of the pax global header. Fortunately the loop verifies that only one
global header per entry is allowed, leading to a later ARCHIVE_FATAL.

Avoid any form of negative size handling and fail early.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
libarchive/archive_read_support_format_tar.c

index 1cc66716904510560cad482501615173afd80fae..52612fc37888f0978fdb502e84aabafece3e75da 100644 (file)
@@ -1304,10 +1304,13 @@ read_body_to_string(struct archive_read *a, struct tar *tar,
        (void)tar; /* UNUSED */
        header = (const struct archive_entry_header_ustar *)h;
        size  = tar_atol(header->size, sizeof(header->size));
-       if (size > entry_limit) {
+       if (size < 0 || size > entry_limit) {
+               archive_set_error(&a->archive, EINVAL,
+                   "Special header has invalid size: %lld",
+                   (long long)size);
                return (ARCHIVE_FATAL);
        }
-       if ((size > (int64_t)pathname_limit) || (size < 0)) {
+       if (size > (int64_t)pathname_limit) {
                archive_string_empty(as);
                int64_t to_consume = ((size + 511) & ~511);
                if (to_consume != __archive_read_consume(a, to_consume)) {
@@ -1754,7 +1757,10 @@ header_pax_global(struct archive_read *a, struct tar *tar,
 
        header = (const struct archive_entry_header_ustar *)h;
        size = tar_atol(header->size, sizeof(header->size));
-       if (size > entry_limit) {
+       if (size < 0 || size > entry_limit) {
+               archive_set_error(&a->archive, EINVAL,
+                   "Special header has invalid size: %lld",
+                   (long long)size);
                return (ARCHIVE_FATAL);
        }
        to_consume = ((size + 511) & ~511);