Skip to content

Commit 1d054b3

Browse files
committed
Fix array object clobbering by user error handler
Fixes oss-fuss #41605 and #41610
1 parent 2515e78 commit 1d054b3

File tree

4 files changed

+938
-141
lines changed

4 files changed

+938
-141
lines changed

Zend/zend_execute.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,9 +2318,15 @@ static zend_always_inline void zend_fetch_dimension_address(zval *result, zval *
23182318
ZVAL_UNDEF(result);
23192319
} else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
23202320
if (ZEND_CONST_COND(dim_type == IS_CV, dim != NULL) && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) {
2321+
zend_object *obj = Z_OBJ_P(container);
2322+
GC_ADDREF(obj);
23212323
dim = ZVAL_UNDEFINED_OP2();
2322-
}
2323-
if (dim_type == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
2324+
if (UNEXPECTED(GC_DELREF(obj) == 0)) {
2325+
zend_objects_store_del(obj);
2326+
ZVAL_NULL(result);
2327+
return;
2328+
}
2329+
} else if (dim_type == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
23242330
dim++;
23252331
}
23262332
retval = Z_OBJ_HT_P(container)->read_dimension(Z_OBJ_P(container), dim, type, result);

Zend/zend_vm_def.h

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,8 +1203,16 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array):
12031203
}
12041204

12051205
if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
1206-
dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
1207-
if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
1206+
dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
1207+
if (OP2_TYPE == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
1208+
zend_object *obj = Z_OBJ_P(container);
1209+
GC_ADDREF(obj);
1210+
dim = ZVAL_UNDEFINED_OP2();
1211+
if (UNEXPECTED(GC_DELREF(obj) == 0)) {
1212+
zend_objects_store_del(obj);
1213+
ZEND_VM_C_GOTO(assign_dim_op_ret_null);
1214+
}
1215+
} else if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
12081216
dim++;
12091217
}
12101218
zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC);
@@ -2575,12 +2583,32 @@ ZEND_VM_C_LABEL(try_assign_dim_array):
25752583
}
25762584
}
25772585
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
2578-
dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
2579-
value = GET_OP_DATA_ZVAL_PTR_DEREF(BP_VAR_R);
2580-
2581-
if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
2586+
dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
2587+
if (OP2_TYPE == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
2588+
zend_object *obj = Z_OBJ_P(object_ptr);
2589+
GC_ADDREF(obj);
2590+
dim = ZVAL_UNDEFINED_OP2();
2591+
if (UNEXPECTED(GC_DELREF(obj) == 0)) {
2592+
zend_objects_store_del(obj);
2593+
ZEND_VM_C_GOTO(assign_dim_error);
2594+
}
2595+
} else if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
25822596
dim++;
25832597
}
2598+
2599+
value = GET_OP_DATA_ZVAL_PTR_UNDEF(BP_VAR_R);
2600+
if (OP_DATA_TYPE == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
2601+
zend_object *obj = Z_OBJ_P(object_ptr);
2602+
GC_ADDREF(obj);
2603+
value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
2604+
if (UNEXPECTED(GC_DELREF(obj) == 0)) {
2605+
zend_objects_store_del(obj);
2606+
ZEND_VM_C_GOTO(assign_dim_error);
2607+
}
2608+
} else if (OP_DATA_TYPE & (IS_CV|IS_VAR)) {
2609+
ZVAL_DEREF(value);
2610+
}
2611+
25842612
zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
25852613

25862614
FREE_OP_DATA();

0 commit comments

Comments
 (0)