summaryrefslogtreecommitdiff
path: root/sapi/fuzzer/fuzzer-unserialize.c
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-09-13 15:15:46 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-09-16 16:04:10 +0200
commitc4e2ca607f49d37564aaf34f5a48c5e59aca12a6 (patch)
tree9efd9c787f0f37f77e9da6d8dac1dfdb275ec4af /sapi/fuzzer/fuzzer-unserialize.c
parent41f45647f90a44514fd18b16fdcec5cceebf1635 (diff)
downloadphp-git-c4e2ca607f49d37564aaf34f5a48c5e59aca12a6.tar.gz
Various improvements to fuzzer SAPIs
Diffstat (limited to 'sapi/fuzzer/fuzzer-unserialize.c')
-rw-r--r--sapi/fuzzer/fuzzer-unserialize.c50
1 files changed, 38 insertions, 12 deletions
diff --git a/sapi/fuzzer/fuzzer-unserialize.c b/sapi/fuzzer/fuzzer-unserialize.c
index 9b843f25fe..9cf040944a 100644
--- a/sapi/fuzzer/fuzzer-unserialize.c
+++ b/sapi/fuzzer/fuzzer-unserialize.c
@@ -32,28 +32,54 @@
#include "ext/standard/php_var.h"
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
- unsigned char *data = malloc(Size+1);
+ unsigned char *orig_data = malloc(Size+1);
+ zend_execute_data execute_data;
+ zend_function func;
- memcpy(data, Data, Size);
- data[Size] = '\0';
+ memcpy(orig_data, Data, Size);
+ orig_data[Size] = '\0';
- if (php_request_startup()==FAILURE) {
- php_module_shutdown();
+ if (fuzzer_request_startup()==FAILURE) {
return 0;
}
- zval result;
+ /* Set up a dummy stack frame so that exceptions may be thrown. */
+ {
+ memset(&execute_data, 0, sizeof(zend_execute_data));
+ memset(&func, 0, sizeof(zend_function));
- php_unserialize_data_t var_hash;
- PHP_VAR_UNSERIALIZE_INIT(var_hash);
- php_var_unserialize(&result, &data, data + Size, &var_hash);
- PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
+ func.type = ZEND_INTERNAL_FUNCTION;
+ func.common.function_name = ZSTR_EMPTY_ALLOC();
+ execute_data.func = &func;
+ EG(current_execute_data) = &execute_data;
+ }
+
+ {
+ const unsigned char *data = orig_data;
+ zval result;
+ ZVAL_UNDEF(&result);
+
+ php_unserialize_data_t var_hash;
+ PHP_VAR_UNSERIALIZE_INIT(var_hash);
+ php_var_unserialize(&result, (const unsigned char **) &data, data + Size, &var_hash);
+ PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
- zval_ptr_dtor(&result);
+ zval_ptr_dtor(&result);
+
+ /* Destroy any thrown exception. */
+ if (EG(exception)) {
+ zend_object_release(EG(exception));
+ EG(exception) = NULL;
+ }
+ }
+ /* Unserialize may create circular structure. Make sure we free them.
+ * Two calls are performed to handle objects with destructors. */
+ zend_gc_collect_cycles();
+ zend_gc_collect_cycles();
php_request_shutdown(NULL);
- free(data);
+ free(orig_data);
return 0;
}