php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78630 PHP 7.3 preg_match(): JIT compilation failed: no more memory (need pcre.jit=0)
Submitted: 2019-10-03 20:08 UTC Modified: 2019-10-07 11:32 UTC
From: ilya at ilya dot pp dot ua Assigned: nikic (profile)
Status: Closed Package: PCRE related
PHP Version: 7.3.10 OS: openSUSE Tumbleweed
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: ilya at ilya dot pp dot ua
New email:
PHP Version: OS:

 

 [2019-10-03 20:08 UTC] ilya at ilya dot pp dot ua
Description:
------------
https://bugzilla.suse.com/show_bug.cgi?id=1124446
In PHP 7.3 using pcre2 and using by default JIT compilation (pcre.jit=1)
This leads to errors on phpMyAdmin login page like:
Warning in ./libraries/classes/Config.php#201 preg_match(): JIT compilation failed: no more memory
mod_fcgid: stderr: PHP Warning:  preg_replace_callback(): JIT compilation failed: no more memory
And for everything that uses preg_*() functions.

php: 7.3.10
pcre2: 10.33
Server: Apache (mpm_event) + mod_fcgid + php-fastcgi
If necessary, I will attach more information.

Test script:
---------------
phpMyAdmin latest version (4.9.1) login page and show this page and apache error_log
Server: Apache (mpm_event) + mod_fcgid + php-fastcgi

Expected result:
----------------
No errors.

Actual result:
--------------
Error on phpMyAdmin login page
Warning in ./libraries/classes/Config.php#201 preg_match(): JIT compilation failed: no more memory
And in apache error_log
mod_fcgid: stderr: PHP Warning:  preg_replace_callback(): JIT compilation failed: no more memory


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-10-03 20:17 UTC] nikic@php.net
Do you know how opensuse builds pcre2? Do they use the bundled PHP library, or do they build a separate pcre2 library and link PHP against it? I'm assuming it's the latter.

Do you know if there is any security mechanism (such as SELinux) that might prevent the allocation of writable executable memory?

If such a mechanism exists and is enabled by default, is pcre2 being compiled with -DSLJIT_PROT_EXECUTABLE_ALLOCATOR=1, as is necessary to avoid W+X mmaps?

Finally, do you know whether the first preg_* call already fails, or are there any preg_* calls that succeed before the first failure?
 [2019-10-03 20:28 UTC] ilya at ilya dot pp dot ua
-Operating System: openSuse Tumbleweed +Operating System: openSUSE Tumbleweed
 [2019-10-03 20:28 UTC] ilya at ilya dot pp dot ua
> @nikic's two referenced commits are only for PHP 7.4.0rc3. @ilya, can you test with that version?

Problematically, openSUSE has many patches, and simply updating the source code will fail.
I asked the maintainer to build 7.4.0RC3, if he has time for this I will test.

> @ilya: It would be helpful to also provide an strace of the process, which should also show the mmap failure.

This is also problematic, I never used strace.
Can you give detailed instructions on how to do it?
 [2019-10-03 20:56 UTC] ilya at ilya dot pp dot ua
> Do you know how opensuse builds pcre2? Do they use the bundled PHP library, or do they build a separate pcre2 library and link PHP against it? I'm assuming it's the latter.

See, please, pcre2 project: https://build.opensuse.org/package/show/devel:libraries:c_c++/pcre2 (click on pcre2.spec file)
And see, please, php7 project: https://build.opensuse.org/package/show/devel:languages:php/php7

> Do you know if there is any security mechanism (such as SELinux) that might prevent the allocation of writable executable memory?

Judging by my installed packages, the system contains libapparmor and libselinux.
But whether they are actually used and how I do not know.

> If such a mechanism exists and is enabled by default, is pcre2 being compiled with -DSLJIT_PROT_EXECUTABLE_ALLOCATOR=1, as is necessary to avoid W+X mmaps?

https://build.opensuse.org/package/view_file/devel:libraries:c_c++/pcre2/pcre2.spec?expand=1
%configure \
%ifarch %{ix86} x86_64 %{arm} ppc ppc64 ppc64le mips sparc
	    --enable-jit \
        --enable-jit-sealloc \
%endif

Most probably not.
But you can always look at the current build log to be sure of this.
https://build.opensuse.org/build/devel:libraries:c_c++/openSUSE_Factory/x86_64/pcre2/_log

> Finally, do you know whether the first preg_* call already fails, or are there any preg_* calls that succeed before the first failure?

Not all. In my code, preg_match () is called once to check my email and it always causes an error.
 [2019-10-03 21:15 UTC] ilya at ilya dot pp dot ua
wget https://www.php.net/distributions/php-7.4.0RC3.tar.xz
... 404 Not a found
Give me please, correct link to dowload 7.4.0RC3
 [2019-10-03 21:33 UTC] nikic@php.net
Thanks for the information. As the PCRE2 build uses --enable-jit-sealloc (which sets SLJIT_PROT_EXECUTABLE_ALLOCATOR) and the PHP build uses the system PCRE2 build, this means that preg_* should end up using the ProtExec allocator, which is W^X compatible.

So the problem here might be the other way around, and the use of the ProtExec allocator is what causes the issue. Looking at recent pcre-dev posts, I saw the discussion in https://bugs.exim.org/show_bug.cgi?id=2445, which looks potentially relevant.
 [2019-10-04 07:49 UTC] build+suse at de-korte dot org
I'm running php-7.3.10 on openSUSE Tumbleweed too and see no problems with 'pcre.jit = 1' and phpMyAdmin. I too use the mpm_event and have an identical memory_limit (128M) for PHP as the reporter. I do run php-fpm through mod_proxy_fcgi though and not through mod_fcgid + php-fastcgi.

I think it is safe to assume that the problems the OP is seeing, is not going to be solved by upgrading to 7.4.0RC3.
 [2019-10-04 07:54 UTC] nikic@php.net
> This is also problematic, I never used strace.
> Can you give detailed instructions on how to do it?

Run "sudo strace -p PID", where PID is a php-fpm process ID and then access the phpmyadmin page. (Or possibly a php-fastcgi process ID, I have no idea what that is.)
 [2019-10-04 10:15 UTC] ilya at ilya dot pp dot ua
@nikic
Thank you, I did it.
Received strange results. At the first start (php processes do not exist yet), an error always appears, and moreover, when you refresh the php page once everything is fine, then again this error.
Attached strace output from both processes after an error.

https://bugzilla.suse.com/attachment.cgi?id=820531
https://bugzilla.suse.com/attachment.cgi?id=820532
 [2019-10-04 10:35 UTC] nikic@php.net
Thanks for the strace logs! The relevant part is:

openat(AT_FDCWD, "/tmp", O_RDWR|O_EXCL|O_NOATIME|O_CLOEXEC|O_TMPFILE, 0600) = 5
ftruncate(5, 65536)                     = 0
mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_SHARED, 5, 0) = 0x7f33788e9000
mmap(NULL, 65536, PROT_READ|PROT_EXEC, MAP_SHARED, 5, 0) = -1 EPERM (Операция не позволена)
munmap(0x7f33788e9000, 65536)           = 0
close(5)                                = 0

The PROT_READ|PROT_EXEC mmap fails with EPERM. Apart from the possibility of this being prevented by something like SELinux, the man page also lists two more possibilities:

       EPERM  The prot argument asks for PROT_EXEC but the mapped area
              belongs to a file on a filesystem that was mounted no-exec.

       EPERM  The operation was prevented by a file seal; see fcntl(2).

Could you check whether the /tmp filesystem might be mounted as noexec? (This should be visible in the output of "mount".)
 [2019-10-04 10:43 UTC] build+suse at de-korte dot org
Note that openSUSE Tumbleweed uses a private /tmp, which is mounted under /var/tmp/systemd-private-[lots of hex]-php-fpm.service-[more hex]/tmp. So if you have mounted your /var partition as no-exec, the private /tmp your PHP process is using will also be no-exec.
 [2019-10-04 10:59 UTC] bugreports at gmail dot com
> Note that openSUSE Tumbleweed uses a private /tmp, 
> which is mounted under /var/tmp/systemd-private...

this is not true!

PrivateTemp isolates /tmp and /var/tmp and so you have /tmp/systemd-private...
 [2019-10-04 10:59 UTC] ilya at ilya dot pp dot ua
I found a shorter and more reliable way to show the problem right from the console.
php -r "preg_match('/^[\w.-]+@[\w.-]+\.\w{2,}$/','ilya@ilya.pp.ua');"
PHP Warning:  preg_match(): JIT compilation failed: no more memory in Command line code on line 1
This code always gives an error no matter how much I run it.

But I don’t know how to execute it in such a way as to connect strace to it, because there is no process before the code execution ..., you can probably try sleep(30) &&.

And now I'm even more confused ...
php -r "preg_match('/^[\w.-]+@[\w.-]+\.\w{2,}$/','ilya@ilya.pp.ua');"
Always performed with an error!
php -r "sleep(30)&&preg_match('/^[\w.-]+@[\w.-]+\.\w{2,}$/','ilya@ilya.pp.ua');"
It always runs without error, so I put it strace You will not be interested.
Is there a way to connect strace without knowing the process number in advance?
 [2019-10-04 11:02 UTC] bugreports at gmail dot com
> But I don’t know how to execute it in such a way as to connect 
> strace to it, because there is no process before the code execution

that's the much easier case than attach a running process

strace php -r "preg_match('/^[\w.-]+@[\w.-]+\.\w{2,}$/','ilya@ilya.pp.ua');"

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

usage: strace [-ACdffhikqqrtttTvVwxxyyzZ] [-I n] [-b execve] [-e expr]...
              [-a column] [-o file] [-s strsize] [-X format] [-P path]...
              [-p pid]... [--seccomp-bpf]
              { -p pid | [-D] [-E var=val]... [-u username] PROG [ARGS] }
   or: strace -c[dfwzZ] [-I n] [-b execve] [-e expr]... [-O overhead]
              [-S sortby] [-P path]... [-p pid]... [--seccomp-bpf]
              { -p pid | [-D] [-E var=val]... [-u username] PROG [ARGS] }
 [2019-10-04 11:05 UTC] 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
 [2019-10-04 11:12 UTC] 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:54 UTC] 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:58 UTC] 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 12:11 UTC] 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 12:11 UTC] nikic@php.net
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.
 [2019-10-04 12:47 UTC] ilya at ilya dot pp dot ua
I shared my opinion in Exim.
I see the main problem in the fact that the JIT compiler uses the "/tmp" or "/var/tmp" directories instead of the "/run".
Correct me if I am wrong?
 [2019-10-04 12:49 UTC] bugreports at gmail dot com
sorry for beeing too dumb prevent loading extensions and reduce noise in the first try :-(

[root@localhost:~]$ systemd-run -p MemoryDenyWriteExecute=yes -t --quiet --wait strace php -d "pcre.jit=1" -n -r "preg_match('/^[\w.-]+@[\w.-]+\.\w{2,}$/','ilya@ilya.pp.ua');"   execve("/usr/bin/php", ["php", "-d", "pcre.jit=1", "-n", "-r", "preg_match('/^[\\w.-]+@[\\w.-]+\\.\\"...], 0x7ffeb5a5fe98 /* 6 vars */) = 0
brk(NULL)                               = 0x5572a1fe6000
brk(0x5572a1fe6026)                     = 0x5572a1fe6026
brk(NULL)                               = 0x5572a1fe6026
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffd29ad83b0) = -1 EINVAL (Invalid argument)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=83197, ...}) = 0
mmap(NULL, 83197, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f2cb110b000
close(3)                                = 0
openat(AT_FDCWD, "/lib64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0r\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=823192, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2cb1109000
lseek(3, 808, SEEK_SET)                 = 808
read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
mmap(NULL, 132288, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2cb10e8000
mmap(0x7f2cb10ee000, 61440, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x7f2cb10ee000
mmap(0x7f2cb10fd000, 24576, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15000) = 0x7f2cb10fd000
mmap(0x7f2cb1103000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a000) = 0x7f2cb1103000
mmap(0x7f2cb1105000, 13504, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f2cb1105000
close(3)                                = 0
openat(AT_FDCWD, "/lib64/libresolv.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000G\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=207000, ...}) = 0
mmap(NULL, 105088, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2cb10ce000
mprotect(0x7f2cb10d2000, 73728, PROT_NONE) = 0
mmap(0x7f2cb10d2000, 53248, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x4000) = 0x7f2cb10d2000
mmap(0x7f2cb10df000, 16384, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x11000) = 0x7f2cb10df000
mmap(0x7f2cb10e4000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15000) = 0x7f2cb10e4000
mmap(0x7f2cb10e6000, 6784, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f2cb10e6000
close(3)                                = 0
openat(AT_FDCWD, "/lib64/libcrypto.so.1.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\240\7\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=4260160, ...}) = 0
mmap(NULL, 2997760, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2cb0df2000
mprotect(0x7f2cb0e6b000, 2293760, PROT_NONE) = 0
mmap(0x7f2cb0e6b000, 1695744, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x79000) = 0x7f2cb0e6b000
mmap(0x7f2cb1009000, 593920, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x217000) = 0x7f2cb1009000
mmap(0x7f2cb109b000, 192512, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2a8000) = 0x7f2cb109b000
mmap(0x7f2cb10ca000, 15872, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f2cb10ca000
close(3)                                = 0
openat(AT_FDCWD, "/lib64/libssl.so.1.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220\10\2\0\0\0\0\0"..., 832) = 832
lseek(3, 552104, SEEK_SET)              = 552104
read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
fstat(3, {st_mode=S_IFREG|0755, st_size=701672, ...}) = 0
lseek(3, 552104, SEEK_SET)              = 552104
read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
mmap(NULL, 610352, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2cb0d5c000
mprotect(0x7f2cb0d79000, 438272, PROT_NONE) = 0
mmap(0x7f2cb0d79000, 327680, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1d000) = 0x7f2cb0d79000
mmap(0x7f2cb0dc9000, 106496, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6d000) = 0x7f2cb0dc9000
mmap(0x7f2cb0de4000, 53248, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x87000) = 0x7f2cb0de4000
mmap(0x7f2cb0df1000, 48, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f2cb0df1000
close(3)                                = 0
openat(AT_FDCWD, "/lib64/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220\323\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=3621096, ...}) = 0
mmap(NULL, 1331456, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2cb0c16000
mmap(0x7f2cb0c23000, 638976, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xd000) = 0x7f2cb0c23000
mmap(0x7f2cb0cbf000, 634880, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xa9000) = 0x7f2cb0cbf000
mmap(0x7f2cb0d5a000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x143000) = 0x7f2cb0d5a000
close(3)                                = 0
openat(AT_FDCWD, "/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0p\22\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=61872, ...}) = 0
mmap(NULL, 20784, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2cb0c10000
mmap(0x7f2cb0c11000, 8192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1000) = 0x7f2cb0c11000
mmap(0x7f2cb0c13000, 4096, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f2cb0c13000
mmap(0x7f2cb0c14000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f2cb0c14000
close(3)                                = 0
openat(AT_FDCWD, "/lib64/libxml2.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\371\2\0\0\0\0\0"..., 832) = 832
lseek(3, 1435968, SEEK_SET)             = 1435968
read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
fstat(3, {st_mode=S_IFREG|0755, st_size=1558944, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2cb0c0e000
lseek(3, 1435968, SEEK_SET)             = 1435968
read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
mmap(NULL, 1483096, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2cb0aa3000
mmap(0x7f2cb0ad1000, 946176, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2e000) = 0x7f2cb0ad1000
mmap(0x7f2cb0bb8000, 303104, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x115000) = 0x7f2cb0bb8000
mmap(0x7f2cb0c02000, 40960, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15e000) = 0x7f2cb0c02000
mmap(0x7f2cb0c0c000, 4440, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f2cb0c0c000
close(3)                                = 0
openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P@\2\0\0\0\0\0"..., 832) = 832
lseek(3, 792, SEEK_SET)                 = 792
read(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\346\4=\16,\314\275\4\36$\325#\200%i\326"..., 68) = 68
fstat(3, {st_mode=S_IFREG|0755, st_size=6697832, ...}) = 0
lseek(3, 792, SEEK_SET)                 = 792
read(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\346\4=\16,\314\275\4\36$\325#\200%i\326"..., 68) = 68
lseek(3, 864, SEEK_SET)                 = 864
read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
mmap(NULL, 1857472, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2cb08dd000
mprotect(0x7f2cb08ff000, 1679360, PROT_NONE) = 0
mmap(0x7f2cb08ff000, 1363968, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7f2cb08ff000
mmap(0x7f2cb0a4c000, 311296, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16f000) = 0x7f2cb0a4c000
mmap(0x7f2cb0a99000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1bb000) = 0x7f2cb0a99000
mmap(0x7f2cb0a9f000, 14272, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f2cb0a9f000
close(3)                                = 0
openat(AT_FDCWD, "/lib64/libz.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\3605\0\0\0\0\0\0"..., 832) = 832
lseek(3, 94320, SEEK_SET)               = 94320
read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
fstat(3, {st_mode=S_IFREG|0755, st_size=172904, ...}) = 0
lseek(3, 94320, SEEK_SET)               = 94320
read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
mmap(NULL, 102408, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2cb08c3000
mmap(0x7f2cb08c6000, 57344, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f2cb08c6000
mmap(0x7f2cb08d4000, 28672, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x11000) = 0x7f2cb08d4000
mmap(0x7f2cb08db000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17000) = 0x7f2cb08db000
mmap(0x7f2cb08dc000, 8, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f2cb08dc000
close(3)                                = 0
openat(AT_FDCWD, "/lib64/liblzma.so.5", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\3609\0\0\0\0\0\0"..., 832) = 832
lseek(3, 154368, SEEK_SET)              = 154368
read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
fstat(3, {st_mode=S_IFREG|0755, st_size=299384, ...}) = 0
lseek(3, 154368, SEEK_SET)              = 154368
read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
mmap(NULL, 163848, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2cb089a000
mprotect(0x7f2cb089d000, 147456, PROT_NONE) = 0
mmap(0x7f2cb089d000, 98304, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f2cb089d000
mmap(0x7f2cb08b5000, 45056, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b000) = 0x7f2cb08b5000
mmap(0x7f2cb08c1000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x26000) = 0x7f2cb08c1000
mmap(0x7f2cb08c2000, 8, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f2cb08c2000
close(3)                                = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2cb0898000
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2cb0895000
arch_prctl(ARCH_SET_FS, 0x7f2cb0895740) = 0
mprotect(0x7f2cb0a99000, 16384, PROT_READ) = 0
mprotect(0x7f2cb1103000, 4096, PROT_READ) = 0
mprotect(0x7f2cb08c1000, 4096, PROT_READ) = 0
mprotect(0x7f2cb08db000, 4096, PROT_READ) = 0
mprotect(0x7f2cb0d5a000, 4096, PROT_READ) = 0
mprotect(0x7f2cb0c14000, 4096, PROT_READ) = 0
mprotect(0x7f2cb0c02000, 36864, PROT_READ) = 0
mprotect(0x7f2cb109b000, 176128, PROT_READ) = 0
mprotect(0x7f2cb0de4000, 36864, PROT_READ) = 0
mprotect(0x7f2cb10e4000, 4096, PROT_READ) = 0
mprotect(0x5572a086e000, 475136, PROT_READ) = 0
mprotect(0x7f2cb114a000, 4096, PROT_READ) = 0
munmap(0x7f2cb110b000, 83197)           = 0
set_tid_address(0x7f2cb0895a10)         = 746965
set_robust_list(0x7f2cb0895a20, 24)     = 0
rt_sigaction(SIGRTMIN, {sa_handler=0x7f2cb10eec50, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f2cb10fac60}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {sa_handler=0x7f2cb10eecf0, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0x7f2cb10fac60}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
access("/etc/system-fips", F_OK)        = -1 ENOENT (No such file or directory)
rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f2cb0914ec0}, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGHUP, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGINT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGQUIT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGILL, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTRAP, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGABRT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGBUS, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGFPE, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGKILL, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGUSR1, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGSEGV, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGUSR2, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGPIPE, NULL, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f2cb0914ec0}, 8) = 0
rt_sigaction(SIGALRM, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTERM, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGSTKFLT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGCHLD, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGCONT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGSTOP, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTSTP, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTTIN, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTTOU, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGURG, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGXCPU, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGXFSZ, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGVTALRM, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGPROF, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGWINCH, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGIO, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGPWR, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGSYS, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_2, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_3, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_4, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_5, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_6, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_7, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_8, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_9, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_10, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_11, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_12, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_13, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_14, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_15, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_16, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_17, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_18, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_19, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_20, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_21, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_22, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_23, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_24, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_25, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_26, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_27, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_28, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_29, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_30, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_31, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_32, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
brk(NULL)                               = 0x5572a1fe6026
brk(0x5572a2007026)                     = 0x5572a2007026
brk(NULL)                               = 0x5572a2007026
brk(0x5572a2008000)                     = 0x5572a2008000
mmap(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2cb0695000
munmap(0x7f2cb0695000, 2097152)         = 0
mmap(NULL, 4190208, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2cb0496000
munmap(0x7f2cb0496000, 1482752)         = 0
munmap(0x7f2cb0800000, 610304)          = 0
getcwd("/", 4096)                       = 2
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2997, ...}) = 0
read(3, "# Locale name alias data base.\n#"..., 4096) = 2997
read(3, "", 4096)                       = 0
close(3)                                = 0
openat(AT_FDCWD, "/usr/lib/locale/C.UTF-8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/locale/C.utf8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=337024, ...}) = 0
mmap(NULL, 337024, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f2cb0842000
close(3)                                = 0
openat(AT_FDCWD, "/usr/lib64/gconv/gconv-modules.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=26398, ...}) = 0
mmap(NULL, 26398, PROT_READ, MAP_SHARED, 3, 0) = 0x7f2cb1119000
close(3)                                = 0
futex(0x7f2cb0a9ea34, FUTEX_WAKE_PRIVATE, 2147483647) = 0
openat(AT_FDCWD, "/etc/localtime", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2228, ...}) = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=2228, ...}) = 0
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\7\0\0\0\7\0\0\0\0"..., 4096) = 2228
lseek(3, -1410, SEEK_CUR)               = 818
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\7\0\0\0\7\0\0\0\0"..., 4096) = 1410
close(3)                                = 0
lstat("/usr/local/sbin/php", 0x7ffd29ad4ce0) = -1 ENOENT (No such file or directory)
lstat("/usr/local/bin/php", 0x7ffd29ad4ce0) = -1 ENOENT (No such file or directory)
lstat("/usr/sbin/php", 0x7ffd29ad4ce0)  = -1 ENOENT (No such file or directory)
lstat("/usr/bin/php", {st_mode=S_IFREG|0755, st_size=4973152, ...}) = 0
lstat("/usr/bin", {st_mode=S_IFDIR|0555, st_size=73728, ...}) = 0
lstat("/usr", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
access("/usr/bin/php", X_OK)            = 0
stat("/usr/bin/php", {st_mode=S_IFREG|0755, st_size=4973152, ...}) = 0
brk(NULL)                               = 0x5572a2008000
brk(0x5572a2029000)                     = 0x5572a2029000
mmap(NULL, 323584, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2cb05b1000
brk(NULL)                               = 0x5572a2029000
brk(0x5572a2058000)                     = 0x5572a2058000
futex(0x7f2cb0c0ce48, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x7f2cb10cc658, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x7f2cb10cc64c, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x7f2cb10cc644, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x7f2cb10cc740, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x7f2cb10cc630, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x7f2cb10cc628, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x7f2cb10c95dc, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x7f2cb10cc044, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x7f2cb10cbfdc, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x7f2cb10cbfd0, FUTEX_WAKE_PRIVATE, 2147483647) = 0
brk(NULL)                               = 0x5572a2058000
brk(0x5572a2079000)                     = 0x5572a2079000
futex(0x7f2cb10cc63c, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x7f2cb10cc5f8, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x7f2cb10cc5f0, FUTEX_WAKE_PRIVATE, 2147483647) = 0
openat(AT_FDCWD, "/etc/pki/tls/openssl.cnf", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=11227, ...}) = 0
read(3, "#\n# OpenSSL example configuratio"..., 4096) = 4096
stat("/etc/crypto-policies/back-ends/opensslcnf.config", {st_mode=S_IFREG|0644, st_size=291, ...}) = 0
openat(AT_FDCWD, "/etc/crypto-policies/back-ends/opensslcnf.config", O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=291, ...}) = 0
read(4, "CipherString = @SECLEVEL=1:kEECD"..., 4096) = 291
read(4, "", 4096)                       = 0
close(4)                                = 0
read(3, "ng, T61String, BMPString.\n# pkix"..., 4096) = 4096
read(3, "rityKeyIdentifier=keyid:always\n\n"..., 4096) = 3035
read(3, "", 4096)                       = 0
close(3)                                = 0
futex(0x7f2cb10cc620, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x7f2cb0df0f40, FUTEX_WAKE_PRIVATE, 2147483647) = 0
sysinfo({uptime=175195, loads=[0, 0, 0], totalram=6233845760, freeram=2524049408, sharedram=255488000, bufferram=97939456, totalswap=623382528, freeswap=614993920, procs=244, totalhigh=0, freehigh=0, mem_unit=1}) = 0
futex(0x7f2cb0df1028, FUTEX_WAKE_PRIVATE, 2147483647) = 0
brk(NULL)                               = 0x5572a2079000
brk(0x5572a209a000)                     = 0x5572a209a000
brk(NULL)                               = 0x5572a209a000
brk(0x5572a20bb000)                     = 0x5572a20bb000
mmap(NULL, 151552, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2cb081d000
brk(NULL)                               = 0x5572a20bb000
brk(0x5572a20e0000)                     = 0x5572a20e0000
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
rt_sigaction(SIGPROF, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGPROF, {sa_handler=0x5572a077fee0, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f2cb10fac60}, NULL, 8) = 0
rt_sigaction(SIGHUP, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGHUP, {sa_handler=0x5572a077fee0, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f2cb10fac60}, NULL, 8) = 0
rt_sigaction(SIGINT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGINT, {sa_handler=0x5572a077fee0, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f2cb10fac60}, NULL, 8) = 0
rt_sigaction(SIGQUIT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGQUIT, {sa_handler=0x5572a077fee0, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f2cb10fac60}, NULL, 8) = 0
rt_sigaction(SIGTERM, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTERM, {sa_handler=0x5572a077fee0, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f2cb10fac60}, NULL, 8) = 0
rt_sigaction(SIGUSR1, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGUSR1, {sa_handler=0x5572a077fee0, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f2cb10fac60}, NULL, 8) = 0
rt_sigaction(SIGUSR2, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGUSR2, {sa_handler=0x5572a077fee0, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f2cb10fac60}, NULL, 8) = 0
rt_sigaction(SIGPROF, {sa_handler=0x5572a077fee0, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f2cb10fac60}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [PROF], NULL, 8) = 0
mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2cb080d000
gettimeofday({tv_sec=1570193260, tv_usec=678587}, NULL) = 0
fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x1), ...}) = 0
fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x1), ...}) = 0
lseek(0, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x1), ...}) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x1), ...}) = 0
lseek(1, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
fstat(2, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x1), ...}) = 0
fstat(2, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x1), ...}) = 0
lseek(2, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
mmap(NULL, 65536, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 EPERM (Operation not permitted)
close(2)                                = 0
close(1)                                = 0
close(0)                                = 0
munmap(0x7f2cb080d000, 65536)           = 0
brk(NULL)                               = 0x5572a20e0000
brk(NULL)                               = 0x5572a20e0000
brk(0x5572a20d7000)                     = 0x5572a20d7000
brk(NULL)                               = 0x5572a20d7000
munmap(0x7f2cb0600000, 2097152)         = 0
munmap(0x7f2cb081d000, 151552)          = 0
munmap(0x7f2cb05b1000, 323584)          = 0
exit_group(0)                           = ?
+++ exited with 0 +++
 [2019-10-04 12:51 UTC] nikic@php.net
strace log by bugreports at gmail dot com deleted moved to https://gist.github.com/nikic/9cedba68cf25343ae9a4a53d4b52eb03 and deleted from here. With these additional notes:

> php 7.2.24-dev snashot from last night with bundeled pcre (--with-pcre-jit --with-pcre-regex)
> 
> systemd-run -p MemoryDenyWriteExecute=yes strace -o /downloads/strace-preg_match.log php -r "preg_match('/^[\w.-]+@[\w.-]+\.\w{2,}$/','ilya@ilya.pp.ua');"

Please avoid pasting huge output as comments.
 [2019-10-04 12:55 UTC] nikic@php.net
Strace log has:

mmap(NULL, 65536, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 EPERM (Operation not permitted)

So clearly the mmap does fail and JIT won't work. As the preg call still succeeds, it does looks like an automatic fallback to non-JIT happens.

So we should implement this fallback for PHP 7.3 as well ... then people may not get good performance, but at least code will work.
 [2019-10-04 13:22 UTC] nikic@php.net
Additional issue I ran into while looking into JIT fallback: https://bugs.exim.org/show_bug.cgi?id=2453
 [2019-10-04 13:23 UTC] bugreports at gmail dot com
than that fallback simply happen in pcre itself and for some reason not in pcre2

mod_security uses pcre_jit too, had an issue some years ago and was forced to rebuild it without to prevent some specific crashes and it shares the MemoryDenyWriteExecute=yes

> then people may not get good performance, but at least code will work

not sure if that's the best thing to do, i would have preferred a one time startup warning because in that case while trying out "MemoryDenyWriteExecute=yes" i would have reverted it which will happen now :-)
 [2019-10-04 13:28 UTC] bugreports at gmail dot com
this bugreport here was the reason that i opened https://bugs.php.net/bug.php?id=78631 last night

things like https://bugs.exim.org/show_bug.cgi?id=2453 as well as the summarized changelog from fedora pcre2-10.33 for me are questioning if cherrypicking alone scales
 [2019-10-04 13:42 UTC] ilya at ilya dot pp dot ua
Does something have to change if I rebuild pcre2 without option "--enable-jit-sealloc" and rebuild php with this?
I am now waiting for the building to complete.
 [2019-10-04 14:08 UTC] nikic@php.net
> than that fallback simply happen in pcre itself and for some reason not in pcre2

Actually the fallback does still happen, the difference is just that now a warning is printed. The preg_match() call succeeds in either case though.

I have now landed an initial improvement in https://github.com/php/php-src/commit/1d6e9da7433bddca5c591ef5b2eeef9c410543bb. It provides a more explicit error message, pointing people to either fix their security restrictions or set pcre.jit=0. It also disables the JIT, so this is not going to be printed for every regex like the current warning is.

We might want to change this to happen completely silently though.

> Does something have to change if I rebuild pcre2 without option "--enable-jit-sealloc" and rebuild php with this?

It might work. But if there is some restriction in place that prohibits WX mmaps, then that won't help either.
 [2019-10-04 15:24 UTC] ilya at ilya dot pp dot ua
I'm build pcre2 without "--enable-jit-sealloc" and it works without errors!
https://bugzilla.suse.com/attachment.cgi?id=820598
Please see what has changed, is jit compiled at all, and if so, in which directory?
 [2019-10-04 15:46 UTC] ilya at ilya dot pp dot ua
https://build.opensuse.org/package/view_file/devel:libraries:c_c++/pcre2/pcre2.changes?expand=1
-------------------------------------------------------------------
Tue Dec 11 14:31:55 UTC 2018 - Cristian Rodríguez <crrodriguez@opensuse.org>

- Build with --enable-jit-sealloc option, otherwise when 
  selinux is enabled or systemd memory protections are on,
  programs will fail to work with execmem violations.

Vicious circle. :-(
 [2019-10-07 11:32 UTC] nikic@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: nikic
 [2019-10-07 11:32 UTC] nikic@php.net
The pcre use-after-free on allocation failure is fixed with https://github.com/php/php-src/commit/ab61d5caf926e080fb5729dbef9ae091169cec88.

I don't think there is anything more we can do here from PHP's side. What is left is either granting PHP appropriate permissions or setting pcre.jit=0, but that has to happen on the distro or developer side.
 [2019-10-07 16:02 UTC] ilya at ilya dot pp dot ua
Thank you
I agree, the problem is on the pcre side.
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Fri Dec 06 07:01:25 2019 UTC