Skip to content

Commit ed33262

Browse files
committed
Disable destructors on fuzzer bailout
This is what we normally do for fatal errors. The reason why this became necessary now, is that a bailout can switch from a fiber back to the main stack. In that case we do not want to try destroying the fiber. Fixes oss-fuzz #33917.
1 parent e5b6f43 commit ed33262

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

sapi/fuzzer/fuzzer-execute.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,22 @@ static uint32_t steps_left;
2727
* we can assume that we don't use global registers / hybrid VM. */
2828
typedef int (ZEND_FASTCALL *opcode_handler_t)(zend_execute_data *);
2929

30+
static ZEND_NORETURN void fuzzer_bailout() {
31+
/* Disable object destructors, like we would do for fatal errors. In particular, if we
32+
* perform a bailout from a fiber to the main stack, we should not try to destroy the
33+
* fiber. */
34+
zend_objects_store_mark_destructed(&EG(objects_store));
35+
zend_bailout();
36+
}
37+
3038
static void fuzzer_execute_ex(zend_execute_data *execute_data) {
3139
while (1) {
3240
int ret;
3341
if (--steps_left == 0) {
3442
/* Reset steps before bailing out, so code running after bailout (e.g. in
3543
* destructors) will get another MAX_STEPS, rather than UINT32_MAX steps. */
3644
steps_left = MAX_STEPS;
37-
zend_bailout();
45+
fuzzer_bailout();
3846
}
3947

4048
if ((ret = ((opcode_handler_t) EX(opline)->handler)(execute_data)) != 0) {
@@ -52,7 +60,7 @@ static zend_op_array *(*orig_compile_string)(zend_string *source_string, const c
5260
static zend_op_array *fuzzer_compile_string(zend_string *str, const char *filename) {
5361
if (ZSTR_LEN(str) > MAX_SIZE) {
5462
/* Avoid compiling huge inputs via eval(). */
55-
zend_bailout();
63+
fuzzer_bailout();
5664
}
5765

5866
return orig_compile_string(str, filename);

0 commit comments

Comments
 (0)