Bug #78927 [Opn]: Crash in pcre2_code_free_8, zend_hash_destroy

From: Date: Tue, 10 Dec 2019 20:19:06 +0000
Subject: Bug #78927 [Opn]: Crash in pcre2_code_free_8, zend_hash_destroy
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-224210@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=78927&edit=1

 ID:                 78927
 Updated by:         nikic@php.net
 Reported by:        xnoreq at gmail dot com
 Summary:            Crash in pcre2_code_free_8, zend_hash_destroy
 Status:             Open
 Type:               Bug
 Package:            Reproducible crash
 Operating System:   Linux 5.3.11
 PHP Version:        7.4.0
 Block user comment: N
 Private report:     N

 New Comment:

> It looks like the change was made to fix the incompatibility with the new
> MemoryDenyWriteExecute=true in the php-fpm.service.
>
> As I wrote, this does not seem like the right solution to me. Instead, Arch should either
> change php.ini to disable pcre.jit by default or patch the service file to disable
> MemoryDenyWriteExecute by default.

If this was just done to satisfy the php-fpm.service definition: MemoryDenyWriteExecute=true was
enabled by mistake there, and this has been reverted by https://github.com/php/php-src/commit/67cd4271e922ee3082b416a7563598274d13a1e5
in the meantime (part of 7.4.1).


Previous Comments:
------------------------------------------------------------------------
[2019-12-10 20:13:30] xnoreq at gmail dot com

Thanks, I have recompiled pcre2 without --enable-sealloc and now there are no more crashes.

I have also created a bug report in Arch Linux's bug tracker:
https://bugs.archlinux.org/task/64799

It looks like the change was made to fix the incompatibility with the new
MemoryDenyWriteExecute=true in the php-fpm.service.

As I wrote, this does not seem like the right solution to me. Instead, Arch should either change
php.ini to disable pcre.jit by default or patch the service file to disable MemoryDenyWriteExecute
by default.

------------------------------------------------------------------------
[2019-12-10 08:22:05] nikic@php.net

The --enable-sealloc flag is passed when building libpcre2 rather than PHP. Looking through the
repository you linked, it seems that they indeed use this flag: https://git.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=packages/pcre2#n31

This compilation option is known to be incompatible with fork(), causes a range of other issues, and
its use is discouraged by PCRE upstream. If you can, please petition ArchLinux to remove this flag
and instead properly grant JIT permissions (W+X mmap) to programs that use PCRE JIT.

Some references for issues this has caused:
https://bugs.php.net/bug.php?id=78630 (tmp
mounted noexec)
https://bugs.exim.org/show_bug.cgi?id=1749
(the fork issue is mentioned here)
https://bugs.exim.org/show_bug.cgi?id=2445
(breaks under low disk conditions)

What isn't clear to me is why you're seeing this issue only on PHP 7.4, as it principally
should affect PHP 7.3 (also using PCRE2) as well.

For now, you can work around this issue by setting pcre.jit=0 for the script that uses forking.

------------------------------------------------------------------------
[2019-12-09 23:47:36] xnoreq at gmail dot com

Here's a simple test-case to reproduce the issue:

$ php -f test.php

test.php:
<?php
function regex() {
        preg_match('/(foo)(bar)(baz)/', 'foobarbaz', $matches,
PREG_OFFSET_CAPTURE);
}

regex();

$pid = pcntl_fork();
if ($pid == -1) {
        die('error.');
}
else if ($pid) {
        echo 'parent... ';
        pcntl_wait($pid);
        echo 'wait done';
}
else {
        echo 'child.';
}
?>

------------------------------------------------------------------------
[2019-12-09 23:39:41] xnoreq at gmail dot com

I was using 7.3.12 before.

You can find the build files and patches here:
https://git.archlinux.org/svntogit/packages.git/tree/repos/extra-x86_64?h=packages/php

There's no --enable-sealloc option.

------------------------------------------------------------------------
[2019-12-09 21:16:23] nikic@php.net

Thanks, the trace makes much more sense with this being a cli executable.

fork() in most cases shouldn't matter, but here there might be a possible interference with the
JIT mapped memory used by PCRE.

Which Linux distro are you using and do you know how they build their PCRE binaries? If they are
using --enable-sealloc, then this may indeed be incompatible with fork().

Which PHP version did you use before the upgrade? PHP 7.3 or something older?

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=78927


--
Edit this bug report at https://bugs.php.net/bug.php?id=78927&edit=1


Thread (11 messages)

« previous php.bugs (#224210) next »