Skip to content

Commit 872f302

Browse files
dktappsnikic
authored andcommitted
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.
1 parent fbd8e20 commit 872f302

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

ext/opcache/jit/zend_jit.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3962,15 +3962,24 @@ ZEND_EXT_API void zend_jit_unprotect(void)
39623962
{
39633963
#ifdef HAVE_MPROTECT
39643964
if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) {
3965-
if (mprotect(dasm_buf, dasm_size, PROT_READ | PROT_WRITE) != 0) {
3965+
int opts = PROT_READ | PROT_WRITE;
3966+
#ifdef ZTS
3967+
/* Another thread may be executing JITed code. */
3968+
opts |= PROT_EXEC;
3969+
#endif
3970+
if (mprotect(dasm_buf, dasm_size, opts) != 0) {
39663971
fprintf(stderr, "mprotect() failed [%d] %s\n", errno, strerror(errno));
39673972
}
39683973
}
39693974
#elif _WIN32
39703975
if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) {
3971-
DWORD old;
3972-
3973-
if (!VirtualProtect(dasm_buf, dasm_size, PAGE_READWRITE, &old)) {
3976+
DWORD old, new;
3977+
#ifdef ZTS
3978+
new = PAGE_EXECUTE_READWRITE;
3979+
#else
3980+
new = PAGE_READWRITE;
3981+
#endif
3982+
if (!VirtualProtect(dasm_buf, dasm_size, new, &old)) {
39743983
DWORD err = GetLastError();
39753984
char *msg = php_win32_error_to_msg(err);
39763985
fprintf(stderr, "VirtualProtect() failed [%u] %s\n", err, msg);

0 commit comments

Comments
 (0)