Bug #78630 [Opn]: PHP 7.3 preg_match(): JIT compilation failed: no more memory (need pcre.jit=0)

From: Date: Fri, 04 Oct 2019 12:11:25 +0000
Subject: Bug #78630 [Opn]: PHP 7.3 preg_match(): JIT compilation failed: no more memory (need pcre.jit=0)
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-223070@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=78630&edit=1 ID: 78630 Updated by: nikic@php.net Reported by: ilya at ilya dot pp dot ua Summary: PHP 7.3 preg_match(): JIT compilation failed: no more memory (need pcre.jit=0) Status: Open Type: Bug Package: PCRE related Operating System: openSUSE Tumbleweed PHP Version: 7.3.10 Block user comment: N Private report: N New Comment: Okay, so taking the information from here and the discussions on https://bugs.exim.org/show_bug.cgi?id=1749 and https://bugs.exim.org/show_bug.cgi?id=2445, I think my two main conclusions would be: * For opensuse: Stop building pcre with --enable-sealloc. This option has a number of issues (including: not fork-safe, may segfault on disk space exhaustion and from this bug: may fail if tmpfs is noexec -- possibly others). The documentation was recently adjusted to label this as "experimental" and based on the discussions, I get the impression that the use is discouraged. Instead either a) the use of PCRE JIT should be disabled or b) the use of W+X should be enabled in SELinux or whatever other security mechanism is in use. * For PHP: We should consider implementing an automatic fallback in case pcre2_jit_compile() fails with PCRE2_ERROR_NOMEMORY. In this case we could assume that this is due to mmap permission issues and disable the PCRE JIT. It would still be good to understand what exactly the difference between PHP 7.2 and PHP 7.3 is. Here is what I know: The ProtExec allocator only exists since PCRE2 (PHP 7.3), so clearly as far as opensuse is concerned, this is the issue. However, bugreports at gmail dot com mentions that PCRE JIT used to work even with MemoryDenyWriteExecute=yes, which seems quite odd to me, because PCRE1 definitely uses WX mappings. My suspicion is that there is some automatic fallback from JIT to non-JIT going on in PHP 7.2 that does not happen in PHP 7.3 @bugreports at gmail dot com: Could you also provide an strace log for PHP 7.2 with MemoryDenyWriteExecute=yes and pcre.jit=1? I'm wondering what the mmap() return value will be for that case. Previous Comments: ------------------------------------------------------------------------ [2019-10-04 12:11:20] ilya at ilya dot pp dot ua I do not agree with this decision. "/tmp" and "/var/tmp" for security reasons should not contain any devices and executable files. This is a longstanding server setup practice. For dynamic things, "/run" exists and similar things should happen in it. ------------------------------------------------------------------------ [2019-10-04 11:58:18] bugreports at gmail dot com > You can't use the JIT compiler if your /tmp directory > (wherever it may be mounted) is noexec can't be entirely true /dev/sdd2 on /tmp type ext4 (rw,noexec,relatime,lazytime,commit=30) pcre.jit = 1 no problem from PHP 7.0.x up to 7.2.24-dev over years combined with "MemoryDenyWriteExecute=yes" in the systemd unit for at least a year ------------------------------------------------------------------------ [2019-10-04 11:54:05] build+suse at de-korte dot org You can't use the JIT compiler if your /tmp directory (wherever it may be mounted) is noexec. You basically want your PHP process to dynamically generate executable code, but disallow executing it. That doesn't fly. This is probably documented somewhere, but I don't have the time to find where. In your case, if you choose to mount your /tmp noexec, your need to set 'pcre.jit = 0', but this is by no means a default openSUSE Tumbleweed setup. ------------------------------------------------------------------------ [2019-10-04 11:12:55] ilya at ilya dot pp dot ua Thank you! sudo strace -o strace-preg_match.log php -r "preg_match('/^[\w.-]+@[\w.-]+\.\w{2,}$/','ilya@ilya.pp.ua');" https://bugzilla.suse.com/attachment.cgi?id=820544 ------------------------------------------------------------------------ [2019-10-04 11:05:39] ilya at ilya dot pp dot ua Of course with noexec! sudo cat /etc/fstab /swap none swap defaults 0 0 UUID=b996e925-3e85-4970-ac69-9c8250989666 / ext4 noatime,acl,user_xattr 1 1 UUID=a8050355-3331-4c81-8cc9-104a8b1632b6 /ILYA ext4 noatime 1 2 tmpfs /tmp tmpfs nodev,nosuid,noexec,size=2G 0 0 tmpfs /var/tmp tmpfs nodev,nosuid,noexec,size=2G 0 0 tmpfs /var/cache/zypp tmpfs nodev,nosuid,noexec,mode=0755,size=2G 0 0 tmpfs /run tmpfs nodev,nosuid,noexec,mode=0755,size=32m 0 0 tmpfs /run/lock tmpfs nodev,nosuid,noexec,mode=0755,size=8m 0 0 tmpfs /root/.cache tmpfs nodev,nosuid,noexec,mode=0700,size=2G 0 0 tmpfs /home/ilya/.cache tmpfs nodev,nosuid,noexec,mode=0700,uid=1000,size=2G 0 0 tmpfs /var/lib/wwwrun/.cache tmpfs nodev,nosuid,noexec,mode=0700,uid=30,size=2G 0 0 ------------------------------------------------------------------------ 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=78630 -- Edit this bug report at https://bugs.php.net/bug.php?id=78630&edit=1

« previous php.bugs (#223070) next »