From 872f302b8dafe5914c18dcf775e584a8dc920f05 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Jan 2021 22:39:14 +0000 Subject: 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. --- ext/opcache/jit/zend_jit.c | 17 +++++++++++++---- 1 file 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); -- cgit v1.2.1