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