[Pcre-svn] [271] code/trunk: Fix buffer overflow for lookbeh…

Top Page
Delete this message
Author: Subversion repository
Date:  
To: pcre-svn
Subject: [Pcre-svn] [271] code/trunk: Fix buffer overflow for lookbehind with mutually recursive groups.
Revision: 271
          http://www.exim.org/viewvc/pcre2?view=rev&revision=271
Author:   ph10
Date:     2015-05-18 18:31:29 +0100 (Mon, 18 May 2015)
Log Message:
-----------
Fix buffer overflow for lookbehind with mutually recursive groups.


Modified Paths:
--------------
    code/trunk/ChangeLog
    code/trunk/src/pcre2_compile.c
    code/trunk/testdata/testinput2
    code/trunk/testdata/testoutput2


Modified: code/trunk/ChangeLog
===================================================================
--- code/trunk/ChangeLog    2015-05-17 17:44:21 UTC (rev 270)
+++ code/trunk/ChangeLog    2015-05-18 17:31:29 UTC (rev 271)
@@ -129,7 +129,10 @@
 32. Fix pcre2grep compile when -std=c99 is used with gcc, though it still gives 
 a warning for "fileno" unless -std=gnu99 us used.


+33. A lookbehind assertion within a set of mutually recursive subpatterns could
+provoke a buffer overflow. This bug was discovered by the LLVM fuzzer.

+
Version 10.10 06-March-2015
---------------------------


Modified: code/trunk/src/pcre2_compile.c
===================================================================
--- code/trunk/src/pcre2_compile.c    2015-05-17 17:44:21 UTC (rev 270)
+++ code/trunk/src/pcre2_compile.c    2015-05-18 17:31:29 UTC (rev 271)
@@ -886,7 +886,11 @@
     cc += 1 + LINK_SIZE;
     break;


-    /* Skip over assertive subpatterns */
+    /* Skip over assertive subpatterns. Note that we must increment cc by 
+    1 + LINK_SIZE at the end, not by OP_length[*cc] because in a recursive 
+    situation this assertion may be the one that is ultimately being checked 
+    for having a fixed length, in which case its terminating OP_KET will have
+    been temporarily replaced by OP_END. */


     case OP_ASSERT:
     case OP_ASSERT_NOT:
@@ -893,7 +897,7 @@
     case OP_ASSERTBACK:
     case OP_ASSERTBACK_NOT:
     do cc += GET(cc, 1); while (*cc == OP_ALT);
-    cc += PRIV(OP_lengths)[*cc];
+    cc += 1 + LINK_SIZE;
     break;


     /* Skip over things that don't match chars */
@@ -8143,7 +8147,9 @@
   /* Loop, searching for OP_REVERSE items, and process those that do not have
   their length set. (Actually, it will also re-process any that have a length
   of zero, but that is a pathological case, and it does no harm.) When we find
-  one, we temporarily terminate the branch it is in while we scan it. */
+  one, we temporarily terminate the branch it is in while we scan it. Note that 
+  calling find_bracket() with a negative group number returns a pointer to the
+  OP_REVERSE item, not the actual lookbehind. */


   for (cc = (PCRE2_UCHAR *)PRIV(find_bracket)(codestart, utf, -1);
        cc != NULL;


Modified: code/trunk/testdata/testinput2
===================================================================
--- code/trunk/testdata/testinput2    2015-05-17 17:44:21 UTC (rev 270)
+++ code/trunk/testdata/testinput2    2015-05-18 17:31:29 UTC (rev 271)
@@ -4306,4 +4306,6 @@


"(?J)(?'d'(?'d'\g{d}))"

+"(?=!((?2)(?))({8(?<=(?1){29}8bbbb\x16\xd\xc6^($(\xa9H4){4}h}?1)B))\x15')"
+
# End of testinput2

Modified: code/trunk/testdata/testoutput2
===================================================================
--- code/trunk/testdata/testoutput2    2015-05-17 17:44:21 UTC (rev 270)
+++ code/trunk/testdata/testoutput2    2015-05-18 17:31:29 UTC (rev 271)
@@ -14405,4 +14405,7 @@


"(?J)(?'d'(?'d'\g{d}))"

+"(?=!((?2)(?))({8(?<=(?1){29}8bbbb\x16\xd\xc6^($(\xa9H4){4}h}?1)B))\x15')"
+Failed: error 125 at offset 72: lookbehind assertion is not fixed length
+
# End of testinput2