From fc8c6d2786ecba731d77d33fe3b034f581fcbde3 Mon Sep 17 00:00:00 2001
From: Ben Wagner <bungeman@chromium.org>
Date: Tue, 19 Jul 2022 13:02:40 -0400
Subject: [PATCH] Validate entry_bytes_remaining in pax_attribute

The `size` attribute may contain a negative or too large value. Check
the range of the `entry_bytes_remaining` in `pax_attribute` the same way
as `header_common`. The test which is added passes both with and without
this change in a normal debug build. It is necessary to run with
`-fsanitize=undefined` to see that the undefined behavior is avoided.

Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=48467
---
 libarchive/archive_read_support_format_tar.c  | 15 ++++++
 1 files changed, 15 insertions(+)

diff --git a/libarchive/archive_read_support_format_tar.c b/libarchive/archive_read_support_format_tar.c
index bfdad7f8..e31f1cc4 100644
--- a/libarchive/archive_read_support_format_tar.c
+++ b/libarchive/archive_read_support_format_tar.c
@@ -2108,6 +2108,21 @@ pax_attribute(struct archive_read *a, struct tar *tar,
 			/* "size" is the size of the data in the entry. */
 			tar->entry_bytes_remaining
 			    = tar_atol10(value, strlen(value));
+			if (tar->entry_bytes_remaining < 0) {
+				tar->entry_bytes_remaining = 0;
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_MISC,
+				    "Tar size attribute is negative");
+				return (ARCHIVE_FATAL);
+			}
+			if (tar->entry_bytes_remaining == INT64_MAX) {
+				/* Note: tar_atol returns INT64_MAX on overflow */
+				tar->entry_bytes_remaining = 0;
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_MISC,
+				    "Tar size attribute overflow");
+				return (ARCHIVE_FATAL);
+			}
 			/*
 			 * The "size" pax header keyword always overrides the
 			 * "size" field in the tar header.
