Blame SOURCES/libarchive-3.3.2-CVE-2019-19221.patch

f485a7
From 72085b30bf30867360c4aa77bd43de5e1788d875 Mon Sep 17 00:00:00 2001
f485a7
From: Ondrej Dubaj <odubaj@redhat.com>
f485a7
Date: Tue, 24 Mar 2020 09:22:47 +0100
f485a7
Subject: [PATCH] Bugfix and optimize archive_wstring_append_from_mbs()
f485a7
f485a7
The cal to mbrtowc() or mbtowc() should read up to mbs_length
f485a7
bytes and not wcs_length. This avoids out-of-bounds reads.
f485a7
f485a7
mbrtowc() and mbtowc() return (size_t)-1 wit errno EILSEQ when
f485a7
they encounter an invalid multibyte character and (size_t)-2 when
f485a7
they they encounter an incomplete multibyte character. As we return
f485a7
failure and all our callers error out it makes no sense to continue
f485a7
parsing mbs.
f485a7
f485a7
As we allocate `len` wchars at the beginning and each wchar has
f485a7
at least one byte, there will never be need to grow the buffer,
f485a7
so the code can be left out. On the other hand, we are always
f485a7
allocatng more memory than we need.
f485a7
f485a7
As long as wcs_length == mbs_length == len we can omit wcs_length.
f485a7
We keep the old code commented if we decide to save memory and
f485a7
use autoexpanding wcs_length in the future.
f485a7
---
f485a7
 libarchive/archive_string.c | 28 +++++++++++++++++-----------
f485a7
 1 file changed, 17 insertions(+), 11 deletions(-)
f485a7
f485a7
diff --git a/libarchive/archive_string.c b/libarchive/archive_string.c
f485a7
index 5ae09b6..d7541dc 100644
f485a7
--- a/libarchive/archive_string.c
f485a7
+++ b/libarchive/archive_string.c
f485a7
@@ -590,7 +590,7 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest,
f485a7
 	 * No single byte will be more than one wide character,
f485a7
 	 * so this length estimate will always be big enough.
f485a7
 	 */
f485a7
-	size_t wcs_length = len;
f485a7
+	//size_t wcs_length = len;
f485a7
 	size_t mbs_length = len;
f485a7
 	const char *mbs = p;
f485a7
 	wchar_t *wcs;
f485a7
@@ -599,7 +599,11 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest,
f485a7
 
f485a7
 	memset(&shift_state, 0, sizeof(shift_state));
f485a7
 #endif
f485a7
-	if (NULL == archive_wstring_ensure(dest, dest->length + wcs_length + 1))
f485a7
+	/*
f485a7
+	 * As we decided to have wcs_length == mbs_length == len
f485a7
+	 * we can use len here instead of wcs_length
f485a7
+	 */
f485a7
+	if (NULL == archive_wstring_ensure(dest, dest->length + len + 1))
f485a7
 		return (-1);
f485a7
 	wcs = dest->s + dest->length;
f485a7
 	/*
f485a7
@@ -608,6 +612,12 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest,
f485a7
 	 * multi bytes.
f485a7
 	 */
f485a7
 	while (*mbs && mbs_length > 0) {
f485a7
+		/*
f485a7
+		 * The buffer we allocated is always big enough.
f485a7
+		 * Keep this code path in a comment if we decide to choose
f485a7
+		 * smaller wcs_length in the future
f485a7
+		 */
f485a7
+/*
f485a7
 		if (wcs_length == 0) {
f485a7
 			dest->length = wcs - dest->s;
f485a7
 			dest->s[dest->length] = L'\0';
f485a7
@@ -617,24 +627,20 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest,
f485a7
 				return (-1);
f485a7
 			wcs = dest->s + dest->length;
f485a7
 		}
f485a7
+*/
f485a7
 #if HAVE_MBRTOWC
f485a7
-		r = mbrtowc(wcs, mbs, wcs_length, &shift_state);
f485a7
+		r = mbrtowc(wcs, mbs, mbs_length, &shift_state);
f485a7
 #else
f485a7
-		r = mbtowc(wcs, mbs, wcs_length);
f485a7
+		r = mbtowc(wcs, mbs, mbs_length);
f485a7
 #endif
f485a7
 		if (r == (size_t)-1 || r == (size_t)-2) {
f485a7
 			ret_val = -1;
f485a7
-			if (errno == EILSEQ) {
f485a7
-				++mbs;
f485a7
-				--mbs_length;
f485a7
-				continue;
f485a7
-			} else
f485a7
-				break;
f485a7
+			break;
f485a7
 		}
f485a7
 		if (r == 0 || r > mbs_length)
f485a7
 			break;
f485a7
 		wcs++;
f485a7
-		wcs_length--;
f485a7
+		//wcs_length--;
f485a7
 		mbs += r;
f485a7
 		mbs_length -= r;
f485a7
 	}
f485a7
-- 
f485a7
2.24.1
f485a7