From b00ef4e615a23415c166c54c40f6c589dfd7bb55 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Tue, 2 Sep 2025 20:25:58 +0200 Subject: [PATCH 1/2] Fix fuzzer runner We must take into account the calling convention of the tailcall vm. --- sapi/fuzzer/fuzzer-execute-common.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sapi/fuzzer/fuzzer-execute-common.h b/sapi/fuzzer/fuzzer-execute-common.h index 20fcad111cd6b..4a52fe1239b81 100644 --- a/sapi/fuzzer/fuzzer-execute-common.h +++ b/sapi/fuzzer/fuzzer-execute-common.h @@ -32,10 +32,6 @@ static uint32_t steps_left; static bool bailed_out = false; -/* Because the fuzzer is always compiled with clang, - * we can assume that we don't use global registers / hybrid VM. */ -typedef zend_op *(ZEND_FASTCALL *opcode_handler_t)(zend_execute_data *, const zend_op *); - static zend_always_inline void fuzzer_bailout(void) { bailed_out = true; zend_bailout(); @@ -67,7 +63,7 @@ static void fuzzer_execute_ex(zend_execute_data *execute_data) { while (1) { fuzzer_step(); - opline = ((opcode_handler_t) opline->handler)(execute_data, opline); + opline = opline->handler(execute_data, opline); if ((uintptr_t) opline & ZEND_VM_ENTER_BIT) { opline = (const zend_op *) ((uintptr_t) opline & ~ZEND_VM_ENTER_BIT); if (opline) { From c8336b25a4c34acefc514f0ced4d63e3cf5731eb Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 3 Sep 2025 20:30:25 +0200 Subject: [PATCH 2/2] change approach --- sapi/fuzzer/fuzzer-execute-common.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sapi/fuzzer/fuzzer-execute-common.h b/sapi/fuzzer/fuzzer-execute-common.h index 4a52fe1239b81..338c771e551a3 100644 --- a/sapi/fuzzer/fuzzer-execute-common.h +++ b/sapi/fuzzer/fuzzer-execute-common.h @@ -23,6 +23,7 @@ #include "fuzzer.h" #include "fuzzer-sapi.h" #include "zend_exceptions.h" +#include "zend_vm.h" #define FILE_NAME "/tmp/fuzzer.php" #define MAX_STEPS 1000 @@ -63,7 +64,7 @@ static void fuzzer_execute_ex(zend_execute_data *execute_data) { while (1) { fuzzer_step(); - opline = opline->handler(execute_data, opline); + opline = ((zend_vm_opcode_handler_func_t) zend_get_opcode_handler_func(opline))(execute_data, opline); if ((uintptr_t) opline & ZEND_VM_ENTER_BIT) { opline = (const zend_op *) ((uintptr_t) opline & ~ZEND_VM_ENTER_BIT); if (opline) {