]> granicus.if.org Git - php/commitdiff
Fixed bug #75601 Thread race in PCRE JIT support
authorAnatol Belski <ab@php.net>
Tue, 5 Dec 2017 16:38:18 +0000 (17:38 +0100)
committerAnatol Belski <ab@php.net>
Tue, 5 Dec 2017 16:38:18 +0000 (17:38 +0100)
ext/pcre/php_pcre.c

index c0a6a848b60227c399191bffdc9d5633edd69a12..42e577e351c62e2157dce3074a8fac71d3425df5 100644 (file)
@@ -67,6 +67,18 @@ PHPAPI ZEND_DECLARE_MODULE_GLOBALS(pcre)
 #define PCRE_JIT_STACK_MAX_SIZE (64 * 1024)
 ZEND_TLS pcre_jit_stack *jit_stack = NULL;
 #endif
+#if defined(ZTS) && defined(HAVE_PCRE_JIT_SUPPORT)
+static MUTEX_T pcre_mt = NULL;
+#define php_pcre_mutex_alloc() if (!pcre_mt) pcre_mt = tsrm_mutex_alloc();
+#define php_pcre_mutex_free() if (pcre_mt) tsrm_mutex_free(pcre_mt);
+#define php_pcre_mutex_lock() tsrm_mutex_lock(pcre_mt);
+#define php_pcre_mutex_unlock() tsrm_mutex_unlock(pcre_mt);
+#else
+#define php_pcre_mutex_alloc()
+#define php_pcre_mutex_free()
+#define php_pcre_mutex_lock()
+#define php_pcre_mutex_unlock()
+#endif
 
 static void pcre_handle_exec_error(int pcre_code) /* {{{ */
 {
@@ -185,6 +197,8 @@ static PHP_MINIT_FUNCTION(pcre)
 {
        REGISTER_INI_ENTRIES();
 
+       php_pcre_mutex_alloc();
+
        REGISTER_LONG_CONSTANT("PREG_PATTERN_ORDER", PREG_PATTERN_ORDER, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("PREG_SET_ORDER", PREG_SET_ORDER, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("PREG_OFFSET_CAPTURE", PREG_OFFSET_CAPTURE, CONST_CS | CONST_PERSISTENT);
@@ -211,6 +225,8 @@ static PHP_MSHUTDOWN_FUNCTION(pcre)
 {
        UNREGISTER_INI_ENTRIES();
 
+       php_pcre_mutex_free();
+
        return SUCCESS;
 }
 /* }}} */
@@ -220,7 +236,9 @@ static PHP_MSHUTDOWN_FUNCTION(pcre)
 static PHP_RINIT_FUNCTION(pcre)
 {
        if (PCRE_G(jit) && jit_stack == NULL) {
+               php_pcre_mutex_lock();
                jit_stack = pcre_jit_stack_alloc(PCRE_JIT_STACK_MIN_SIZE,PCRE_JIT_STACK_MAX_SIZE);
+               php_pcre_mutex_unlock();
        }
 
        return SUCCESS;