|
|
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 |
|