summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan K. Taylor <dktapps@pmmp.io>2021-01-11 22:39:14 +0000
committerNikita Popov <nikita.ppv@gmail.com>2021-01-19 10:25:42 +0100
commit872f302b8dafe5914c18dcf775e584a8dc920f05 (patch)
treeb831a2f0dfef108353e2ae6cdeadfd25e6691bda
parentfbd8e20ed5c6014b96c6f533e7f94b35789ac2f0 (diff)
downloadphp-git-872f302b8dafe5914c18dcf775e584a8dc920f05.tar.gz
Keep JIT region executable under ZTS
When one thread tries to compile a script, another thread may already be executing JITed code. In this case we can't make the memory non-executable. This violates the W^X principle, but doesn't seem to be avoidable for ZTS builds for now. The same problem does not exist for NTS, as it's a different process executing there, which has it's own memory protection mapping. Closes GH-6595.
-rw-r--r--ext/opcache/jit/zend_jit.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c
index a983a818a9..1306bb36ba 100644
--- a/ext/opcache/jit/zend_jit.c
+++ b/ext/opcache/jit/zend_jit.c
@@ -3962,15 +3962,24 @@ ZEND_EXT_API void zend_jit_unprotect(void)
{
#ifdef HAVE_MPROTECT
if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) {
- if (mprotect(dasm_buf, dasm_size, PROT_READ | PROT_WRITE) != 0) {
+ int opts = PROT_READ | PROT_WRITE;
+#ifdef ZTS
+ /* Another thread may be executing JITed code. */
+ opts |= PROT_EXEC;
+#endif
+ if (mprotect(dasm_buf, dasm_size, opts) != 0) {
fprintf(stderr, "mprotect() failed [%d] %s\n", errno, strerror(errno));
}
}
#elif _WIN32
if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) {
- DWORD old;
-
- if (!VirtualProtect(dasm_buf, dasm_size, PAGE_READWRITE, &old)) {
+ DWORD old, new;
+#ifdef ZTS
+ new = PAGE_EXECUTE_READWRITE;
+#else
+ new = PAGE_READWRITE;
+#endif
+ if (!VirtualProtect(dasm_buf, dasm_size, new, &old)) {
DWORD err = GetLastError();
char *msg = php_win32_error_to_msg(err);
fprintf(stderr, "VirtualProtect() failed [%u] %s\n", err, msg);