Skip to content

Commit 1143b34

Browse files
committed
Fix stack poisoning
1 parent b977297 commit 1143b34

File tree

3 files changed

+47
-2
lines changed

3 files changed

+47
-2
lines changed

Zend/zend_vm_def.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2981,8 +2981,14 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY)
29812981
} else if (UNEXPECTED(call_info & ZEND_CALL_FAKE_CLOSURE)) {
29822982
OBJ_RELEASE(ZEND_PARTIAL_OBJECT(EX(func)));
29832983
}
2984+
2985+
zend_execute_data *prev_execute_data = EX(prev_execute_data);
2986+
#ifdef __SANITIZE_ADDRESS__
2987+
size_t size = (size_t)EG(vm_stack_top) - (size_t)execute_data;
2988+
__asan_poison_memory_region(execute_data, size);
2989+
#endif
29842990
EG(vm_stack_top) = (zval*)execute_data;
2985-
execute_data = EX(prev_execute_data);
2991+
execute_data = prev_execute_data;
29862992

29872993
if (UNEXPECTED(EG(exception) != NULL)) {
29882994
zend_rethrow_exception(execute_data);
@@ -4154,6 +4160,10 @@ ZEND_VM_HOT_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL,OBSERVER))
41544160
}
41554161
zend_vm_stack_free_call_frame_ex(call_info, call);
41564162
} else {
4163+
#ifdef __SANITIZE_ADDRESS__
4164+
size_t size = (size_t)EG(vm_stack_top) - (size_t)call;
4165+
__asan_poison_memory_region(call, size);
4166+
#endif
41574167
EG(vm_stack_top) = (zval*)call;
41584168
}
41594169

@@ -4290,6 +4300,10 @@ ZEND_VM_C_LABEL(fcall_by_name_end):
42904300
}
42914301
zend_vm_stack_free_call_frame_ex(call_info, call);
42924302
} else {
4303+
#ifdef __SANITIZE_ADDRESS__
4304+
size_t size = (size_t)EG(vm_stack_top) - (size_t)call;
4305+
__asan_poison_memory_region(call, size);
4306+
#endif
42934307
EG(vm_stack_top) = (zval*)call;
42944308
}
42954309

@@ -4710,8 +4724,13 @@ ZEND_VM_HANDLER(139, ZEND_GENERATOR_CREATE, ANY, ANY)
47104724
call_info = EX_CALL_INFO();
47114725
EG(current_execute_data) = EX(prev_execute_data);
47124726
if (EXPECTED(!(call_info & (ZEND_CALL_TOP|ZEND_CALL_ALLOCATED)))) {
4727+
zend_execute_data *prev_execute_data = EX(prev_execute_data);
4728+
#ifdef __SANITIZE_ADDRESS__
4729+
size_t size = (size_t)EG(vm_stack_top) - (size_t)execute_data;
4730+
__asan_poison_memory_region(execute_data, size);
4731+
#endif
47134732
EG(vm_stack_top) = (zval*)execute_data;
4714-
execute_data = EX(prev_execute_data);
4733+
execute_data = prev_execute_data;
47154734
LOAD_NEXT_OPLINE();
47164735
ZEND_VM_LEAVE();
47174736
} else if (EXPECTED(!(call_info & ZEND_CALL_TOP))) {

ext/opcache/jit/zend_jit_helpers.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,20 @@ static zend_execute_data* ZEND_FASTCALL zend_jit_int_extend_stack_helper(uint32_
306306
return call;
307307
}
308308

309+
static void ZEND_FASTCALL zend_jit_poison_memory_region_helper(void *addr, size_t size)
310+
{
311+
#ifdef __SANITIZE_ADDRESS__
312+
__asan_poison_memory_region(addr, size);
313+
#endif
314+
}
315+
316+
static void ZEND_FASTCALL zend_jit_unpoison_memory_region_helper(void *addr, size_t size)
317+
{
318+
#ifdef __SANITIZE_ADDRESS__
319+
__asan_unpoison_memory_region(addr, size);
320+
#endif
321+
}
322+
309323
static zval* ZEND_FASTCALL zend_jit_symtable_find(HashTable *ht, zend_string *str)
310324
{
311325
zend_ulong idx;

ext/opcache/jit/zend_jit_ir.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3112,6 +3112,8 @@ static void zend_jit_setup_disasm(void)
31123112
REGISTER_HELPER(zend_jit_uninit_static_prop);
31133113
REGISTER_HELPER(zend_jit_rope_end);
31143114
REGISTER_HELPER(zend_fcall_interrupt);
3115+
REGISTER_HELPER(zend_jit_poison_memory_region_helper);
3116+
REGISTER_HELPER(zend_jit_unpoison_memory_region_helper);
31153117

31163118
#ifndef ZTS
31173119
REGISTER_DATA(EG(current_execute_data));
@@ -8632,6 +8634,11 @@ static int zend_jit_push_call_frame(zend_jit_ctx *jit, const zend_op *opline, co
86328634
#endif
86338635
ir_STORE(ref, ir_ADD_A(top, used_stack_ref));
86348636

8637+
#ifdef __SANITIZE_ADDRESS__
8638+
ir_CALL_2(IR_VOID, ir_CONST_FC_FUNC(zend_jit_unpoison_memory_region_helper),
8639+
rx, used_stack_ref);
8640+
#endif
8641+
86358642
// JIT: zend_vm_init_call_frame(call, call_info, func, num_args, called_scope, object);
86368643
if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || opline->opcode != ZEND_INIT_METHOD_CALL) {
86378644
// JIT: ZEND_SET_CALL_INFO(call, 0, call_info);
@@ -11193,6 +11200,11 @@ static int zend_jit_leave_func(zend_jit_ctx *jit,
1119311200
may_throw = 1;
1119411201
}
1119511202

11203+
#ifdef __SANITIZE_ADDRESS__
11204+
ir_CALL_2(IR_VOID, ir_CONST_FC_FUNC(zend_jit_poison_memory_region_helper),
11205+
jit_FP(jit), ir_SUB_A(ir_LOAD_A(jit_EG(vm_stack_top)), jit_FP(jit)));
11206+
#endif
11207+
1119611208
// JIT: EG(vm_stack_top) = (zval*)execute_data
1119711209
ir_STORE(jit_EG(vm_stack_top), jit_FP(jit));
1119811210

0 commit comments

Comments
 (0)