From 466e4dc2a2946aa903bdbb98941b435ac1935a7e Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Fri, 9 Sep 2022 10:50:03 +0200 Subject: [PATCH] Check return value of zend_jit_trace_get_exit_addr() (#9097) --- ext/opcache/jit/zend_jit_arm64.dasc | 30 ++++++++++++++++++++++++++++ ext/opcache/jit/zend_jit_x86.dasc | 31 +++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/ext/opcache/jit/zend_jit_arm64.dasc b/ext/opcache/jit/zend_jit_arm64.dasc index f623e07c83f..d2a8fead267 100644 --- a/ext/opcache/jit/zend_jit_arm64.dasc +++ b/ext/opcache/jit/zend_jit_arm64.dasc @@ -2997,6 +2997,9 @@ static int zend_jit_trace_end(dasm_State **Dst, zend_jit_trace_info *t) |.cold_code for (i = 0; i < t->exit_count; i++) { exit_addr = zend_jit_trace_get_exit_addr(i); + if (!exit_addr) { + return 0; + } | b &exit_addr } |=>1: // end of the code @@ -3809,6 +3812,9 @@ static int zend_jit_inc_dec(dasm_State **Dst, const zend_op *opline, uint32_t op exit_point = zend_jit_trace_get_exit_point(opline + 1, 0); exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!exit_addr) { + return 0; + } | bvs &exit_addr if ((opline->opcode == ZEND_PRE_INC || opline->opcode == ZEND_PRE_DEC) && @@ -4111,6 +4117,9 @@ static int zend_jit_math_long_long(dasm_State **Dst, if (res_info & MAY_BE_GUARD) { int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0); const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!exit_addr) { + return 0; + } if ((res_info & MAY_BE_ANY) == MAY_BE_LONG) { if (use_ovf_flag) { | bvs &exit_addr @@ -6319,6 +6328,9 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3 && !(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF) - (MAY_BE_LONG|MAY_BE_STRING)))) { int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0); not_found_exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!not_found_exit_addr) { + return 0; + } } if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_RW, op1_info, op2_info, dim_type, NULL, not_found_exit_addr, NULL)) { @@ -12498,6 +12510,9 @@ static int zend_jit_fetch_obj(dasm_State **Dst, && (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_OBJECT) { exit_point = zend_jit_trace_get_exit_point(opline, 0); exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!exit_addr) { + return 0; + } } else { val_addr = ZEND_ADDR_MEM_ZVAL(ZREG_REG0, 0); | LOAD_ZVAL_ADDR REG0, prop_addr @@ -12888,6 +12903,9 @@ static int zend_jit_incdec_obj(dasm_State **Dst, if (use_prop_guard) { int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0); const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!exit_addr) { + return 0; + } | IF_NOT_ZVAL_TYPE var_addr, prop_type, &exit_addr, ZREG_TMP1 var_info = (1 << prop_type) | (var_info & ~(MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)); @@ -13027,6 +13045,9 @@ static int zend_jit_incdec_obj(dasm_State **Dst, SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->result.var), IS_DOUBLE, 0); exit_point = zend_jit_trace_get_exit_point(opline + 1, 0); exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!exit_addr) { + return 0; + } SET_STACK_INFO(stack, EX_VAR_TO_NUM(opline->result.var), old_res_info); ssa->var_info[ssa_op->result_def].type = res_info & ~MAY_BE_GUARD; | b &exit_addr @@ -13320,6 +13341,9 @@ static int zend_jit_assign_obj_op(dasm_State **Dst, if (use_prop_guard) { int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0); const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!exit_addr) { + return 0; + } | IF_NOT_ZVAL_TYPE var_addr, prop_type, &exit_addr, ZREG_TMP1 var_info = (1 << prop_type) | (var_info & ~(MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)); @@ -14095,10 +14119,16 @@ static int zend_jit_switch(dasm_State **Dst, const zend_op *opline, const zend_o if (next_opline != opline + 1) { exit_point = zend_jit_trace_get_exit_point(opline + 1, 0); fallback_label = zend_jit_trace_get_exit_addr(exit_point); + if (!fallback_label) { + return 0; + } } if (next_opline != default_opline) { exit_point = zend_jit_trace_get_exit_point(default_opline, 0); default_label = zend_jit_trace_get_exit_addr(exit_point); + if (!default_label) { + return 0; + } } } diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 24936e94d37..ba6e52abbcc 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -4166,6 +4166,9 @@ static int zend_jit_inc_dec(dasm_State **Dst, const zend_op *opline, uint32_t op exit_point = zend_jit_trace_get_exit_point(opline + 1, 0); exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!exit_addr) { + return 0; + } | jo &exit_addr if ((opline->opcode == ZEND_PRE_INC || opline->opcode == ZEND_PRE_DEC) && @@ -4465,6 +4468,9 @@ static int zend_jit_math_long_long(dasm_State **Dst, if (res_info & MAY_BE_GUARD) { int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0); const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!exit_addr) { + return 0; + } if ((res_info & MAY_BE_ANY) == MAY_BE_LONG) { | jo &exit_addr if (Z_MODE(res_addr) == IS_REG && result_reg != Z_REG(res_addr)) { @@ -6852,6 +6858,9 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3 && !(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF) - (MAY_BE_LONG|MAY_BE_STRING)))) { int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0); not_found_exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!not_found_exit_addr) { + return 0; + } } if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_RW, op1_info, op2_info, dim_type, NULL, not_found_exit_addr, NULL)) { @@ -13235,6 +13244,9 @@ static int zend_jit_fetch_obj(dasm_State **Dst, && (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_OBJECT) { exit_point = zend_jit_trace_get_exit_point(opline, 0); exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!exit_addr) { + return 0; + } } else { val_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0); | LOAD_ZVAL_ADDR r0, prop_addr @@ -13626,6 +13638,9 @@ static int zend_jit_incdec_obj(dasm_State **Dst, if (use_prop_guard) { int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0); const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!exit_addr) { + return 0; + } | IF_NOT_ZVAL_TYPE var_addr, prop_type, &exit_addr var_info = (1 << prop_type) | (var_info & ~(MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)); @@ -13784,6 +13799,9 @@ static int zend_jit_incdec_obj(dasm_State **Dst, SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->result.var), IS_DOUBLE, 0); exit_point = zend_jit_trace_get_exit_point(opline + 1, 0); exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!exit_addr) { + return 0; + } SET_STACK_INFO(stack, EX_VAR_TO_NUM(opline->result.var), old_res_info); ssa->var_info[ssa_op->result_def].type = res_info & ~MAY_BE_GUARD; | jmp &exit_addr @@ -14107,6 +14125,9 @@ static int zend_jit_assign_obj_op(dasm_State **Dst, if (use_prop_guard) { int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0); const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!exit_addr) { + return 0; + } | IF_NOT_ZVAL_TYPE var_addr, prop_type, &exit_addr var_info = (1 << prop_type) | (var_info & ~(MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)); @@ -14807,6 +14828,10 @@ static int zend_jit_fetch_this(dasm_State **Dst, const zend_op *opline, const ze int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!exit_addr) { + return 0; + } + | cmp byte EX->This.u1.v.type, IS_OBJECT | jne &exit_addr @@ -14980,10 +15005,16 @@ static int zend_jit_switch(dasm_State **Dst, const zend_op *opline, const zend_o if (next_opline != opline + 1) { exit_point = zend_jit_trace_get_exit_point(opline + 1, 0); fallback_label = zend_jit_trace_get_exit_addr(exit_point); + if (!fallback_label) { + return 0; + } } if (next_opline != default_opline) { exit_point = zend_jit_trace_get_exit_point(default_opline, 0); default_label = zend_jit_trace_get_exit_addr(exit_point); + if (!default_label) { + return 0; + } } }