Skip to content

Commit d422478

Browse files
committed
Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3: Fix bug #76047
2 parents db7193f + ef1e489 commit d422478

File tree

6 files changed

+81
-13
lines changed

6 files changed

+81
-13
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ PHP NEWS
1010
. Fixed bug #78989 (Delayed variance check involving trait segfaults).
1111
(Nikita)
1212
. Fixed bug #79174 (cookie values with spaces fail to round-trip). (cmb)
13+
. Fixed bug #76047 (Use-after-free when accessing already destructed
14+
backtrace arguments). (Nikita)
1315

1416
- CURL:
1517
. Fixed bug #79078 (Hypothetical use-after-free in curl_multi_add_handle()).

Zend/tests/bug52361.phpt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ try {
2525
--EXPECTF--
2626
1. Exception: aaa in %sbug52361.php:5
2727
Stack trace:
28-
#0 %sbug52361.php(13): aaa->__destruct()
29-
#1 %sbug52361.php(16): bbb()
30-
#2 {main}
28+
#0 %sbug52361.php(16): aaa->__destruct()
29+
#1 {main}
3130
2. Exception: bbb in %sbug52361.php:13
3231
Stack trace:
3332
#0 %sbug52361.php(16): bbb()

Zend/tests/bug76047.phpt

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
--TEST--
2+
Bug #76047: Use-after-free when accessing already destructed backtrace arguments
3+
--FILE--
4+
<?php
5+
6+
class Vuln {
7+
public $a;
8+
public function __destruct() {
9+
unset($this->a);
10+
$backtrace = (new Exception)->getTrace();
11+
var_dump($backtrace);
12+
}
13+
}
14+
15+
function test($arg) {
16+
$arg = str_shuffle(str_repeat('A', 79));
17+
$vuln = new Vuln();
18+
$vuln->a = $arg;
19+
}
20+
21+
function test2($arg) {
22+
$$arg = 1; // Trigger symbol table
23+
$arg = str_shuffle(str_repeat('A', 79));
24+
$vuln = new Vuln();
25+
$vuln->a = $arg;
26+
}
27+
28+
test('x');
29+
test2('x');
30+
31+
?>
32+
--EXPECTF--
33+
array(1) {
34+
[0]=>
35+
array(6) {
36+
["file"]=>
37+
string(%d) "%s"
38+
["line"]=>
39+
int(%d)
40+
["function"]=>
41+
string(10) "__destruct"
42+
["class"]=>
43+
string(4) "Vuln"
44+
["type"]=>
45+
string(2) "->"
46+
["args"]=>
47+
array(0) {
48+
}
49+
}
50+
}
51+
array(1) {
52+
[0]=>
53+
array(6) {
54+
["file"]=>
55+
string(%d) "%s"
56+
["line"]=>
57+
int(%d)
58+
["function"]=>
59+
string(10) "__destruct"
60+
["class"]=>
61+
string(4) "Vuln"
62+
["type"]=>
63+
string(2) "->"
64+
["args"]=>
65+
array(0) {
66+
}
67+
}
68+
}

Zend/tests/bug78973.phpt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,3 @@ test(new class {
1616
?>
1717
--EXPECTF--
1818
#0 class@anonymous->__destruct() called at [%s:%d]
19-
#1 test() called at [%s:%d]

Zend/zend_vm_def.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2876,12 +2876,12 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY)
28762876
SAVE_OPLINE();
28772877

28782878
if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) {
2879+
EG(current_execute_data) = EX(prev_execute_data);
28792880
i_free_compiled_variables(execute_data);
28802881

28812882
#ifdef ZEND_PREFER_RELOAD
28822883
call_info = EX_CALL_INFO();
28832884
#endif
2884-
EG(current_execute_data) = EX(prev_execute_data);
28852885
if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
28862886
OBJ_RELEASE(Z_OBJ(execute_data->This));
28872887
} else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
@@ -2898,6 +2898,7 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY)
28982898
LOAD_NEXT_OPLINE();
28992899
ZEND_VM_LEAVE();
29002900
} else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) {
2901+
EG(current_execute_data) = EX(prev_execute_data);
29012902
i_free_compiled_variables(execute_data);
29022903

29032904
#ifdef ZEND_PREFER_RELOAD
@@ -2906,7 +2907,6 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY)
29062907
if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
29072908
zend_clean_and_cache_symbol_table(EX(symbol_table));
29082909
}
2909-
EG(current_execute_data) = EX(prev_execute_data);
29102910

29112911
/* Free extra args before releasing the closure,
29122912
* as that may free the op_array. */
@@ -2950,6 +2950,7 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY)
29502950
ZEND_VM_LEAVE();
29512951
} else {
29522952
if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) {
2953+
EG(current_execute_data) = EX(prev_execute_data);
29532954
i_free_compiled_variables(execute_data);
29542955
#ifdef ZEND_PREFER_RELOAD
29552956
call_info = EX_CALL_INFO();
@@ -2960,7 +2961,6 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY)
29602961
}
29612962
zend_vm_stack_free_extra_args_ex(call_info, execute_data);
29622963
}
2963-
EG(current_execute_data) = EX(prev_execute_data);
29642964
if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
29652965
OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
29662966
}

Zend/zend_vm_execute.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,12 +1133,12 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper
11331133
SAVE_OPLINE();
11341134

11351135
if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) {
1136+
EG(current_execute_data) = EX(prev_execute_data);
11361137
i_free_compiled_variables(execute_data);
11371138

11381139
#ifdef ZEND_PREFER_RELOAD
11391140
call_info = EX_CALL_INFO();
11401141
#endif
1141-
EG(current_execute_data) = EX(prev_execute_data);
11421142
if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
11431143
OBJ_RELEASE(Z_OBJ(execute_data->This));
11441144
} else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
@@ -1155,6 +1155,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper
11551155
LOAD_NEXT_OPLINE();
11561156
ZEND_VM_LEAVE();
11571157
} else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) {
1158+
EG(current_execute_data) = EX(prev_execute_data);
11581159
i_free_compiled_variables(execute_data);
11591160

11601161
#ifdef ZEND_PREFER_RELOAD
@@ -1163,7 +1164,6 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper
11631164
if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
11641165
zend_clean_and_cache_symbol_table(EX(symbol_table));
11651166
}
1166-
EG(current_execute_data) = EX(prev_execute_data);
11671167

11681168
/* Free extra args before releasing the closure,
11691169
* as that may free the op_array. */
@@ -1207,6 +1207,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper
12071207
ZEND_VM_LEAVE();
12081208
} else {
12091209
if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) {
1210+
EG(current_execute_data) = EX(prev_execute_data);
12101211
i_free_compiled_variables(execute_data);
12111212
#ifdef ZEND_PREFER_RELOAD
12121213
call_info = EX_CALL_INFO();
@@ -1217,7 +1218,6 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper
12171218
}
12181219
zend_vm_stack_free_extra_args_ex(call_info, execute_data);
12191220
}
1220-
EG(current_execute_data) = EX(prev_execute_data);
12211221
if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
12221222
OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
12231223
}
@@ -53675,12 +53675,12 @@ ZEND_API void execute_ex(zend_execute_data *ex)
5367553675
SAVE_OPLINE();
5367653676

5367753677
if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) {
53678+
EG(current_execute_data) = EX(prev_execute_data);
5367853679
i_free_compiled_variables(execute_data);
5367953680

5368053681
#ifdef ZEND_PREFER_RELOAD
5368153682
call_info = EX_CALL_INFO();
5368253683
#endif
53683-
EG(current_execute_data) = EX(prev_execute_data);
5368453684
if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
5368553685
OBJ_RELEASE(Z_OBJ(execute_data->This));
5368653686
} else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
@@ -53697,6 +53697,7 @@ ZEND_API void execute_ex(zend_execute_data *ex)
5369753697
LOAD_NEXT_OPLINE();
5369853698
ZEND_VM_LEAVE();
5369953699
} else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) {
53700+
EG(current_execute_data) = EX(prev_execute_data);
5370053701
i_free_compiled_variables(execute_data);
5370153702

5370253703
#ifdef ZEND_PREFER_RELOAD
@@ -53705,7 +53706,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
5370553706
if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
5370653707
zend_clean_and_cache_symbol_table(EX(symbol_table));
5370753708
}
53708-
EG(current_execute_data) = EX(prev_execute_data);
5370953709

5371053710
/* Free extra args before releasing the closure,
5371153711
* as that may free the op_array. */
@@ -53749,6 +53749,7 @@ ZEND_API void execute_ex(zend_execute_data *ex)
5374953749
ZEND_VM_LEAVE();
5375053750
} else {
5375153751
if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) {
53752+
EG(current_execute_data) = EX(prev_execute_data);
5375253753
i_free_compiled_variables(execute_data);
5375353754
#ifdef ZEND_PREFER_RELOAD
5375453755
call_info = EX_CALL_INFO();
@@ -53759,7 +53760,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
5375953760
}
5376053761
zend_vm_stack_free_extra_args_ex(call_info, execute_data);
5376153762
}
53762-
EG(current_execute_data) = EX(prev_execute_data);
5376353763
if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
5376453764
OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
5376553765
}

0 commit comments

Comments
 (0)