Skip to content

Commit 261a08a

Browse files
committed
JIT: Fix incorrect EX(opline) override
Fixes oss-fuzz #52674
1 parent 2caa79e commit 261a08a

File tree

3 files changed

+50
-20
lines changed

3 files changed

+50
-20
lines changed

ext/opcache/jit/zend_jit_arm64.dasc

+13-10
Original file line numberDiff line numberDiff line change
@@ -5342,7 +5342,6 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
53425342
| // hval = Z_LVAL_P(dim);
53435343
| GET_ZVAL_LVAL ZREG_FCARG2, op2_addr, TMP1
53445344
}
5345-
| SET_EX_OPLINE opline, REG0
53465345
if (packed_loaded) {
53475346
| EXT_CALL zend_jit_hash_index_lookup_rw_no_packed, REG0
53485347
} else {
@@ -5465,7 +5464,6 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
54655464
}
54665465
break;
54675466
case BP_VAR_RW:
5468-
| SET_EX_OPLINE opline, REG0
54695467
if (opline->op2_type != IS_CONST) {
54705468
| EXT_CALL zend_jit_symtable_lookup_rw, REG0
54715469
} else {
@@ -5512,7 +5510,9 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
55125510
|.cold_code
55135511
|3:
55145512
}
5515-
| SET_EX_OPLINE opline, REG0
5513+
if (type != BP_VAR_RW) {
5514+
| SET_EX_OPLINE opline, REG0
5515+
}
55165516
| LOAD_ZVAL_ADDR FCARG2x, op2_addr
55175517
switch (type) {
55185518
case BP_VAR_R:
@@ -6233,6 +6233,7 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
62336233
op2_addr = (opline->op2_type != IS_UNUSED) ? OP2_ADDR() : 0;
62346234
op3_addr = OP1_DATA_ADDR();
62356235

6236+
| SET_EX_OPLINE opline, REG0
62366237
if (op1_info & MAY_BE_REF) {
62376238
| LOAD_ZVAL_ADDR FCARG1x, op1_addr
62386239
| IF_NOT_Z_TYPE FCARG1x, IS_REFERENCE, >1, TMP1w
@@ -6244,7 +6245,6 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
62446245
| b >3
62456246
|.cold_code
62466247
|2:
6247-
| SET_EX_OPLINE opline, REG0
62486248
| EXT_CALL zend_jit_prepare_assign_dim_ref, REG0
62496249
| mov FCARG1x, RETVALx
62506250
| cbnz RETVALx, >1
@@ -6277,7 +6277,6 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
62776277
if (op1_info & MAY_BE_NULL) {
62786278
| IF_NOT_ZVAL_TYPE op1_addr, IS_UNDEF, >1, ZREG_TMP1
62796279
}
6280-
| SET_EX_OPLINE opline, REG0
62816280
| LOAD_32BIT_VAL FCARG1x, opline->op1.var
62826281
| EXT_CALL zend_jit_undefined_op_helper, REG0
62836282
|1:
@@ -6359,7 +6358,6 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
63596358
|2:
63606359
| LOAD_ZVAL_ADDR FCARG2x, op3_addr
63616360
| LOAD_ADDR CARG3, binary_op
6362-
| SET_EX_OPLINE opline, REG0
63636361
if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR))
63646362
&& (op1_data_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
63656363
| EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, REG0
@@ -6417,7 +6415,6 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
64176415
|7:
64186416
}
64196417

6420-
| SET_EX_OPLINE opline, REG0
64216418
if (Z_REG(op1_addr) != ZREG_FCARG1 || Z_OFFSET(op1_addr) != 0) {
64226419
| LOAD_ZVAL_ADDR FCARG1x, op1_addr
64236420
}
@@ -11532,6 +11529,9 @@ static int zend_jit_fetch_dim(dasm_State **Dst,
1153211529

1153311530
op2_addr = (opline->op2_type != IS_UNUSED) ? OP2_ADDR() : 0;
1153411531

11532+
if (opline->opcode == ZEND_FETCH_DIM_RW) {
11533+
| SET_EX_OPLINE opline, REG0
11534+
}
1153511535
if (op1_info & MAY_BE_REF) {
1153611536
may_throw = 1;
1153711537
| LOAD_ZVAL_ADDR FCARG1x, op1_addr
@@ -11545,7 +11545,9 @@ static int zend_jit_fetch_dim(dasm_State **Dst,
1154511545
|.cold_code
1154611546
|2:
1154711547
| SET_EX_OPLINE opline, REG0
11548-
| EXT_CALL zend_jit_prepare_assign_dim_ref, REG0
11548+
if (if (opline->opcode != ZEND_FETCH_DIM_RW) {
11549+
| EXT_CALL zend_jit_prepare_assign_dim_ref, REG0
11550+
}
1154911551
| mov FCARG1x, RETVALx
1155011552
| cbnz FCARG1x, >1
1155111553
| b ->exception_handler_undef
@@ -11579,7 +11581,6 @@ static int zend_jit_fetch_dim(dasm_State **Dst,
1157911581
if (op1_info & MAY_BE_NULL) {
1158011582
| IF_NOT_ZVAL_TYPE op1_addr, IS_UNDEF, >1, ZREG_TMP1
1158111583
}
11582-
| SET_EX_OPLINE opline, REG0
1158311584
| LOAD_32BIT_VAL FCARG1w, opline->op1.var
1158411585
| EXT_CALL zend_jit_undefined_op_helper, REG0
1158511586
|1:
@@ -11666,7 +11667,9 @@ static int zend_jit_fetch_dim(dasm_State **Dst,
1166611667
|7:
1166711668
}
1166811669

11669-
| SET_EX_OPLINE opline, REG0
11670+
if (opline->opcode != ZEND_FETCH_DIM_RW) {
11671+
| SET_EX_OPLINE opline, REG0
11672+
}
1167011673
if (Z_REG(op1_addr) != ZREG_FCARG1 || Z_OFFSET(op1_addr) != 0) {
1167111674
| LOAD_ZVAL_ADDR FCARG1x, op1_addr
1167211675
}

ext/opcache/jit/zend_jit_x86.dasc

+13-10
Original file line numberDiff line numberDiff line change
@@ -5850,7 +5850,6 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
58505850
| // hval = Z_LVAL_P(dim);
58515851
| GET_ZVAL_LVAL ZREG_FCARG2, op2_addr
58525852
}
5853-
| SET_EX_OPLINE opline, r0
58545853
if (packed_loaded) {
58555854
| EXT_CALL zend_jit_hash_index_lookup_rw_no_packed, r0
58565855
} else {
@@ -5970,7 +5969,6 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
59705969
}
59715970
break;
59725971
case BP_VAR_RW:
5973-
| SET_EX_OPLINE opline, r0
59745972
if (opline->op2_type != IS_CONST) {
59755973
| EXT_CALL zend_jit_symtable_lookup_rw, r0
59765974
} else {
@@ -6015,7 +6013,9 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
60156013
|.cold_code
60166014
|3:
60176015
}
6018-
| SET_EX_OPLINE opline, r0
6016+
if (type != BP_VAR_RW) {
6017+
| SET_EX_OPLINE opline, r0
6018+
}
60196019
| LOAD_ZVAL_ADDR FCARG2a, op2_addr
60206020
switch (type) {
60216021
case BP_VAR_R:
@@ -6772,6 +6772,7 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
67726772
op2_addr = (opline->op2_type != IS_UNUSED) ? OP2_ADDR() : 0;
67736773
op3_addr = OP1_DATA_ADDR();
67746774

6775+
| SET_EX_OPLINE opline, r0
67756776
if (op1_info & MAY_BE_REF) {
67766777
| LOAD_ZVAL_ADDR FCARG1a, op1_addr
67776778
| IF_NOT_Z_TYPE FCARG1a, IS_REFERENCE, >1
@@ -6781,7 +6782,6 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
67816782
| jmp >3
67826783
|.cold_code
67836784
|2:
6784-
| SET_EX_OPLINE opline, r0
67856785
| EXT_CALL zend_jit_prepare_assign_dim_ref, r0
67866786
| test r0, r0
67876787
| mov FCARG1a, r0
@@ -6815,7 +6815,6 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
68156815
if (op1_info & MAY_BE_NULL) {
68166816
| IF_NOT_ZVAL_TYPE op1_addr, IS_UNDEF, >1
68176817
}
6818-
| SET_EX_OPLINE opline, r0
68196818
| mov FCARG1a, opline->op1.var
68206819
| EXT_CALL zend_jit_undefined_op_helper, r0
68216820
|1:
@@ -6901,7 +6900,6 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
69016900
| sub r4, 12
69026901
| PUSH_ADDR binary_op, r0
69036902
|.endif
6904-
| SET_EX_OPLINE opline, r0
69056903
if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR))
69066904
&& (op1_data_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
69076905
| EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, r0
@@ -6962,7 +6960,6 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
69626960
|7:
69636961
}
69646962

6965-
| SET_EX_OPLINE opline, r0
69666963
if (Z_REG(op1_addr) != ZREG_FCARG1 || Z_OFFSET(op1_addr) != 0) {
69676964
| LOAD_ZVAL_ADDR FCARG1a, op1_addr
69686965
}
@@ -12236,6 +12233,9 @@ static int zend_jit_fetch_dim(dasm_State **Dst,
1223612233

1223712234
op2_addr = (opline->op2_type != IS_UNUSED) ? OP2_ADDR() : 0;
1223812235

12236+
if (opline->opcode == ZEND_FETCH_DIM_RW) {
12237+
| SET_EX_OPLINE opline, r0
12238+
}
1223912239
if (op1_info & MAY_BE_REF) {
1224012240
may_throw = 1;
1224112241
| LOAD_ZVAL_ADDR FCARG1a, op1_addr
@@ -12246,7 +12246,9 @@ static int zend_jit_fetch_dim(dasm_State **Dst,
1224612246
| jmp >3
1224712247
|.cold_code
1224812248
|2:
12249-
| SET_EX_OPLINE opline, r0
12249+
if (opline->opcode != ZEND_FETCH_DIM_RW) {
12250+
| SET_EX_OPLINE opline, r0
12251+
}
1225012252
| EXT_CALL zend_jit_prepare_assign_dim_ref, r0
1225112253
| test r0, r0
1225212254
| mov FCARG1a, r0
@@ -12282,7 +12284,6 @@ static int zend_jit_fetch_dim(dasm_State **Dst,
1228212284
if (op1_info & MAY_BE_NULL) {
1228312285
| IF_NOT_ZVAL_TYPE op1_addr, IS_UNDEF, >1
1228412286
}
12285-
| SET_EX_OPLINE opline, r0
1228612287
| mov FCARG1a, opline->op1.var
1228712288
| EXT_CALL zend_jit_undefined_op_helper, r0
1228812289
|1:
@@ -12369,7 +12370,9 @@ static int zend_jit_fetch_dim(dasm_State **Dst,
1236912370
|7:
1237012371
}
1237112372

12372-
| SET_EX_OPLINE opline, r0
12373+
if (opline->opcode != ZEND_FETCH_DIM_RW) {
12374+
| SET_EX_OPLINE opline, r0
12375+
}
1237312376
if (Z_REG(op1_addr) != ZREG_FCARG1 || Z_OFFSET(op1_addr) != 0) {
1237412377
| LOAD_ZVAL_ADDR FCARG1a, op1_addr
1237512378
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
JIT FETCH_DIM_RW: 004
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_update_protection=0
7+
opcache.jit_buffer_size=1M
8+
--FILE--
9+
<?php
10+
set_error_handler(function(y$y) {
11+
});
12+
$k=[];
13+
$y[$k]++;
14+
?>
15+
--EXPECTF--
16+
Fatal error: Uncaught TypeError: {closure}(): Argument #1 ($y) must be of type y, int given, called in %sfetch_dim_rw_004.php on line 5 and defined in /home/dmitry/php/php8.1/ext/opcache/tests/jit/fetch_dim_rw_004.php:2
17+
Stack trace:
18+
#0 %sfetch_dim_rw_004.php(5): {closure}(2, 'Undefined varia...', '%s', 5)
19+
#1 {main}
20+
21+
Next TypeError: Illegal offset type in %sfetch_dim_rw_004.php:5
22+
Stack trace:
23+
#0 {main}
24+
thrown in %sfetch_dim_rw_004.php on line 5

0 commit comments

Comments
 (0)