From e11ed028706dbedc51ba71736de21db15890a1c0 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 18 Sep 2019 09:44:00 +0200 Subject: [PATCH] Fixed bug #78272 Use MAP_JIT only when running under hardened runtime, because MAP_JIT is incompatible with fork(). The check is based on https://github.com/mono/mono/commit/f879e35e3ed7496d819bd766deb8be6992d068ed. --- NEWS | 4 +++ ext/pcre/pcre2lib/sljit/sljitExecAllocator.c | 15 ++++++++- ext/pcre/tests/bug78272.phpt | 33 ++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 ext/pcre/tests/bug78272.phpt diff --git a/NEWS b/NEWS index 84ac832178..69bc3b41dd 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,10 @@ PHP NEWS . Fixed bug #78525 (Memory leak in pdo when reusing native prepared statements). (Nikita) +- PCRE: + . Fixed bug #78272 (calling preg_match() before pcntl_fork() will freeze + child process). (Nikita) + - Standard: . Fixed bug #76342 (file_get_contents waits twice specified timeout). (Thomas Calvet) diff --git a/ext/pcre/pcre2lib/sljit/sljitExecAllocator.c b/ext/pcre/pcre2lib/sljit/sljitExecAllocator.c index 3b37a9751f..caaf438578 100644 --- a/ext/pcre/pcre2lib/sljit/sljitExecAllocator.c +++ b/ext/pcre/pcre2lib/sljit/sljitExecAllocator.c @@ -121,7 +121,20 @@ static SLJIT_INLINE int get_map_jit_flag() uname(&name); /* Kernel version for 10.14.0 (Mojave) */ - map_jit_flag = (atoi(name.release) >= 18) ? MAP_JIT : 0; + if (atoi(name.release) >= 18) { + /* Only use MAP_JIT if a hardened runtime is used, because MAP_JIT is incompatible + with fork(). */ + void *ptr = mmap( + NULL, getpagesize(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if (ptr == MAP_FAILED) { + map_jit_flag = MAP_JIT; + } else { + map_jit_flag = 0; + munmap(ptr, getpagesize()); + } + } else { + map_jit_flag = 0; + } } return map_jit_flag; diff --git a/ext/pcre/tests/bug78272.phpt b/ext/pcre/tests/bug78272.phpt new file mode 100644 index 0000000000..576d3013a5 --- /dev/null +++ b/ext/pcre/tests/bug78272.phpt @@ -0,0 +1,33 @@ +--TEST-- +Bug #78272: calling preg_match() before pcntl_fork() will freeze child process +--SKIPIF-- + +--FILE-- + +--EXPECT-- +Main start +Child start +Array +( + [0] => abc +) +End child +End Main -- 2.49.0