]> granicus.if.org Git - php/commitdiff
Fixed bug #78272
authorNikita Popov <nikita.ppv@gmail.com>
Wed, 18 Sep 2019 07:44:00 +0000 (09:44 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Wed, 18 Sep 2019 08:41:27 +0000 (10:41 +0200)
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
ext/pcre/pcre2lib/sljit/sljitExecAllocator.c
ext/pcre/tests/bug78272.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 84ac832178ad9486119e8d05298851af6e9c83d3..69bc3b41dde83df83d0f17013e48d890b52050d2 100644 (file)
--- 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)
index 3b37a9751f81baa4509e40f4f0d2c20b54a7a9d5..caaf4385783997a288e3a305d696e53128b0263f 100644 (file)
@@ -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 (file)
index 0000000..576d301
--- /dev/null
@@ -0,0 +1,33 @@
+--TEST--
+Bug #78272: calling preg_match() before pcntl_fork() will freeze child process
+--SKIPIF--
+<?php
+if (!extension_loaded('pcntl')) die("skip pcntl extension required");
+?>
+--FILE--
+<?php
+preg_match('/abc/', 'abcde', $r);
+
+$pid = pcntl_fork();
+if ($pid === 0) {
+    print "Child start\n";
+    preg_match('/abc/', 'abcde', $r);
+    print_r($r);
+    print "End child\n";
+    exit(0);
+} else {
+    print "Main start\n";
+    pcntl_waitpid($pid, $status);
+    print "End Main\n";
+    exit(0);
+}
+?>
+--EXPECT--
+Main start
+Child start
+Array
+(
+    [0] => abc
+)
+End child
+End Main