Skip to content

Fix GH-16913: 8.4 function JIT memory corruption #16943

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 26, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions ext/opcache/jit/zend_jit_ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -11523,6 +11523,32 @@ static int zend_jit_rope(zend_jit_ctx *jit, const zend_op *opline, uint32_t op2_
return 1;
}

static int zend_jit_zval_copy_deref_reg(zend_jit_ctx *jit, zend_jit_addr res_addr, uint32_t res_info, zend_jit_addr val_addr, ir_ref type, ir_ref *values)
{
ir_ref if_type, val;

if (res_info == MAY_BE_LONG) {
if_type = ir_IF(ir_EQ(type, ir_CONST_U32(IS_LONG)));
ir_IF_TRUE(if_type);
val = jit_ZVAL_ADDR(jit, val_addr);
ir_END_PHI_list(*values, val);
ir_IF_FALSE(if_type);
val = ir_ADD_OFFSET(jit_Z_PTR(jit, val_addr), offsetof(zend_reference, val));
ir_END_PHI_list(*values, val);
} else if (res_info == MAY_BE_DOUBLE) {
if_type = ir_IF(ir_EQ(type, ir_CONST_U32(IS_DOUBLE)));
ir_IF_TRUE(if_type);
val = jit_ZVAL_ADDR(jit, val_addr);
ir_END_PHI_list(*values, val);
ir_IF_FALSE(if_type);
val = ir_ADD_OFFSET(jit_Z_PTR(jit, val_addr), offsetof(zend_reference, val));
ir_END_PHI_list(*values, val);
} else {
ZEND_UNREACHABLE();
}
return 1;
}

static int zend_jit_zval_copy_deref(zend_jit_ctx *jit, zend_jit_addr res_addr, zend_jit_addr val_addr, ir_ref type)
{
ir_ref if_refcounted, if_reference, if_refcounted2, ptr, val2, ptr2, type2;
Expand Down Expand Up @@ -14253,9 +14279,16 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit,
}
ir_END_list(end_inputs);
} else {
if (((res_info & MAY_BE_GUARD) && JIT_G(current_frame) && prop_info)
|| Z_MODE(res_addr) == IS_REG) {
if ((res_info & MAY_BE_GUARD) && JIT_G(current_frame) && prop_info) {
ir_END_PHI_list(end_values, jit_ZVAL_ADDR(jit, prop_addr));
} else if ((res_info & MAY_BE_GUARD) && Z_MODE(res_addr) == IS_REG) {
ir_END_PHI_list(end_values, jit_ZVAL_ADDR(jit, prop_addr));
} else if (Z_MODE(res_addr) == IS_REG) {
prop_type_ref = jit_Z_TYPE_INFO(jit, prop_addr);

if (!zend_jit_zval_copy_deref_reg(jit, res_addr, res_info & ~MAY_BE_GUARD, prop_addr, prop_type_ref, &end_values)) {
return 0;
}
} else {
prop_type_ref = jit_Z_TYPE_INFO(jit, prop_addr);

Expand Down