Skip to content

Commit b740bb3

Browse files
committed
Fixed bug #72907 (null pointer deref, segfault in gc_remove_zval_from_buffer (zend_gc.c:260))
1 parent b12ac31 commit b740bb3

File tree

5 files changed

+63
-28
lines changed

5 files changed

+63
-28
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? 2016, PHP 5.6.26
44

5+
- Core:
6+
. Fixed bug #72907 (null pointer deref, segfault in gc_remove_zval_from_buffer
7+
(zend_gc.c:260)). (Laruence)
8+
59
- Streams:
610
. Fixed bug #72853 (stream_set_blocking doesn't work). (Laruence)
711

Zend/tests/bug72907.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Bug #72907 (null pointer deref, segfault in gc_remove_zval_from_buffer (zend_gc.c:260))
3+
--FILE--
4+
<?php
5+
6+
$a = 0;
7+
8+
($a->a = &$E) + ($b = $a->b->i -= 0);
9+
10+
?>
11+
--EXPECTF--
12+
Warning: Attempt to modify property of non-object in %sbug72907.php on line %d
13+
14+
Warning: Attempt to modify property of non-object in %sbug72907.php on line %d
15+
16+
Warning: Creating default object from empty value in %sbug72907.php on line %d
17+
18+
Notice: Undefined property: stdClass::$i in %sbug72907.php on line %d

Zend/zend_execute.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -522,9 +522,7 @@ static void zend_assign_to_variable_reference(zval **variable_ptr_ptr, zval **va
522522
zval *variable_ptr = *variable_ptr_ptr;
523523
zval *value_ptr = *value_ptr_ptr;
524524

525-
if (variable_ptr == &EG(error_zval) || value_ptr == &EG(error_zval)) {
526-
variable_ptr_ptr = &EG(uninitialized_zval_ptr);
527-
} else if (variable_ptr != value_ptr) {
525+
if (variable_ptr != value_ptr) {
528526
if (!PZVAL_IS_REF(value_ptr)) {
529527
/* break it away */
530528
Z_DELREF_P(value_ptr);

Zend/zend_vm_def.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1817,11 +1817,14 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
18171817
if ((OP2_TYPE == IS_VAR && UNEXPECTED(value_ptr_ptr == NULL)) ||
18181818
(OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL))) {
18191819
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
1820-
}
1821-
zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
1822-
1823-
if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
1824-
Z_DELREF_PP(variable_ptr_ptr);
1820+
} else if ((OP2_TYPE == IS_VAR && UNEXPECTED(*value_ptr_ptr == &EG(error_zval))) ||
1821+
(OP1_TYPE == IS_VAR && UNEXPECTED(*variable_ptr_ptr == &EG(error_zval)))) {
1822+
variable_ptr_ptr = &EG(uninitialized_zval_ptr);
1823+
} else {
1824+
zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
1825+
if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
1826+
Z_DELREF_PP(variable_ptr_ptr);
1827+
}
18251828
}
18261829

18271830
if (RETURN_VALUE_USED(opline)) {

Zend/zend_vm_execute.h

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20408,11 +20408,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
2040820408
if ((IS_VAR == IS_VAR && UNEXPECTED(value_ptr_ptr == NULL)) ||
2040920409
(IS_VAR == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL))) {
2041020410
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
20411-
}
20412-
zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
20413-
20414-
if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
20415-
Z_DELREF_PP(variable_ptr_ptr);
20411+
} else if ((IS_VAR == IS_VAR && UNEXPECTED(*value_ptr_ptr == &EG(error_zval))) ||
20412+
(IS_VAR == IS_VAR && UNEXPECTED(*variable_ptr_ptr == &EG(error_zval)))) {
20413+
variable_ptr_ptr = &EG(uninitialized_zval_ptr);
20414+
} else {
20415+
zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
20416+
if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
20417+
Z_DELREF_PP(variable_ptr_ptr);
20418+
}
2041620419
}
2041720420

2041820421
if (RETURN_VALUE_USED(opline)) {
@@ -23903,11 +23906,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
2390323906
if ((IS_CV == IS_VAR && UNEXPECTED(value_ptr_ptr == NULL)) ||
2390423907
(IS_VAR == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL))) {
2390523908
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
23906-
}
23907-
zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
23908-
23909-
if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
23910-
Z_DELREF_PP(variable_ptr_ptr);
23909+
} else if ((IS_CV == IS_VAR && UNEXPECTED(*value_ptr_ptr == &EG(error_zval))) ||
23910+
(IS_VAR == IS_VAR && UNEXPECTED(*variable_ptr_ptr == &EG(error_zval)))) {
23911+
variable_ptr_ptr = &EG(uninitialized_zval_ptr);
23912+
} else {
23913+
zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
23914+
if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
23915+
Z_DELREF_PP(variable_ptr_ptr);
23916+
}
2391123917
}
2391223918

2391323919
if (RETURN_VALUE_USED(opline)) {
@@ -37721,11 +37727,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
3772137727
if ((IS_VAR == IS_VAR && UNEXPECTED(value_ptr_ptr == NULL)) ||
3772237728
(IS_CV == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL))) {
3772337729
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
37724-
}
37725-
zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
37726-
37727-
if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
37728-
Z_DELREF_PP(variable_ptr_ptr);
37730+
} else if ((IS_VAR == IS_VAR && UNEXPECTED(*value_ptr_ptr == &EG(error_zval))) ||
37731+
(IS_CV == IS_VAR && UNEXPECTED(*variable_ptr_ptr == &EG(error_zval)))) {
37732+
variable_ptr_ptr = &EG(uninitialized_zval_ptr);
37733+
} else {
37734+
zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
37735+
if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
37736+
Z_DELREF_PP(variable_ptr_ptr);
37737+
}
3772937738
}
3773037739

3773137740
if (RETURN_VALUE_USED(opline)) {
@@ -40929,11 +40938,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
4092940938
if ((IS_CV == IS_VAR && UNEXPECTED(value_ptr_ptr == NULL)) ||
4093040939
(IS_CV == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL))) {
4093140940
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
40932-
}
40933-
zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
40934-
40935-
if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
40936-
Z_DELREF_PP(variable_ptr_ptr);
40941+
} else if ((IS_CV == IS_VAR && UNEXPECTED(*value_ptr_ptr == &EG(error_zval))) ||
40942+
(IS_CV == IS_VAR && UNEXPECTED(*variable_ptr_ptr == &EG(error_zval)))) {
40943+
variable_ptr_ptr = &EG(uninitialized_zval_ptr);
40944+
} else {
40945+
zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
40946+
if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
40947+
Z_DELREF_PP(variable_ptr_ptr);
40948+
}
4093740949
}
4093840950

4093940951
if (RETURN_VALUE_USED(opline)) {

0 commit comments

Comments
 (0)