Skip to content

Commit

Permalink
Limit internal function calls in execute fuzzer
Browse files Browse the repository at this point in the history
Infinite recursion might occur purely through internal functions,
without reentering the executor.
  • Loading branch information
nikic committed Aug 26, 2021
1 parent fa03276 commit cae80ef
Showing 1 changed file with 19 additions and 7 deletions.
26 changes: 19 additions & 7 deletions sapi/fuzzer/fuzzer-execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,19 @@ static uint32_t steps_left;
* we can assume that we don't use global registers / hybrid VM. */
typedef int (ZEND_FASTCALL *opcode_handler_t)(zend_execute_data *);

static zend_always_inline void fuzzer_step(void) {
if (--steps_left == 0) {
/* Reset steps before bailing out, so code running after bailout (e.g. in
* destructors) will get another MAX_STEPS, rather than UINT32_MAX steps. */
steps_left = MAX_STEPS;
zend_bailout();
}
}

static void fuzzer_execute_ex(zend_execute_data *execute_data) {
while (1) {
int ret;
if (--steps_left == 0) {
/* Reset steps before bailing out, so code running after bailout (e.g. in
* destructors) will get another MAX_STEPS, rather than UINT32_MAX steps. */
steps_left = MAX_STEPS;
zend_bailout();
}

fuzzer_step();
if ((ret = ((opcode_handler_t) EX(opline)->handler)(execute_data)) != 0) {
if (ret > 0) {
execute_data = EG(current_execute_data);
Expand All @@ -58,6 +61,13 @@ static zend_op_array *fuzzer_compile_string(zend_string *str, const char *filena
return orig_compile_string(str, filename);
}

static void (*orig_execute_internal)(zend_execute_data *execute_data, zval *return_value);

static void fuzzer_execute_internal(zend_execute_data *execute_data, zval *return_value) {
fuzzer_step();
orig_execute_internal(execute_data, return_value);
}

int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
if (Size > MAX_SIZE) {
/* Large inputs have a large impact on fuzzer performance,
Expand All @@ -82,6 +92,8 @@ int LLVMFuzzerInitialize(int *argc, char ***argv) {
fuzzer_init_php();

zend_execute_ex = fuzzer_execute_ex;
orig_execute_internal = zend_execute_internal ? zend_execute_internal : execute_internal;
zend_execute_internal = fuzzer_execute_internal;
orig_compile_string = zend_compile_string;
zend_compile_string = fuzzer_compile_string;

Expand Down

0 comments on commit cae80ef

Please sign in to comment.