Skip to content

Commit a8bd342

Browse files
committedNov 14, 2022
Fix memory leak
Fizes oss-fuzz #53143
1 parent b8c1b5e commit a8bd342

File tree

3 files changed

+60
-17
lines changed

3 files changed

+60
-17
lines changed
 

‎ext/opcache/jit/zend_jit_arm64.dasc

+17-8
Original file line numberDiff line numberDiff line change
@@ -5579,7 +5579,8 @@ static int zend_jit_simple_assign(dasm_State **Dst,
55795579
uint32_t val_info,
55805580
zend_jit_addr res_addr,
55815581
int in_cold,
5582-
int save_r1)
5582+
int save_r1,
5583+
bool check_exception)
55835584
/* Labels: 1,2,3 */
55845585
{
55855586
zend_reg tmp_reg;
@@ -5629,7 +5630,9 @@ static int zend_jit_simple_assign(dasm_State **Dst,
56295630
ZEND_ASSERT(Z_MODE(val_addr) == IS_MEM_ZVAL && Z_REG(val_addr) == ZREG_FP);
56305631
| LOAD_32BIT_VAL FCARG1w, Z_OFFSET(val_addr)
56315632
| EXT_CALL zend_jit_undefined_op_helper, REG0
5632-
| cbz RETVALx, ->exception_handler_undef
5633+
if (check_exception) {
5634+
| cbz RETVALx, ->exception_handler_undef
5635+
}
56335636
if (save_r1) {
56345637
| ldr FCARG1x, T1 // restore
56355638
}
@@ -5938,15 +5941,15 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
59385941
if (!keep_gc) {
59395942
| str Rx(tmp_reg), T1 // save
59405943
}
5941-
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, in_cold, 0)) {
5944+
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, in_cold, 0, 0)) {
59425945
return 0;
59435946
}
59445947
if (!keep_gc) {
59455948
| ldr FCARG1x, T1 // restore
59465949
}
59475950
} else {
59485951
| GET_ZVAL_PTR FCARG1x, var_use_addr, TMP1
5949-
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, in_cold, 1)) {
5952+
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, in_cold, 1, 0)) {
59505953
return 0;
59515954
}
59525955
}
@@ -5958,7 +5961,7 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
59585961
}
59595962
| ZVAL_DTOR_FUNC var_info, opline, TMP1
59605963
if (in_cold || (RC_MAY_BE_N(var_info) && (var_info & (MAY_BE_ARRAY|MAY_BE_OBJECT)) != 0)) {
5961-
if (check_exception) {
5964+
if (check_exception && !(val_info & MAY_BE_UNDEF)) {
59625965
| MEM_LOAD_64_ZTS ldr, REG0, executor_globals, exception, TMP1
59635966
| cbz REG0, >8
59645967
| b ->exception_handler
@@ -5974,6 +5977,12 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
59745977
| b >8
59755978
}
59765979
}
5980+
if (check_exception && (val_info & MAY_BE_UNDEF)) {
5981+
|8:
5982+
| MEM_LOAD_64_ZTS ldr, REG0, executor_globals, exception, TMP1
5983+
| cbz REG0, >8
5984+
| b ->exception_handler
5985+
}
59775986
if (in_cold) {
59785987
|.code
59795988
} else {
@@ -6002,7 +6011,7 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
60026011
}
60036012
}
60046013

6005-
if (!done && !zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, 0, 0)) {
6014+
if (!done && !zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, 0, 0, check_exception)) {
60066015
return 0;
60076016
}
60086017

@@ -6102,7 +6111,7 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, uint32_t
61026111
| b >9
61036112
|.code
61046113

6105-
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, -1, (opline+1)->op1_type, op3_addr, val_info, res_addr, 0, 0)) {
6114+
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, -1, (opline+1)->op1_type, op3_addr, val_info, res_addr, 0, 0, 0)) {
61066115
return 0;
61076116
}
61086117
} else {
@@ -8453,7 +8462,7 @@ static int zend_jit_qm_assign(dasm_State **Dst, const zend_op *opline, uint32_t
84538462
}
84548463
}
84558464

8456-
if (!zend_jit_simple_assign(Dst, opline, res_addr, res_use_info, res_info, opline->op1_type, op1_addr, op1_info, 0, 0, 0)) {
8465+
if (!zend_jit_simple_assign(Dst, opline, res_addr, res_use_info, res_info, opline->op1_type, op1_addr, op1_info, 0, 0, 0, 1)) {
84578466
return 0;
84588467
}
84598468
if (!zend_jit_store_var_if_necessary(Dst, opline->result.var, res_addr, res_info)) {

‎ext/opcache/jit/zend_jit_x86.dasc

+18-9
Original file line numberDiff line numberDiff line change
@@ -6096,7 +6096,8 @@ static int zend_jit_simple_assign(dasm_State **Dst,
60966096
uint32_t val_info,
60976097
zend_jit_addr res_addr,
60986098
int in_cold,
6099-
int save_r1)
6099+
int save_r1,
6100+
bool check_exception)
61006101
/* Labels: 1,2,3 */
61016102
{
61026103
zend_reg tmp_reg;
@@ -6146,8 +6147,10 @@ static int zend_jit_simple_assign(dasm_State **Dst,
61466147
ZEND_ASSERT(Z_MODE(val_addr) == IS_MEM_ZVAL && Z_REG(val_addr) == ZREG_FP);
61476148
| mov FCARG1d, Z_OFFSET(val_addr)
61486149
| EXT_CALL zend_jit_undefined_op_helper, r0
6149-
| test r0, r0
6150-
| jz ->exception_handler_undef
6150+
if (check_exception) {
6151+
| test r0, r0
6152+
| jz ->exception_handler_undef
6153+
}
61516154
if (save_r1) {
61526155
| mov FCARG1a, aword T1 // restore
61536156
}
@@ -6462,15 +6465,15 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
64626465
if (!keep_gc) {
64636466
| mov aword T1, Ra(tmp_reg) // save
64646467
}
6465-
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, in_cold, 0)) {
6468+
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, in_cold, 0, 0)) {
64666469
return 0;
64676470
}
64686471
if (!keep_gc) {
64696472
| mov FCARG1a, aword T1 // restore
64706473
}
64716474
} else {
64726475
| GET_ZVAL_PTR FCARG1a, var_use_addr
6473-
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, in_cold, 1)) {
6476+
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, in_cold, 1, 0)) {
64746477
return 0;
64756478
}
64766479
}
@@ -6482,7 +6485,7 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
64826485
}
64836486
| ZVAL_DTOR_FUNC var_info, opline
64846487
if (in_cold || (RC_MAY_BE_N(var_info) && (var_info & (MAY_BE_ARRAY|MAY_BE_OBJECT)) != 0)) {
6485-
if (check_exception) {
6488+
if (check_exception && !(val_info & MAY_BE_UNDEF)) {
64866489
| MEM_CMP_ZTS aword, executor_globals, exception, 0, r0
64876490
| je >8
64886491
| jmp ->exception_handler
@@ -6498,6 +6501,12 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
64986501
| jmp >8
64996502
}
65006503
}
6504+
if (check_exception && (val_info & MAY_BE_UNDEF)) {
6505+
|8:
6506+
| MEM_CMP_ZTS aword, executor_globals, exception, 0, r0
6507+
| je >8
6508+
| jmp ->exception_handler
6509+
}
65016510
if (in_cold) {
65026511
|.code
65036512
} else {
@@ -6526,7 +6535,7 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
65266535
}
65276536
}
65286537

6529-
if (!done && !zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, 0, 0)) {
6538+
if (!done && !zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, 0, 0, check_exception)) {
65306539
return 0;
65316540
}
65326541

@@ -6624,7 +6633,7 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, uint32_t
66246633
| jmp >9
66256634
|.code
66266635

6627-
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, -1, (opline+1)->op1_type, op3_addr, val_info, res_addr, 0, 0)) {
6636+
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, -1, (opline+1)->op1_type, op3_addr, val_info, res_addr, 0, 0, 0)) {
66286637
return 0;
66296638
}
66306639
} else {
@@ -9045,7 +9054,7 @@ static int zend_jit_qm_assign(dasm_State **Dst, const zend_op *opline, uint32_t
90459054
}
90469055
}
90479056

9048-
if (!zend_jit_simple_assign(Dst, opline, res_addr, res_use_info, res_info, opline->op1_type, op1_addr, op1_info, 0, 0, 0)) {
9057+
if (!zend_jit_simple_assign(Dst, opline, res_addr, res_use_info, res_info, opline->op1_type, op1_addr, op1_info, 0, 0, 0, 1)) {
90499058
return 0;
90509059
}
90519060
if (!zend_jit_store_var_if_necessary(Dst, opline->result.var, res_addr, res_info)) {

‎ext/opcache/tests/jit/assign_055.phpt

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
JIT ASSIGN: memory leak
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_update_protection=0
7+
opcache.jit_buffer_size=1M
8+
opcache.protect_memory=1
9+
--FILE--
10+
<?php
11+
set_error_handler(function() {
12+
(y);
13+
});
14+
$ret = new stdClass;
15+
try {
16+
$ret = $y;
17+
} catch (y) {
18+
}
19+
?>
20+
--EXPECTF--
21+
Fatal error: Uncaught Error: Undefined constant "y" in %sassign_055.php:3
22+
Stack trace:
23+
#0 %sassign_055.php(7): {closure}(2, 'Undefined varia...', '%s', 7)
24+
#1 {main}
25+
thrown in %sassign_055.php on line 3

0 commit comments

Comments
 (0)