Skip to content

Instantly share code, notes, and snippets.

@nikic
Created June 26, 2020 20:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nikic/34d798a0c579e5069ac9e9eccf8511c8 to your computer and use it in GitHub Desktop.
Save nikic/34d798a0c579e5069ac9e9eccf8511c8 to your computer and use it in GitHub Desktop.
diff --git a/sapi/fuzzer/config.m4 b/sapi/fuzzer/config.m4
index 8e15a274ec..6d2339df1e 100644
--- a/sapi/fuzzer/config.m4
+++ b/sapi/fuzzer/config.m4
@@ -53,7 +53,7 @@ if test "$PHP_FUZZER" != "no"; then
dnl union, and this can't be easily fixed.
dnl We need to specify -fno-sanitize-recover=undefined here, otherwise ubsan warnings
dnl will not be considered failures by the fuzzer.
- CFLAGS="$CFLAGS -fsanitize=undefined -fno-sanitize=object-size -fno-sanitize-recover=undefined"
+ CFLAGS="$CFLAGS -fsanitize=undefined -fno-sanitize=object-size -fno-sanitize=alignment -fno-sanitize-recover=undefined"
fi
],[
AC_MSG_ERROR(Compiler doesn't support -fsanitize=fuzzer-no-link)
diff --git a/sapi/fuzzer/fuzzer-unserialize.c b/sapi/fuzzer/fuzzer-unserialize.c
index 4b65197df9..d2166df50f 100644
--- a/sapi/fuzzer/fuzzer-unserialize.c
+++ b/sapi/fuzzer/fuzzer-unserialize.c
@@ -29,11 +29,16 @@
#include "ext/standard/php_var.h"
-int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
- unsigned char *orig_data = malloc(Size+1);
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t FullSize) {
zend_execute_data execute_data;
zend_function func;
+ const uint8_t *end = memrchr(Data, '|', FullSize);
+ if (!end) {
+ return 0;
+ }
+ size_t Size = end - Data;
+ unsigned char *orig_data = malloc(Size + 1);
memcpy(orig_data, Data, Size);
orig_data[Size] = '\0';
@@ -62,6 +67,15 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
php_var_unserialize(&result, (const unsigned char **) &data, data + Size, &var_hash);
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
+ if (Z_TYPE(result) == IS_OBJECT
+ && zend_string_equals_literal(Z_OBJCE(result)->name, "HashContext")) {
+ zval args[2];
+ ZVAL_COPY_VALUE(&args[0], &result);
+ ZVAL_STRINGL(&args[1], (char *) end + 1, Data + FullSize - end - 1);
+ fuzzer_call_php_func_zval("hash_update", 2, args);
+ zval_ptr_dtor(&args[1]);
+ }
+
zval_ptr_dtor(&result);
/* Destroy any thrown exception. */
<?php
if ($argc < 2) die("Missing arg");
$i = 0;
mkdir($argv[1]);
foreach (hash_algos() as $algo) {
$ctx = hash_init($algo);
file_put_contents($argv[1] . '/' . $i++, serialize($ctx) . '|x');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment