Commit | Line | Data |
---|---|---|
ccda7c83 LF |
1 | Fixes CVE-2016-3191 (remote execution of arbitrary code or denial of |
2 | service (stack-based buffer overflow) via a crafted regular expression). | |
3 | ||
4 | See <https://bugzilla.redhat.com/show_bug.cgi?id=1311503>. | |
5 | ||
6 | This is svn r489 at <svn://vcs.exim.org/pcre2/code>, omitting the | |
7 | changes to 'testdata/testoutput8-16-4', which does not exist in the | |
8 | source tarball. | |
9 | ||
10 | git-svn-id: svn://vcs.exim.org/pcre2/code/trunk@489 6239d852-aaf2-0410-a92c-79f79f948069 | |
11 | --- | |
12 | ChangeLog | 4 ++++ | |
13 | src/pcre2_compile.c | 16 ++++++++++++++-- | |
14 | testdata/testinput8 | 2 ++ | |
15 | testdata/testoutput8-16-2 | 3 +++ | |
16 | testdata/testoutput8-16-3 | 3 +++ | |
17 | testdata/testoutput8-16-4 | 3 +++ | |
18 | testdata/testoutput8-32-2 | 3 +++ | |
19 | testdata/testoutput8-32-3 | 3 +++ | |
20 | testdata/testoutput8-32-4 | 3 +++ | |
21 | testdata/testoutput8-8-2 | 3 +++ | |
22 | testdata/testoutput8-8-3 | 3 +++ | |
23 | testdata/testoutput8-8-4 | 3 +++ | |
24 | 12 files changed, 47 insertions(+), 2 deletions(-) | |
25 | ||
26 | diff --git a/ChangeLog b/ChangeLog | |
27 | index 3ce0207..65e333e 100644 | |
28 | --- a/ChangeLog | |
29 | +++ b/ChangeLog | |
30 | @@ -58,6 +58,10 @@ some head-scratching the next time this happens. | |
31 | assertion, caused pcre2test to output a very large number of spaces when the | |
32 | callout was taken, making the program appearing to loop. | |
33 | ||
34 | +12. A pattern that included (*ACCEPT) in the middle of a sufficiently deeply | |
35 | +nested set of parentheses of sufficient size caused an overflow of the | |
36 | +compiling workspace (which was diagnosed, but of course is not desirable). | |
37 | + | |
38 | ||
39 | Version 10.21 12-January-2016 | |
40 | ----------------------------- | |
41 | diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c | |
42 | index e33d620..887fbfd 100644 | |
43 | --- a/src/pcre2_compile.c | |
44 | +++ b/src/pcre2_compile.c | |
45 | @@ -5901,10 +5901,22 @@ for (;; ptr++) | |
46 | goto FAILED; | |
47 | } | |
48 | cb->had_accept = TRUE; | |
49 | + | |
50 | + /* In the first pass, just accumulate the length required; | |
51 | + otherwise hitting (*ACCEPT) inside many nested parentheses can | |
52 | + cause workspace overflow. */ | |
53 | + | |
54 | for (oc = cb->open_caps; oc != NULL; oc = oc->next) | |
55 | { | |
56 | - *code++ = OP_CLOSE; | |
57 | - PUT2INC(code, 0, oc->number); | |
58 | + if (lengthptr != NULL) | |
59 | + { | |
60 | + *lengthptr += CU2BYTES(1) + IMM2_SIZE; | |
61 | + } | |
62 | + else | |
63 | + { | |
64 | + *code++ = OP_CLOSE; | |
65 | + PUT2INC(code, 0, oc->number); | |
66 | + } | |
67 | } | |
68 | setverb = *code++ = | |
69 | (cb->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT; | |
70 | diff --git a/testdata/testinput8 b/testdata/testinput8 | |
71 | index ca3b1b9..7e2a1f0 100644 | |
72 | --- a/testdata/testinput8 | |
73 | +++ b/testdata/testinput8 | |
74 | @@ -182,4 +182,6 @@ | |
75 | ||
76 | /((?1)(?2)(?3)(?4)(?5)(?6)(?7)(?8)(?9)(?9)(?8)(?7)(?6)(?5)(?4)(?3)(?2)(?1)(?0)){2,}()()()()()()()()()/debug | |
77 | ||
78 | +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ | |
79 | + | |
80 | # End of testinput8 | |
81 | diff --git a/testdata/testoutput8-16-2 b/testdata/testoutput8-16-2 | |
82 | index 05669bb..a5e8dec 100644 | |
83 | --- a/testdata/testoutput8-16-2 | |
84 | +++ b/testdata/testoutput8-16-2 | |
85 | @@ -1027,4 +1027,7 @@ Capturing subpattern count = 10 | |
86 | May match empty string | |
87 | Subject length lower bound = 0 | |
88 | ||
89 | +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ | |
90 | +Failed: error 186 at offset 490: regular expression is too complicated | |
91 | + | |
92 | # End of testinput8 | |
93 | diff --git a/testdata/testoutput8-16-3 b/testdata/testoutput8-16-3 | |
94 | index 31884e1..36133b3 100644 | |
95 | --- a/testdata/testoutput8-16-3 | |
96 | +++ b/testdata/testoutput8-16-3 | |
97 | @@ -1023,4 +1023,7 @@ Capturing subpattern count = 10 | |
98 | May match empty string | |
99 | Subject length lower bound = 0 | |
100 | ||
101 | +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ | |
102 | +Failed: error 114 at offset 509: missing closing parenthesis | |
103 | + | |
104 | # End of testinput8 | |
105 | diff --git a/testdata/testoutput8-32-2 b/testdata/testoutput8-32-2 | |
106 | index babd0c7..99c4fad 100644 | |
107 | --- a/testdata/testoutput8-32-2 | |
108 | +++ b/testdata/testoutput8-32-2 | |
109 | @@ -1023,4 +1023,7 @@ Capturing subpattern count = 10 | |
110 | May match empty string | |
111 | Subject length lower bound = 0 | |
112 | ||
113 | +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ | |
114 | +Failed: error 114 at offset 509: missing closing parenthesis | |
115 | + | |
116 | # End of testinput8 | |
117 | diff --git a/testdata/testoutput8-32-3 b/testdata/testoutput8-32-3 | |
118 | index babd0c7..99c4fad 100644 | |
119 | --- a/testdata/testoutput8-32-3 | |
120 | +++ b/testdata/testoutput8-32-3 | |
121 | @@ -1023,4 +1023,7 @@ Capturing subpattern count = 10 | |
122 | May match empty string | |
123 | Subject length lower bound = 0 | |
124 | ||
125 | +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ | |
126 | +Failed: error 114 at offset 509: missing closing parenthesis | |
127 | + | |
128 | # End of testinput8 | |
129 | diff --git a/testdata/testoutput8-32-4 b/testdata/testoutput8-32-4 | |
130 | index babd0c7..99c4fad 100644 | |
131 | --- a/testdata/testoutput8-32-4 | |
132 | +++ b/testdata/testoutput8-32-4 | |
133 | @@ -1023,4 +1023,7 @@ Capturing subpattern count = 10 | |
134 | May match empty string | |
135 | Subject length lower bound = 0 | |
136 | ||
137 | +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ | |
138 | +Failed: error 114 at offset 509: missing closing parenthesis | |
139 | + | |
140 | # End of testinput8 | |
141 | diff --git a/testdata/testoutput8-8-2 b/testdata/testoutput8-8-2 | |
142 | index 6a9aa0a..6dc1f42 100644 | |
143 | --- a/testdata/testoutput8-8-2 | |
144 | +++ b/testdata/testoutput8-8-2 | |
145 | @@ -1026,4 +1026,7 @@ Capturing subpattern count = 10 | |
146 | May match empty string | |
147 | Subject length lower bound = 0 | |
148 | ||
149 | +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ | |
150 | +Failed: error 114 at offset 509: missing closing parenthesis | |
151 | + | |
152 | # End of testinput8 | |
153 | diff --git a/testdata/testoutput8-8-3 b/testdata/testoutput8-8-3 | |
154 | index 2fe1168..ae14946 100644 | |
155 | --- a/testdata/testoutput8-8-3 | |
156 | +++ b/testdata/testoutput8-8-3 | |
157 | @@ -1024,4 +1024,7 @@ Capturing subpattern count = 10 | |
158 | May match empty string | |
159 | Subject length lower bound = 0 | |
160 | ||
161 | +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ | |
162 | +Failed: error 114 at offset 509: missing closing parenthesis | |
163 | + | |
164 | # End of testinput8 | |
165 | diff --git a/testdata/testoutput8-8-4 b/testdata/testoutput8-8-4 | |
166 | index 91993b2..6c79956 100644 | |
167 | --- a/testdata/testoutput8-8-4 | |
168 | +++ b/testdata/testoutput8-8-4 | |
169 | @@ -1022,4 +1022,7 @@ Capturing subpattern count = 10 | |
170 | May match empty string | |
171 | Subject length lower bound = 0 | |
172 | ||
173 | +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ | |
174 | +Failed: error 114 at offset 509: missing closing parenthesis | |
175 | + | |
176 | # End of testinput8 | |
177 | -- | |
178 | 2.8.3 | |
179 |