kernel: php-fpm: segfault at x ip y sp z error 6 in libpcre.so.1.2.0

An issue with php70-php-fpm Perl PCRE causing some segfaults every once in a while.

Current pcre/jit details from phpinfo:

# php -r "phpinfo();" |egrep -i "pcre|jit"
auto_globals_jit => On => On
pcre
PCRE (Perl Compatible Regular Expressions) Support => enabled
PCRE Library Version => 8.32 2012-11-30
PCRE JIT Support => enabled
pcre.backtrack_limit => 1000000 => 1000000
pcre.jit => 0 => 0
pcre.recursion_limit => 100000 => 100000

Here’s the php.ini section (/etc/opt/remi/php70/php.ini)

 930 [Pcre]
 931 ;PCRE library backtracking limit.
 932 ; http://php.net/pcre.backtrack-limit
 933 ;pcre.backtrack_limit=100000
 934 pcre.backtrack_limit=2000000
 935 ; Increased from 1,000,000 (default) to 2,000,000
 936 
 937 ;PCRE library recursion limit.
 938 ;Please note that if you set this value to a high number you may consume all
 939 ;the available process stack and eventually crash PHP (due to reaching the
 940 ;stack size limit imposed by the Operating System).
 941 ; http://php.net/pcre.recursion-limit
 942 ;pcre.recursion_limit=100000
 943 pcre.recursion_limit=1000000
 944 ; Increased from 100,000 to 1,000,000
 945 
 946 ;Enables or disables JIT compilation of patterns. This requires the PCRE
 947 ;library to be compiled with JIT support.
 948 ;pcre.jit=0
 949 pcre.jit=1
 950 ; STK 051717 Enabled pcre.jit.  It's compiled in and looks like it should help perf.
 951 ; php -r "phpinfo();" |egrep -i "pcre|jit"

After making that change, restart php70-php-fpm and you should be good with the new values set:

# php -r "phpinfo();" |egrep -i "pcre|jit"
auto_globals_jit => On => On
pcre
PCRE (Perl Compatible Regular Expressions) Support => enabled
PCRE Library Version => 8.32 2012-11-30
PCRE JIT Support => enabled
pcre.backtrack_limit => 2000000 => 2000000
pcre.jit => 1 => 1
pcre.recursion_limit => 1000000 => 1000000

Still, need to find out what is causing the PCRE to cause a stack overflow.

EDIT: Need to double-check SELinux

If you want to allow httpd to execmem, then you must tell SELinux about this by enabling the ‘httpd_execmem’ boolean.

# setsebool -P httpd_execmem 1

You can generate a local policy module to allow this access.  You can allow this access for now by executing:

# ausearch -c 'php-fpm' --raw | audit2allow -M my-phpfpm
# semodule -i my-phpfpm.pp
Additional Information:
Source Context system_u:system_r:httpd_t:s0
Target Context system_u:system_r:httpd_t:s0
Source php-fpm

Raw Audit Messages:
type=AVC msg=audit(1495071733.385:311998): avc: denied { execmem } for pid=989 comm="php-fpm" scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:httpd_t:s0 tclass=process

type=SYSCALL msg=audit(1495071733.385:311998): arch=x86_64 syscall=mmap success=no exit=EACCES a0=0 a1=10000 a2=7 a3=22 items=0 ppid=984 pid=989 auid=4294967295 uid=99 gid=99 euid=99 suid=99 fsuid=99 egid=99 sgid=99 fsgid=99 tty=(none) ses=4294967295 comm=php-fpm exe=/opt/remi/php70/root/usr/sbin/php-fpm subj=system_u:system_r:httpd_t:s0 key=(null)

Hash: php-fpm,httpd_t,httpd_t,process,execmem