]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/pcre-8.37-Fix-buffer-overflow-for-named-references-in-situatio.patch
pakfire: use correct tree on x86_64.
[ipfire-2.x.git] / src / patches / pcre-8.37-Fix-buffer-overflow-for-named-references-in-situatio.patch
1 From b3f0b0dd971314df8f865e221aa1a88e75d6d1a6 Mon Sep 17 00:00:00 2001
2 From: ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>
3 Date: Wed, 5 Aug 2015 15:38:32 +0000
4 Subject: [PATCH] Fix buffer overflow for named references in (?| situations.
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 Ported for 8.37:
10
11 commit 7af8e8717def179fd7b69e173abd347c1a3547cb
12 Author: ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>
13 Date: Wed Aug 5 15:38:32 2015 +0000
14
15 Fix buffer overflow for named references in (?| situations.
16
17 git-svn-id: svn://vcs.exim.org/pcre/code/trunk@1585 2f5784b3-3f2a-0410-8824-cb99058d5e15
18
19 Signed-off-by: Petr Písař <ppisar@redhat.com>
20 ---
21 pcre_compile.c | 74 ++++++++++++++++++++++++++++++----------------------
22 pcre_internal.h | 1 +
23 testdata/testinput2 | 2 ++
24 testdata/testoutput2 | 2 ++
25 4 files changed, 48 insertions(+), 31 deletions(-)
26
27 diff --git a/pcre_compile.c b/pcre_compile.c
28 index f5d2384..5fe5c1d 100644
29 --- a/pcre_compile.c
30 +++ b/pcre_compile.c
31 @@ -6641,6 +6641,7 @@ for (;; ptr++)
32 /* ------------------------------------------------------------ */
33 case CHAR_VERTICAL_LINE: /* Reset capture count for each branch */
34 reset_bracount = TRUE;
35 + cd->dupgroups = TRUE; /* Record (?| encountered */
36 /* Fall through */
37
38 /* ------------------------------------------------------------ */
39 @@ -7151,7 +7152,8 @@ for (;; ptr++)
40 if (lengthptr != NULL)
41 {
42 named_group *ng;
43 -
44 + recno = 0;
45 +
46 if (namelen == 0)
47 {
48 *errorcodeptr = ERR62;
49 @@ -7168,32 +7170,6 @@ for (;; ptr++)
50 goto FAILED;
51 }
52
53 - /* The name table does not exist in the first pass; instead we must
54 - scan the list of names encountered so far in order to get the
55 - number. If the name is not found, set the value to 0 for a forward
56 - reference. */
57 -
58 - recno = 0;
59 - ng = cd->named_groups;
60 - for (i = 0; i < cd->names_found; i++, ng++)
61 - {
62 - if (namelen == ng->length &&
63 - STRNCMP_UC_UC(name, ng->name, namelen) == 0)
64 - {
65 - open_capitem *oc;
66 - recno = ng->number;
67 - if (is_recurse) break;
68 - for (oc = cd->open_caps; oc != NULL; oc = oc->next)
69 - {
70 - if (oc->number == recno)
71 - {
72 - oc->flag = TRUE;
73 - break;
74 - }
75 - }
76 - }
77 - }
78 -
79 /* Count named back references. */
80
81 if (!is_recurse) cd->namedrefcount++;
82 @@ -7215,7 +7191,44 @@ for (;; ptr++)
83 issue is fixed "properly" in PCRE2. As PCRE1 is now in maintenance
84 only mode, we finesse the bug by allowing more memory always. */
85
86 - /* if (recno == 0) */ *lengthptr += 2 + 2*LINK_SIZE;
87 + *lengthptr += 2 + 2*LINK_SIZE;
88 +
89 + /* It is even worse than that. The current reference may be to an
90 + existing named group with a different number (so apparently not
91 + recursive) but which later on is also attached to a group with the
92 + current number. This can only happen if $(| has been previous
93 + encountered. In that case, we allow yet more memory, just in case.
94 + (Again, this is fixed "properly" in PCRE2. */
95 +
96 + if (cd->dupgroups) *lengthptr += 2 + 2*LINK_SIZE;
97 +
98 + /* Otherwise, check for recursion here. The name table does not exist
99 + in the first pass; instead we must scan the list of names encountered
100 + so far in order to get the number. If the name is not found, leave
101 + the value of recno as 0 for a forward reference. */
102 +
103 + else
104 + {
105 + ng = cd->named_groups;
106 + for (i = 0; i < cd->names_found; i++, ng++)
107 + {
108 + if (namelen == ng->length &&
109 + STRNCMP_UC_UC(name, ng->name, namelen) == 0)
110 + {
111 + open_capitem *oc;
112 + recno = ng->number;
113 + if (is_recurse) break;
114 + for (oc = cd->open_caps; oc != NULL; oc = oc->next)
115 + {
116 + if (oc->number == recno)
117 + {
118 + oc->flag = TRUE;
119 + break;
120 + }
121 + }
122 + }
123 + }
124 + }
125 }
126
127 /* In the real compile, search the name table. We check the name
128 @@ -7262,8 +7275,6 @@ for (;; ptr++)
129 for (i++; i < cd->names_found; i++)
130 {
131 if (STRCMP_UC_UC(slot + IMM2_SIZE, cslot + IMM2_SIZE) != 0) break;
132 -
133 -
134 count++;
135 cslot += cd->name_entry_size;
136 }
137 @@ -9189,6 +9200,7 @@ cd->names_found = 0;
138 cd->name_entry_size = 0;
139 cd->name_table = NULL;
140 cd->dupnames = FALSE;
141 +cd->dupgroups = FALSE;
142 cd->namedrefcount = 0;
143 cd->start_code = cworkspace;
144 cd->hwm = cworkspace;
145 @@ -9223,7 +9235,7 @@ if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;
146
147 DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,
148 (int)(cd->hwm - cworkspace)));
149 -
150 +
151 if (length > MAX_PATTERN_SIZE)
152 {
153 errorcode = ERR20;
154 diff --git a/pcre_internal.h b/pcre_internal.h
155 index dd0ac7f..7ca6020 100644
156 --- a/pcre_internal.h
157 +++ b/pcre_internal.h
158 @@ -2446,6 +2446,7 @@ typedef struct compile_data {
159 BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */
160 BOOL check_lookbehind; /* Lookbehinds need later checking */
161 BOOL dupnames; /* Duplicate names exist */
162 + BOOL dupgroups; /* Duplicate groups exist: (?| found */
163 BOOL iscondassert; /* Next assert is a condition */
164 int nltype; /* Newline type */
165 int nllen; /* Newline string length */
166 diff --git a/testdata/testinput2 b/testdata/testinput2
167 index e12de3a..8e044f8 100644
168 --- a/testdata/testinput2
169 +++ b/testdata/testinput2
170 @@ -4158,4 +4158,6 @@ backtracking verbs. --/
171
172 "(?J:(?|(?'R')(\k'R')|((?'R'))))"
173
174 +/(?J:(?|(:(?|(?'R')(\k'R')|((?'R')))H'Rk'Rf)|s(?'R')))/
175 +
176 /-- End of testinput2 --/
177 diff --git a/testdata/testoutput2 b/testdata/testoutput2
178 index 5bad26c..6019425 100644
179 --- a/testdata/testoutput2
180 +++ b/testdata/testoutput2
181 @@ -14430,4 +14430,6 @@ Failed: unmatched parentheses at offset 23
182
183 "(?J:(?|(?'R')(\k'R')|((?'R'))))"
184
185 +/(?J:(?|(:(?|(?'R')(\k'R')|((?'R')))H'Rk'Rf)|s(?'R')))/
186 +
187 /-- End of testinput2 --/
188 --
189 2.4.3
190