Bug 1166147 (CVE-2014-8964)

Summary: CVE-2014-8964 pcre: incorrect handling of zero-repeat assertion conditions
Product: [Other] Security Response Reporter: Vasyl Kaigorodov <vkaigoro>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED ERRATA QA Contact:
Severity: low Docs Contact:
Priority: low    
Version: unspecifiedCC: adam.stokes, andrew, carnil, c.david86, erik-fedora, jorton, lkundrak, mmaslano, ppisar, rcollet, vondruch, vuvova, yselkowi
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: pcre 8.37 Doc Type: Bug Fix
Doc Text:
A flaw was found in the way PCRE handled certain malformed regular expressions. This issue could cause an application (for example, Konqueror) linked against PCRE to crash while parsing malicious regular expressions.
Story Points: ---
Clone Of: Environment:
Last Closed: 2021-10-20 10:47:40 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1165626, 1169797, 1177278    
Bug Blocks: 1166148    

Description Vasyl Kaigorodov 2014-11-20 13:17:00 UTC
Heap buffer overflow issue was reported in PCRE when processing a specially crafted regular expressions:
http://bugs.exim.org/show_bug.cgi?id=1546

Upstream patch for this:
http://www.exim.org/viewvc/pcre2?view=rev&revision=154

The next upstream release that will contain the above fix is likely to be around Feb/Mar next year (2015).

Comment 1 Vasyl Kaigorodov 2014-11-20 13:24:48 UTC
Original report along with the patch:
...
echo "a" | /tmp/pcre-8.36/pcregrep "((?=(?(?=(?(?=(?(?=())))*))))){2}" -
=================================================================
==29857==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x61000000fb94 at pc 0x7faf416f0dc6 bp 0x7fff9c91d3b0 sp 0x7fff9c91d3a8
READ of size 1 at 0x61000000fb94 thread T0
    #0 0x7faf416f0dc5 in match /tmp/pcre-8.36/pcre_exec.c:1410:9
    #1 0x7faf416dfe35 in match /tmp/pcre-8.36/pcre_exec.c:1538:7
    #2 0x7faf416e46de in match /tmp/pcre-8.36/pcre_exec.c:1399:7
    #3 0x7faf416dfe35 in match /tmp/pcre-8.36/pcre_exec.c:1538:7
    #4 0x7faf416ee260 in match /tmp/pcre-8.36/pcre_exec.c:983:9
    #5 0x7faf416dcd49 in pcre_exec /tmp/pcre-8.36/pcre_exec.c:6923:8
    #6 0x4a4580 in match_patterns /tmp/pcre-8.36/pcregrep.c:1449:10
    #7 0x4a13ca in pcregrep /tmp/pcre-8.36/pcregrep.c:1679:11
    #8 0x4a3624 in grep_or_recurse /tmp/pcre-8.36/pcregrep.c:2122:10
    #9 0x49efbf in main /tmp/pcre-8.36/pcregrep.c:3251:13
    #10 0x7faf405b7ec4 in __libc_start_main
/build/buildd/eglibc-2.19/csu/libc-start.c:287
    #11 0x4172a6 in _start (/tmp/pcre-8.36/.libs/lt-pcregrep+0x4172a6)

Upstream prepared a fix:

--- pcre_exec.c (revision 1512)
+++ pcre_exec.c (working copy)
@@ -1404,8 +1404,11 @@
         condition = TRUE;

         /* Advance ecode past the assertion to the start of the first branch,
-        but adjust it so that the general choosing code below works. */
-
+        but adjust it so that the general choosing code below works. If the 
+        assertion has a quantifier that allows zero repeats we must skip over 
+        the BRAZERO. This is a lunatic thing to do, but somebody did! */
+        
+        if (*ecode == OP_BRAZERO) ecode++; 
         ecode += GET(ecode, 1);
         while (*ecode == OP_ALT) ecode += GET(ecode, 1);
         ecode += 1 + LINK_SIZE - PRIV(OP_lengths)[condcode];

Comment 2 Petr Pisar 2014-11-20 13:27:48 UTC
I fixed it in Fedora 22 and 21. I cannot fix it in older Fedoras because the fix depends on another extensive change which I do not want to back-port. If you have different opinion we could try to involve the upstream, but I believe this is not necessary.

Comment 3 Vasyl Kaigorodov 2014-11-20 13:39:59 UTC
(In reply to Petr Pisar from comment #2)
> I fixed it in Fedora 22 and 21. I cannot fix it in older Fedoras because the
> fix depends on another extensive change which I do not want to back-port. If
> you have different opinion we could try to involve the upstream, but I
> believe this is not necessary.

Taking the Low impact - I would say it's not necessary.
Unless a real exploit is found for this I'd say let's leave it for now as it is.

Comment 4 Vasyl Kaigorodov 2014-11-20 14:56:27 UTC
CVE request: http://seclists.org/oss-sec/2014/q4/714

Comment 5 Martin Prpič 2014-11-21 09:07:43 UTC
CVE-2014-8964 was assigned to this issue:

http://seclists.org/oss-sec/2014/q4/746

Comment 6 Tomas Hoger 2014-12-01 11:56:07 UTC
(In reply to Vasyl Kaigorodov from comment #0)
> Upstream patch for this:
> http://www.exim.org/viewvc/pcre2?view=rev&revision=154

Upstream patch in pcre / pcre1 repository:
http://www.exim.org/viewvc/pcre?view=revision&revision=1513

Comment 7 Tomas Hoger 2014-12-01 20:46:21 UTC
The problem here is that malicious regular expression may cause an op code pointer to point outside of the buffer that holds compiled regular expression.  This happens because the unexpected OP_BRAZERO code makes pcre use the following code (OP_ASSERT in the regular expressions from the upstream bugs) as part of the value that indicate the number of bytes to advance the code pointer by.  In the worst case, pcre may end up interpreting malicious compiled regex op code.  While pcre seems to preform bounds checking when performing write operations while interpreting op code, it may be possible to (indirectly) disclose some portions of the process memory.

Comment 8 Tomas Hoger 2014-12-01 20:52:03 UTC
(In reply to Petr Pisar from comment #2)
> I fixed it in Fedora 22 and 21. I cannot fix it in older Fedoras because the
> fix depends on another extensive change which I do not want to back-port.

Isn't this equivalent change for PCRE 8.32?

--- pcre-8.32/pcre_exec.c.orig
+++ pcre-8.32/pcre_exec.c
@@ -1459,7 +1459,9 @@ for (;;)
         if (md->end_offset_top > offset_top)
           offset_top = md->end_offset_top;  /* Captures may have happened */
         condition = TRUE;
-        ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
+        ecode += 1 + LINK_SIZE;
+        if (*ecode == OP_BRAZERO) ecode++;
+        ecode += GET(ecode, 1);
         while (*ecode == OP_ALT) ecode += GET(ecode, 1);
         }
 
Code in the more recent PCRE versions increment ecode by 1 + LINK_SIZE earlier, near the beginning of the OP_COND / OP_SCOND case.

Comment 12 Petr Pisar 2014-12-02 12:06:22 UTC
(In reply to Tomas Hoger from comment #8)
> --- pcre-8.32/pcre_exec.c.orig
> +++ pcre-8.32/pcre_exec.c
> @@ -1459,7 +1459,9 @@ for (;;)
>          if (md->end_offset_top > offset_top)
>            offset_top = md->end_offset_top;  /* Captures may have happened */
>          condition = TRUE;
> -        ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
> +        ecode += 1 + LINK_SIZE;
> +        if (*ecode == OP_BRAZERO) ecode++;
> +        ecode += GET(ecode, 1);
>          while (*ecode == OP_ALT) ecode += GET(ecode, 1);
>          }
>  
> Code in the more recent PCRE versions increment ecode by 1 + LINK_SIZE
> earlier, near the beginning of the OP_COND / OP_SCOND case.

Great. That makes the trick. I will push it.

Comment 14 Fedora Update System 2014-12-12 04:16:06 UTC
pcre-8.35-8.fc21 has been pushed to the Fedora 21 stable repository.  If problems still persist, please make note of it in this bug report.

Comment 15 Fedora Update System 2014-12-19 18:27:18 UTC
pcre-8.32-12.fc19 has been pushed to the Fedora 19 stable repository.  If problems still persist, please make note of it in this bug report.

Comment 16 Fedora Update System 2014-12-19 18:28:58 UTC
pcre-8.33-8.fc20 has been pushed to the Fedora 20 stable repository.  If problems still persist, please make note of it in this bug report.

Comment 17 Yaakov Selkowitz 2014-12-24 17:54:18 UTC
Does this apply also to mingw-pcre?

Comment 18 Tomas Hoger 2014-12-25 16:11:45 UTC
(In reply to Yaakov Selkowitz from comment #17)
> Does this apply also to mingw-pcre?

It most likely does.  Versions 8.32 - 8.35 were confirmed as affected, mingw-pcre versions currently in Fedora are all within the range.

Comment 19 Tomas Hoger 2014-12-25 16:13:58 UTC
Created mingw-pcre tracking bugs for this issue:

Affects: fedora-all [bug 1177278]

Comment 21 errata-xmlrpc 2015-03-05 07:14:59 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 7

Via RHSA-2015:0330 https://rhn.redhat.com/errata/RHSA-2015-0330.html