Skip to content

Commit fe1f613

Browse files
committed
Merge branch 'PHP-8.1'
* PHP-8.1: Fix use after free because of data clobbering by user error handler
2 parents ebb7b17 + 5459ed4 commit fe1f613

File tree

5 files changed

+561
-196
lines changed

5 files changed

+561
-196
lines changed

Zend/tests/falsetoarray_002.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
Autovivification of false to array with data clobbering by error handler
3+
--FILE--
4+
<?php
5+
set_error_handler(function($code, $msg) {
6+
echo "Err: $msg\n";
7+
$GLOBALS['a']='';
8+
});
9+
$a=[!'a'];
10+
$a[0][$d]='b';
11+
var_dump($a);
12+
?>
13+
--EXPECT--
14+
Err: Automatic conversion of false to array is deprecated
15+
string(0) ""

Zend/zend_execute.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2434,13 +2434,24 @@ static zend_always_inline void zend_fetch_dimension_address(zval *result, zval *
24342434
if (type != BP_VAR_W && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
24352435
ZVAL_UNDEFINED_OP1();
24362436
}
2437-
if (Z_TYPE_P(container) == IS_FALSE) {
2438-
zend_false_to_array_deprecated();
2439-
}
24402437
if (type != BP_VAR_UNSET) {
2441-
array_init(container);
2438+
HashTable *ht = zend_new_array(0);
2439+
zend_uchar old_type = Z_TYPE_P(container);
2440+
2441+
ZVAL_ARR(container, ht);
2442+
if (UNEXPECTED(old_type == IS_FALSE)) {
2443+
GC_ADDREF(ht);
2444+
zend_false_to_array_deprecated();
2445+
if (UNEXPECTED(GC_DELREF(ht) == 0)) {
2446+
zend_array_destroy(ht);
2447+
goto return_null;
2448+
}
2449+
}
24422450
goto fetch_from_array;
24432451
} else {
2452+
if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) {
2453+
zend_false_to_array_deprecated();
2454+
}
24442455
return_null:
24452456
/* for read-mode only */
24462457
if (ZEND_CONST_COND(dim_type == IS_CV, dim != NULL) && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) {

Zend/zend_vm_def.h

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,13 +1217,23 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array):
12171217
}
12181218
zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC);
12191219
} else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
1220+
HashTable *ht;
1221+
zend_uchar old_type;
1222+
12201223
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
12211224
ZVAL_UNDEFINED_OP1();
12221225
}
1223-
if (Z_TYPE_P(container) == IS_FALSE) {
1226+
ht = zend_new_array(8);
1227+
old_type = Z_TYPE_P(container);
1228+
ZVAL_ARR(container, ht);
1229+
if (UNEXPECTED(old_type == IS_FALSE)) {
1230+
GC_ADDREF(ht);
12241231
zend_false_to_array_deprecated();
1232+
if (UNEXPECTED(GC_DELREF(ht) == 0)) {
1233+
zend_array_destroy(ht);
1234+
ZEND_VM_C_GOTO(assign_dim_op_ret_null);
1235+
}
12251236
}
1226-
ZVAL_ARR(container, zend_new_array(8));
12271237
ZEND_VM_C_GOTO(assign_dim_op_new_array);
12281238
} else {
12291239
dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
@@ -2635,18 +2645,25 @@ ZEND_VM_C_LABEL(try_assign_dim_array):
26352645
FREE_OP_DATA();
26362646
}
26372647
} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
2638-
if (Z_TYPE_P(object_ptr) == IS_FALSE) {
2639-
zend_false_to_array_deprecated();
2640-
}
2641-
26422648
if (Z_ISREF_P(orig_object_ptr)
26432649
&& ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
26442650
&& !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
26452651
dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
26462652
FREE_OP_DATA();
26472653
UNDEF_RESULT();
26482654
} else {
2649-
ZVAL_ARR(object_ptr, zend_new_array(8));
2655+
HashTable *ht = zend_new_array(8);
2656+
zend_uchar old_type = Z_TYPE_P(object_ptr);
2657+
2658+
ZVAL_ARR(object_ptr, ht);
2659+
if (UNEXPECTED(old_type == IS_FALSE)) {
2660+
GC_ADDREF(ht);
2661+
zend_false_to_array_deprecated();
2662+
if (UNEXPECTED(GC_DELREF(ht) == 0)) {
2663+
zend_array_destroy(ht);
2664+
ZEND_VM_C_GOTO(assign_dim_error);
2665+
}
2666+
}
26502667
ZEND_VM_C_GOTO(try_assign_dim_array);
26512668
}
26522669
} else {

0 commit comments

Comments
 (0)