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

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