Blame SOURCES/libarchive-3.1.2-CVE-2015-8921.patch

995285
From 6c2128928b93902d4af154a954ffa383591feba4 Mon Sep 17 00:00:00 2001
995285
From: Tim Kientzle <kientzle@acm.org>
995285
Date: Sat, 7 Feb 2015 12:59:39 -0800
995285
Subject: [PATCH] Issue 404: Read past end of string parsing fflags
995285
995285
--
995285
995285
Correct the spelling of 'wcscmp'.
995285
995285
--
995285
995285
A correct fix for Issue 404: Read past end of string parsing fflags
995285
995285
The previous fix actually broke the fflag parsing.  We
995285
cannot use strcmp() here because we're comparing a null-terminated
995285
string to a part of another string.
995285
995285
This fix explicitly tracks the various string lengths and
995285
checks that they match before calling memcmp() or wmemcmp().
995285
That avoids any buffer overrun without breaking the parser.
995285
995285
--
995285
Generated from commits: 1cbc76faff 05a875fdb8 90632371f
995285
---
995285
 libarchive/archive_entry.c | 18 ++++++++++++------
995285
 1 file changed, 12 insertions(+), 6 deletions(-)
995285
995285
diff --git a/libarchive/archive_entry.c b/libarchive/archive_entry.c
995285
index 7958a17..787d281 100644
995285
--- a/libarchive/archive_entry.c
995285
+++ b/libarchive/archive_entry.c
995285
@@ -1744,14 +1744,17 @@ ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
995285
 		while (*end != '\0'  &&  *end != '\t'  &&
995285
 		    *end != ' '  &&  *end != ',')
995285
 			end++;
995285
+		size_t length = end - start;
995285
 		for (flag = flags; flag->name != NULL; flag++) {
995285
-			if (memcmp(start, flag->name, end - start) == 0) {
995285
+			size_t flag_length = strlen(flag->name);
995285
+			if (length == flag_length
995285
+			    && memcmp(start, flag->name, length) == 0) {
995285
 				/* Matched "noXXXX", so reverse the sense. */
995285
 				clear |= flag->set;
995285
 				set |= flag->clear;
995285
 				break;
995285
-			} else if (memcmp(start, flag->name + 2, end - start)
995285
-			    == 0) {
995285
+			} else if (length == flag_length - 2
995285
+			    && memcmp(start, flag->name + 2, length) == 0) {
995285
 				/* Matched "XXXX", so don't reverse. */
995285
 				set |= flag->set;
995285
 				clear |= flag->clear;
995285
@@ -1808,14 +1811,17 @@ ae_wcstofflags(const wchar_t *s, unsigned long *setp, unsigned long *clrp)
995285
 		while (*end != L'\0'  &&  *end != L'\t'  &&
995285
 		    *end != L' '  &&  *end != L',')
995285
 			end++;
995285
+		size_t length = end - start;
995285
 		for (flag = flags; flag->wname != NULL; flag++) {
995285
-			if (wmemcmp(start, flag->wname, end - start) == 0) {
995285
+			size_t flag_length = wcslen(flag->wname);
995285
+			if (length == flag_length
995285
+			    && wmemcmp(start, flag->wname, length) == 0) {
995285
 				/* Matched "noXXXX", so reverse the sense. */
995285
 				clear |= flag->set;
995285
 				set |= flag->clear;
995285
 				break;
995285
-			} else if (wmemcmp(start, flag->wname + 2, end - start)
995285
-			    == 0) {
995285
+			} else if (length == flag_length - 2
995285
+			    && wmemcmp(start, flag->wname + 2, length) == 0) {
995285
 				/* Matched "XXXX", so don't reverse. */
995285
 				set |= flag->set;
995285
 				clear |= flag->clear;
995285
-- 
995285
2.7.4
995285