Recentemente, deparei com esse problema com o SELinux no Amazon Linux com PHP7. Eu usei uma combinação do excelente truque LD_PRELOAD de Russell Coker (para interceptar chamadas mmap () e disparar uma falha de asserção) e gdb (para visualizar a pilha de chamadas assim que a falha de asserção é acionada) para verificar qual função deseja executar.
Eu também cheguei à conclusão de que o PHP7 PCRE JIT foi o culpado. Colocar pcre.jit = 0 no php.ini corrigiu para mim.
Etapas detalhadas
- faça login em sua máquina como root
- faça o download do código-fonte mmap.c em link em /root/mmap.c
- crie o código com
gcc -shared -g -fPIC mmap.c -o mmap.so
- agora execute o Apache através do gdb, interceptando as chamadas mmap ():
LD_PRELOAD=/root/mmap.so gdb /usr/sbin/httpd
- você é lançado no gdb. Como o Apache bifurca os processos filhos, é importante informar ao gdb para entrar neles digitando
set follow-fork-mode child
após o prompt (gdb) - agora inicie o Apache digitando
run
após o prompt (gdb) - aguarde com paciência até que alguma solicitação HTTP dispare o código que, por sua vez, aciona a asserção no mmap, e você volta ao gdb.
Program received signal SIGABRT, Aborted. [Switching to Thread 0x7ffff7fe9840 (LWP 28370)] 0x00007ffff638d5f7 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 56 return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);
- Digite
bt
(backtrace) para ver a pilha de chamadas:
(gdb) bt #0 0x00007ffff638d5f7 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 #1 0x00007ffff638ece8 in __GI_abort () at abort.c:90 #2 0x00007ffff6386566 in __assert_fail_base (fmt=0x7ffff64d6ca8 "%s%s%s:%u: %s%sAssertion '%s' failed.\n%n", assertion=assertion@entry=0x7ffff7bda990 "!(prot & 0x4) || !(prot & 0x2)", file=file@entry=0x7ffff7bda985 "mmap.c", line=line@entry=27, function=function@entry=0x7ffff7bda9af "mmap") at assert.c:92 #3 0x00007ffff6386612 in __GI___assert_fail (assertion=0x7ffff7bda990 "!(prot & 0x4) || !(prot & 0x2)", file=0x7ffff7bda985 "mmap.c", line=27, function=0x7ffff7bda9af "mmap") at assert.c:101 #4 0x00007ffff7bda93e in mmap (addr=0x0, length=65536, prot=7, flags=34, fd=-1, offset=0) at mmap.c:27 #5 0x00007ffff79a6b86 in alloc_chunk (size=65536) at sljit/sljitExecAllocator.c:101 #6 sljit_malloc_exec (size=4440) at sljit/sljitExecAllocator.c:204 #7 sljit_generate_code (compiler=compiler@entry=0x555555b14ad0) at sljit/sljitNativeX86_common.c:296 #8 0x00007ffff79bf74e in _pcre_jit_compile (re=re@entry=0x555555b14650, extra=extra@entry=0x555555b14750) at pcre_jit_compile.c:6434 #9 0x00007ffff79c1fc3 in pcre_study (external_re=external_re@entry=0x555555b14650, options=1, errorptr=errorptr@entry=0x7fffffffa3c8) at pcre_study.c:1354 #10 0x00007fffed2edcbc in pcre_get_compiled_regex_cache (regex=0x7fffd8a04000) at /usr/src/debug/php-7.0.9/ext/pcre/php_pcre.c:487 #11 0x00007fffed2ef21f in php_do_pcre_match (execute_data=0x7fffec419ab0, return_value=0x7fffec419870, global=1) at /usr/src/debug/php-7.0.9/ext/pcre/php_pcre.c:655
- o culpado é facilmente identificado. A entrada de pilha 11 dá-lhe uma sugestão para verificar o PCRE e a entrada 5 é a chamada real que dá errado.