Skip to content

Commit 5518165

Browse files
committed
Fix EG(current_execute_data) introduced in 1292037
Fixes OSS-Fuzz #456317305
1 parent 6fe40de commit 5518165

File tree

3 files changed

+45
-13
lines changed

3 files changed

+45
-13
lines changed

Zend/tests/oss_fuzz_456317305.phpt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
OSS-Fuzz #456317305: EG(current_execute_data) NULL pointer violation
3+
--FILE--
4+
<?php
5+
6+
class C {
7+
public function __destruct() {
8+
static $again = true;
9+
if ($again) {
10+
$again = false;
11+
$c = new C;
12+
}
13+
throw new Exception;
14+
}
15+
}
16+
17+
$c = new C;
18+
19+
?>
20+
--EXPECTF--
21+
Fatal error: Uncaught Exception in %s:%d
22+
Stack trace:
23+
#0 [internal function]: C->__destruct()
24+
#1 {main}
25+
thrown in %s on line %d

Zend/zend_generators.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -321,9 +321,11 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
321321
zend_object *old_exception = NULL;
322322
const zend_op *old_opline_before_exception = NULL;
323323
if (EG(exception)) {
324-
EG(current_execute_data)->opline = EG(opline_before_exception);
324+
if (EG(current_execute_data)) {
325+
EG(current_execute_data)->opline = EG(opline_before_exception);
326+
old_opline_before_exception = EG(opline_before_exception);
327+
}
325328
old_exception = EG(exception);
326-
old_opline_before_exception = EG(opline_before_exception);
327329
EG(exception) = NULL;
328330
}
329331

@@ -335,8 +337,10 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
335337
zend_generator_resume(generator);
336338

337339
if (old_exception) {
338-
EG(current_execute_data)->opline = EG(exception_op);
339-
EG(opline_before_exception) = old_opline_before_exception;
340+
if (EG(current_execute_data)) {
341+
EG(current_execute_data)->opline = EG(exception_op);
342+
EG(opline_before_exception) = old_opline_before_exception;
343+
}
340344
if (EG(exception)) {
341345
zend_exception_set_previous(EG(exception), old_exception);
342346
} else {

Zend/zend_objects.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
100100

101101
if (destructor) {
102102
zend_object *old_exception;
103-
const zend_op *old_opline_before_exception;
103+
const zend_op *old_opline_before_exception = NULL;
104104

105105
if (destructor->op_array.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) {
106106
if (destructor->op_array.fn_flags & ZEND_ACC_PRIVATE) {
@@ -159,23 +159,26 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
159159
if (EG(exception) == object) {
160160
zend_error_noreturn(E_CORE_ERROR, "Attempt to destruct pending exception");
161161
} else {
162-
if (EG(current_execute_data)
163-
&& EG(current_execute_data)->func
164-
&& ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) {
165-
zend_rethrow_exception(EG(current_execute_data));
162+
if (EG(current_execute_data)) {
163+
if (EG(current_execute_data)->func
164+
&& ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) {
165+
zend_rethrow_exception(EG(current_execute_data));
166+
}
167+
EG(current_execute_data)->opline = EG(opline_before_exception);
168+
old_opline_before_exception = EG(opline_before_exception);
166169
}
167-
EG(current_execute_data)->opline = EG(opline_before_exception);
168170
old_exception = EG(exception);
169-
old_opline_before_exception = EG(opline_before_exception);
170171
EG(exception) = NULL;
171172
}
172173
}
173174

174175
zend_call_known_instance_method_with_0_params(destructor, object, NULL);
175176

176177
if (old_exception) {
177-
EG(current_execute_data)->opline = EG(exception_op);
178-
EG(opline_before_exception) = old_opline_before_exception;
178+
if (EG(current_execute_data)) {
179+
EG(current_execute_data)->opline = EG(exception_op);
180+
EG(opline_before_exception) = old_opline_before_exception;
181+
}
179182
if (EG(exception)) {
180183
zend_exception_set_previous(EG(exception), old_exception);
181184
} else {

0 commit comments

Comments
 (0)