Fixes CVE-2016-3191 (remote execution of arbitrary code or denial of service (stack-based buffer overflow) via a crafted regular expression). See . This is svn r489 at , omitting the changes to 'testdata/testoutput8-16-4', which does not exist in the source tarball. git-svn-id: svn://vcs.exim.org/pcre2/code/trunk@489 6239d852-aaf2-0410-a92c-79f79f948069 --- ChangeLog | 4 ++++ src/pcre2_compile.c | 16 ++++++++++++++-- testdata/testinput8 | 2 ++ testdata/testoutput8-16-2 | 3 +++ testdata/testoutput8-16-3 | 3 +++ testdata/testoutput8-16-4 | 3 +++ testdata/testoutput8-32-2 | 3 +++ testdata/testoutput8-32-3 | 3 +++ testdata/testoutput8-32-4 | 3 +++ testdata/testoutput8-8-2 | 3 +++ testdata/testoutput8-8-3 | 3 +++ testdata/testoutput8-8-4 | 3 +++ 12 files changed, 47 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3ce0207..65e333e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -58,6 +58,10 @@ some head-scratching the next time this happens. assertion, caused pcre2test to output a very large number of spaces when the callout was taken, making the program appearing to loop. +12. A pattern that included (*ACCEPT) in the middle of a sufficiently deeply +nested set of parentheses of sufficient size caused an overflow of the +compiling workspace (which was diagnosed, but of course is not desirable). + Version 10.21 12-January-2016 ----------------------------- diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c index e33d620..887fbfd 100644 --- a/src/pcre2_compile.c +++ b/src/pcre2_compile.c @@ -5901,10 +5901,22 @@ for (;; ptr++) goto FAILED; } cb->had_accept = TRUE; + + /* In the first pass, just accumulate the length required; + otherwise hitting (*ACCEPT) inside many nested parentheses can + cause workspace overflow. */ + for (oc = cb->open_caps; oc != NULL; oc = oc->next) { - *code++ = OP_CLOSE; - PUT2INC(code, 0, oc->number); + if (lengthptr != NULL) + { + *lengthptr += CU2BYTES(1) + IMM2_SIZE; + } + else + { + *code++ = OP_CLOSE; + PUT2INC(code, 0, oc->number); + } } setverb = *code++ = (cb->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT; diff --git a/testdata/testinput8 b/testdata/testinput8 index ca3b1b9..7e2a1f0 100644 --- a/testdata/testinput8 +++ b/testdata/testinput8 @@ -182,4 +182,6 @@ /((?1)(?2)(?3)(?4)(?5)(?6)(?7)(?8)(?9)(?9)(?8)(?7)(?6)(?5)(?4)(?3)(?2)(?1)(?0)){2,}()()()()()()()()()/debug +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([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)/ + # End of testinput8 diff --git a/testdata/testoutput8-16-2 b/testdata/testoutput8-16-2 index 05669bb..a5e8dec 100644 --- a/testdata/testoutput8-16-2 +++ b/testdata/testoutput8-16-2 @@ -1027,4 +1027,7 @@ Capturing subpattern count = 10 May match empty string Subject length lower bound = 0 +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([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)/ +Failed: error 186 at offset 490: regular expression is too complicated + # End of testinput8 diff --git a/testdata/testoutput8-16-3 b/testdata/testoutput8-16-3 index 31884e1..36133b3 100644 --- a/testdata/testoutput8-16-3 +++ b/testdata/testoutput8-16-3 @@ -1023,4 +1023,7 @@ Capturing subpattern count = 10 May match empty string Subject length lower bound = 0 +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([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)/ +Failed: error 114 at offset 509: missing closing parenthesis + # End of testinput8 diff --git a/testdata/testoutput8-32-2 b/testdata/testoutput8-32-2 index babd0c7..99c4fad 100644 --- a/testdata/testoutput8-32-2 +++ b/testdata/testoutput8-32-2 @@ -1023,4 +1023,7 @@ Capturing subpattern count = 10 May match empty string Subject length lower bound = 0 +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([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)/ +Failed: error 114 at offset 509: missing closing parenthesis + # End of testinput8 diff --git a/testdata/testoutput8-32-3 b/testdata/testoutput8-32-3 index babd0c7..99c4fad 100644 --- a/testdata/testoutput8-32-3 +++ b/testdata/testoutput8-32-3 @@ -1023,4 +1023,7 @@ Capturing subpattern count = 10 May match empty string Subject length lower bound = 0 +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([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)/ +Failed: error 114 at offset 509: missing closing parenthesis + # End of testinput8 diff --git a/testdata/testoutput8-32-4 b/testdata/testoutput8-32-4 index babd0c7..99c4fad 100644 --- a/testdata/testoutput8-32-4 +++ b/testdata/testoutput8-32-4 @@ -1023,4 +1023,7 @@ Capturing subpattern count = 10 May match empty string Subject length lower bound = 0 +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([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)/ +Failed: error 114 at offset 509: missing closing parenthesis + # End of testinput8 diff --git a/testdata/testoutput8-8-2 b/testdata/testoutput8-8-2 index 6a9aa0a..6dc1f42 100644 --- a/testdata/testoutput8-8-2 +++ b/testdata/testoutput8-8-2 @@ -1026,4 +1026,7 @@ Capturing subpattern count = 10 May match empty string Subject length lower bound = 0 +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([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)/ +Failed: error 114 at offset 509: missing closing parenthesis + # End of testinput8 diff --git a/testdata/testoutput8-8-3 b/testdata/testoutput8-8-3 index 2fe1168..ae14946 100644 --- a/testdata/testoutput8-8-3 +++ b/testdata/testoutput8-8-3 @@ -1024,4 +1024,7 @@ Capturing subpattern count = 10 May match empty string Subject length lower bound = 0 +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([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)/ +Failed: error 114 at offset 509: missing closing parenthesis + # End of testinput8 diff --git a/testdata/testoutput8-8-4 b/testdata/testoutput8-8-4 index 91993b2..6c79956 100644 --- a/testdata/testoutput8-8-4 +++ b/testdata/testoutput8-8-4 @@ -1022,4 +1022,7 @@ Capturing subpattern count = 10 May match empty string Subject length lower bound = 0 +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([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)/ +Failed: error 114 at offset 509: missing closing parenthesis + # End of testinput8 -- 2.8.3