3333
3434#ifdef HAVE_JIT
3535
36+ #if defined(HAVE_PKEY_MPROTECT ) && defined(PKEY_DISABLE_WRITE )
37+ # define ZEND_JIT_USE_PKEYS
38+ # ifndef PKEY_DISABLE_EXECUTE
39+ # define PKEY_DISABLE_EXECUTE 0
40+ # endif
41+ #endif
42+
3643#include "Optimizer/zend_func_info.h"
3744#include "Optimizer/zend_ssa.h"
3845#include "Optimizer/zend_inference.h"
@@ -88,6 +95,10 @@ static void **dasm_ptr = NULL;
8895
8996static size_t dasm_size = 0 ;
9097
98+ #ifdef ZEND_JIT_USE_PKEYS
99+ static int pkey = 0 ; /* Memory Protection Key */
100+ #endif
101+
91102static zend_long jit_bisect_pos = 0 ;
92103
93104static zend_vm_opcode_handler_t zend_jit_runtime_jit_handler = NULL ;
@@ -3519,6 +3530,21 @@ void zend_jit_unprotect(void)
35193530{
35203531#ifdef HAVE_MPROTECT
35213532 if (!(JIT_G (debug ) & (ZEND_JIT_DEBUG_GDB |ZEND_JIT_DEBUG_PERF_DUMP ))) {
3533+ # ifdef ZEND_JIT_USE_PKEYS
3534+ if (pkey ) {
3535+ # ifdef ZTS
3536+ int restrictions = 0 ;
3537+ # else
3538+ int restrictions = PKEY_DISABLE_EXECUTE ;
3539+ # endif
3540+ if (pkey_set (pkey , restrictions ) != 0 ) {
3541+ fprintf (stderr , "pkey_set() failed [%d] %s\n" , errno , strerror (errno ));
3542+ } else {
3543+ return ;
3544+ }
3545+ }
3546+ # endif
3547+
35223548 int opts = PROT_READ | PROT_WRITE ;
35233549#ifdef ZTS
35243550#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
@@ -3554,6 +3580,16 @@ void zend_jit_protect(void)
35543580{
35553581#ifdef HAVE_MPROTECT
35563582 if (!(JIT_G (debug ) & (ZEND_JIT_DEBUG_GDB |ZEND_JIT_DEBUG_PERF_DUMP ))) {
3583+ # ifdef ZEND_JIT_USE_PKEYS
3584+ if (pkey ) {
3585+ if (pkey_set (pkey , PKEY_DISABLE_WRITE ) != 0 ) {
3586+ fprintf (stderr , "pkey_set() failed [%d] %s\n" , errno , strerror (errno ));
3587+ } else {
3588+ return ;
3589+ }
3590+ }
3591+ # endif
3592+
35573593#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
35583594 if (zend_write_protect ) {
35593595 pthread_jit_write_protect_np (1 );
@@ -3774,34 +3810,45 @@ int zend_jit_check_support(void)
37743810 return SUCCESS ;
37753811}
37763812
3777- void zend_jit_startup (void * buf , size_t size , bool reattached )
3813+ static void zend_jit_startup_dasm_prot (void )
37783814{
3779- zend_jit_halt_op = zend_get_halt_op ();
3780- zend_jit_profile_counter_rid = zend_get_op_array_extension_handle (ACCELERATOR_PRODUCT_NAME );
3781-
3782- #ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
3783- zend_write_protect = pthread_jit_write_protect_supported_np ();
3784- #endif
3785-
3786- dasm_buf = buf ;
3787- dasm_size = size ;
3788- dasm_ptr = dasm_end = (void * )(((char * )dasm_buf ) + size - sizeof (* dasm_ptr ) * 2 );
3789-
37903815#ifdef HAVE_MPROTECT
3791- #ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
3816+ # ifdef ZEND_JIT_USE_PKEYS
3817+ pkey = pkey_alloc (0 , PKEY_DISABLE_WRITE );
3818+ if (pkey < 0 ) {
3819+ pkey = 0 ;
3820+ }
3821+ # endif
3822+ # ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
37923823 if (zend_write_protect ) {
37933824 pthread_jit_write_protect_np (1 );
37943825 }
3795- #endif
3826+ # endif
3827+
37963828 if (JIT_G (debug ) & (ZEND_JIT_DEBUG_GDB |ZEND_JIT_DEBUG_PERF_DUMP )) {
37973829 if (mprotect (dasm_buf , dasm_size , PROT_READ | PROT_WRITE | PROT_EXEC ) != 0 ) {
37983830 fprintf (stderr , "mprotect() failed [%d] %s\n" , errno , strerror (errno ));
37993831 }
3800- } else {
3801- if (mprotect (dasm_buf , dasm_size , PROT_READ | PROT_EXEC ) != 0 ) {
3802- fprintf (stderr , "mprotect() failed [%d] %s\n" , errno , strerror (errno ));
3832+ return ;
3833+ }
3834+
3835+ # if ZEND_JIT_USE_PKEYS
3836+ if (pkey ) {
3837+ if (pkey_mprotect (dasm_buf , dasm_size , PROT_READ | PROT_WRITE | PROT_EXEC , pkey ) != 0 ) {
3838+ fprintf (stderr , "pkey_mprotect() failed [%d] %s\n" , errno , strerror (errno ));
3839+ pkey = 0 ;
3840+ } else {
3841+ /* Fallback to mprotect(PROT_READ | PROT_EXEC) */
3842+ return ;
38033843 }
38043844 }
3845+
3846+ # endif
3847+
3848+ if (mprotect (dasm_buf , dasm_size , PROT_READ | PROT_EXEC ) != 0 ) {
3849+ fprintf (stderr , "mprotect() failed [%d] %s\n" , errno , strerror (errno ));
3850+ }
3851+
38053852#elif defined(_WIN32 )
38063853 if (JIT_G (debug ) & (ZEND_JIT_DEBUG_GDB |ZEND_JIT_DEBUG_PERF_DUMP )) {
38073854 DWORD old ;
@@ -3823,6 +3870,22 @@ void zend_jit_startup(void *buf, size_t size, bool reattached)
38233870 }
38243871 }
38253872#endif
3873+ }
3874+
3875+ void zend_jit_startup (void * buf , size_t size , bool reattached )
3876+ {
3877+ zend_jit_halt_op = zend_get_halt_op ();
3878+ zend_jit_profile_counter_rid = zend_get_op_array_extension_handle (ACCELERATOR_PRODUCT_NAME );
3879+
3880+ #ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
3881+ zend_write_protect = pthread_jit_write_protect_supported_np ();
3882+ #endif
3883+
3884+ dasm_buf = buf ;
3885+ dasm_size = size ;
3886+ dasm_ptr = dasm_end = (void * )(((char * )dasm_buf ) + size - sizeof (* dasm_ptr ) * 2 );
3887+
3888+ zend_jit_startup_dasm_prot ();
38263889
38273890 if (!reattached ) {
38283891 zend_jit_unprotect ();
0 commit comments