1 |
jpp |
1.1 |
From 6c2128928b93902d4af154a954ffa383591feba4 Mon Sep 17 00:00:00 2001 |
2 |
|
|
From: Tim Kientzle <kientzle@acm.org> |
3 |
|
|
Date: Sat, 7 Feb 2015 12:59:39 -0800 |
4 |
|
|
Subject: [PATCH] Issue 404: Read past end of string parsing fflags |
5 |
|
|
|
6 |
|
|
-- |
7 |
|
|
|
8 |
|
|
Correct the spelling of 'wcscmp'. |
9 |
|
|
|
10 |
|
|
-- |
11 |
|
|
|
12 |
|
|
A correct fix for Issue 404: Read past end of string parsing fflags |
13 |
|
|
|
14 |
|
|
The previous fix actually broke the fflag parsing. We |
15 |
|
|
cannot use strcmp() here because we're comparing a null-terminated |
16 |
|
|
string to a part of another string. |
17 |
|
|
|
18 |
|
|
This fix explicitly tracks the various string lengths and |
19 |
|
|
checks that they match before calling memcmp() or wmemcmp(). |
20 |
|
|
That avoids any buffer overrun without breaking the parser. |
21 |
|
|
|
22 |
|
|
-- |
23 |
|
|
Generated from commits: 1cbc76faff 05a875fdb8 90632371f |
24 |
|
|
--- |
25 |
|
|
libarchive/archive_entry.c | 18 ++++++++++++------ |
26 |
|
|
1 file changed, 12 insertions(+), 6 deletions(-) |
27 |
|
|
|
28 |
|
|
diff --git a/libarchive/archive_entry.c b/libarchive/archive_entry.c |
29 |
|
|
index 7958a17..787d281 100644 |
30 |
|
|
--- a/libarchive/archive_entry.c |
31 |
|
|
+++ b/libarchive/archive_entry.c |
32 |
|
|
@@ -1744,14 +1744,17 @@ ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp) |
33 |
|
|
while (*end != '\0' && *end != '\t' && |
34 |
|
|
*end != ' ' && *end != ',') |
35 |
|
|
end++; |
36 |
|
|
+ size_t length = end - start; |
37 |
|
|
for (flag = flags; flag->name != NULL; flag++) { |
38 |
|
|
- if (memcmp(start, flag->name, end - start) == 0) { |
39 |
|
|
+ size_t flag_length = strlen(flag->name); |
40 |
|
|
+ if (length == flag_length |
41 |
|
|
+ && memcmp(start, flag->name, length) == 0) { |
42 |
|
|
/* Matched "noXXXX", so reverse the sense. */ |
43 |
|
|
clear |= flag->set; |
44 |
|
|
set |= flag->clear; |
45 |
|
|
break; |
46 |
|
|
- } else if (memcmp(start, flag->name + 2, end - start) |
47 |
|
|
- == 0) { |
48 |
|
|
+ } else if (length == flag_length - 2 |
49 |
|
|
+ && memcmp(start, flag->name + 2, length) == 0) { |
50 |
|
|
/* Matched "XXXX", so don't reverse. */ |
51 |
|
|
set |= flag->set; |
52 |
|
|
clear |= flag->clear; |
53 |
|
|
@@ -1808,14 +1811,17 @@ ae_wcstofflags(const wchar_t *s, unsigned long *setp, unsigned long *clrp) |
54 |
|
|
while (*end != L'\0' && *end != L'\t' && |
55 |
|
|
*end != L' ' && *end != L',') |
56 |
|
|
end++; |
57 |
|
|
+ size_t length = end - start; |
58 |
|
|
for (flag = flags; flag->wname != NULL; flag++) { |
59 |
|
|
- if (wmemcmp(start, flag->wname, end - start) == 0) { |
60 |
|
|
+ size_t flag_length = wcslen(flag->wname); |
61 |
|
|
+ if (length == flag_length |
62 |
|
|
+ && wmemcmp(start, flag->wname, length) == 0) { |
63 |
|
|
/* Matched "noXXXX", so reverse the sense. */ |
64 |
|
|
clear |= flag->set; |
65 |
|
|
set |= flag->clear; |
66 |
|
|
break; |
67 |
|
|
- } else if (wmemcmp(start, flag->wname + 2, end - start) |
68 |
|
|
- == 0) { |
69 |
|
|
+ } else if (length == flag_length - 2 |
70 |
|
|
+ && wmemcmp(start, flag->wname + 2, length) == 0) { |
71 |
|
|
/* Matched "XXXX", so don't reverse. */ |
72 |
|
|
set |= flag->set; |
73 |
|
|
clear |= flag->clear; |
74 |
|
|
-- |
75 |
|
|
2.7.4 |
76 |
|
|
|