Skip to content

Commit b0b8361

Browse files
committed
Extract some common fuzzer code
1 parent 75ada66 commit b0b8361

File tree

5 files changed

+45
-53
lines changed

5 files changed

+45
-53
lines changed

sapi/fuzzer/fuzzer-sapi.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,37 @@ int fuzzer_request_startup()
156156
return SUCCESS;
157157
}
158158

159+
void fuzzer_request_shutdown()
160+
{
161+
/* Destroy thrown exceptions. This does not happen as part of request shutdown. */
162+
if (EG(exception)) {
163+
zend_object_release(EG(exception));
164+
EG(exception) = NULL;
165+
}
166+
167+
/* Some fuzzers (like unserialize) may create circular structures. Make sure we free them.
168+
* Two calls are performed to handle objects with destructors. */
169+
zend_gc_collect_cycles();
170+
zend_gc_collect_cycles();
171+
172+
php_request_shutdown(NULL);
173+
}
174+
175+
/* Set up a dummy stack frame so that exceptions may be thrown. */
176+
void fuzzer_setup_dummy_frame()
177+
{
178+
static zend_execute_data execute_data;
179+
static zend_function func;
180+
181+
memset(&execute_data, 0, sizeof(zend_execute_data));
182+
memset(&func, 0, sizeof(zend_function));
183+
184+
func.type = ZEND_INTERNAL_FUNCTION;
185+
func.common.function_name = ZSTR_EMPTY_ALLOC();
186+
execute_data.func = &func;
187+
EG(current_execute_data) = &execute_data;
188+
}
189+
159190
void fuzzer_set_ini_file(const char *file)
160191
{
161192
if (fuzzer_module.php_ini_path_override) {

sapi/fuzzer/fuzzer-sapi.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
+----------------------------------------------------------------------+
1616
*/
1717

18-
int fuzzer_init_php();
19-
int fuzzer_request_startup();
18+
int fuzzer_init_php(void);
19+
int fuzzer_request_startup(void);
20+
void fuzzer_request_shutdown(void);
21+
void fuzzer_setup_dummy_frame(void);
2022
void fuzzer_call_php_func(const char *func_name, int nargs, char **params);
2123
void fuzzer_call_php_func_zval(const char *func_name, int nargs, zval *args);
2224
int fuzzer_do_request_from_buffer(char *filename, char *data, size_t data_len);

sapi/fuzzer/fuzzer-unserialize.c

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -31,26 +31,14 @@
3131

3232
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
3333
unsigned char *orig_data = malloc(Size+1);
34-
zend_execute_data execute_data;
35-
zend_function func;
36-
3734
memcpy(orig_data, Data, Size);
3835
orig_data[Size] = '\0';
3936

40-
if (fuzzer_request_startup()==FAILURE) {
37+
if (fuzzer_request_startup() == FAILURE) {
4138
return 0;
4239
}
4340

44-
/* Set up a dummy stack frame so that exceptions may be thrown. */
45-
{
46-
memset(&execute_data, 0, sizeof(zend_execute_data));
47-
memset(&func, 0, sizeof(zend_function));
48-
49-
func.type = ZEND_INTERNAL_FUNCTION;
50-
func.common.function_name = ZSTR_EMPTY_ALLOC();
51-
execute_data.func = &func;
52-
EG(current_execute_data) = &execute_data;
53-
}
41+
fuzzer_setup_dummy_frame();
5442

5543
{
5644
const unsigned char *data = orig_data;
@@ -63,22 +51,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
6351
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
6452

6553
zval_ptr_dtor(&result);
66-
67-
/* Destroy any thrown exception. */
68-
if (EG(exception)) {
69-
zend_object_release(EG(exception));
70-
EG(exception) = NULL;
71-
}
7254
}
7355

74-
/* Unserialize may create circular structure. Make sure we free them.
75-
* Two calls are performed to handle objects with destructors. */
76-
zend_gc_collect_cycles();
77-
zend_gc_collect_cycles();
78-
php_request_shutdown(NULL);
79-
8056
free(orig_data);
8157

58+
fuzzer_request_shutdown();
8259
return 0;
8360
}
8461

sapi/fuzzer/fuzzer-unserializehash.c

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
#include "ext/standard/php_var.h"
2929

3030
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t FullSize) {
31-
zend_execute_data execute_data;
32-
zend_function func;
3331
const uint8_t *Start = memchr(Data, '|', FullSize);
3432
if (!Start) {
3533
return 0;
@@ -41,20 +39,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t FullSize) {
4139
memcpy(orig_data, Start, Size);
4240
orig_data[Size] = '\0';
4341

44-
if (fuzzer_request_startup()==FAILURE) {
42+
if (fuzzer_request_startup() == FAILURE) {
4543
return 0;
4644
}
4745

48-
/* Set up a dummy stack frame so that exceptions may be thrown. */
49-
{
50-
memset(&execute_data, 0, sizeof(zend_execute_data));
51-
memset(&func, 0, sizeof(zend_function));
52-
53-
func.type = ZEND_INTERNAL_FUNCTION;
54-
func.common.function_name = ZSTR_EMPTY_ALLOC();
55-
execute_data.func = &func;
56-
EG(current_execute_data) = &execute_data;
57-
}
46+
fuzzer_setup_dummy_frame();
5847

5948
{
6049
const unsigned char *data = orig_data;
@@ -77,22 +66,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t FullSize) {
7766
}
7867

7968
zval_ptr_dtor(&result);
80-
81-
/* Destroy any thrown exception. */
82-
if (EG(exception)) {
83-
zend_object_release(EG(exception));
84-
EG(exception) = NULL;
85-
}
8669
}
8770

88-
/* Unserialize may create circular structure. Make sure we free them.
89-
* Two calls are performed to handle objects with destructors. */
90-
zend_gc_collect_cycles();
91-
zend_gc_collect_cycles();
92-
php_request_shutdown(NULL);
93-
9471
free(orig_data);
9572

73+
fuzzer_request_shutdown();
9674
return 0;
9775
}
9876

sapi/fuzzer/generate_all.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?php
2+
require __DIR__ . '/generate_unserialize_dict.php';
3+
require __DIR__ . '/generate_unserializehash_corpus.php';
4+
require __DIR__ . '/generate_parser_corpus.php';

0 commit comments

Comments
 (0)