From 6dd132304047d8e59faed4c604fd3b5781b921ac Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Thu, 13 Mar 2025 09:46:23 +0900 Subject: [PATCH] fuzzer for bcmath --- sapi/fuzzer/Makefile.frag | 3 + sapi/fuzzer/config.m4 | 1 + sapi/fuzzer/corpus/bcmath/1 | 1 + sapi/fuzzer/corpus/bcmath/2 | 1 + sapi/fuzzer/corpus/bcmath/3 | 1 + sapi/fuzzer/corpus/bcmath/4 | 1 + sapi/fuzzer/corpus/bcmath/5 | 1 + sapi/fuzzer/corpus/bcmath/6 | 1 + sapi/fuzzer/fuzzer-bcmath.c | 139 ++++++++++++++++++++++++++++++++++++ 9 files changed, 149 insertions(+) create mode 100644 sapi/fuzzer/corpus/bcmath/1 create mode 100644 sapi/fuzzer/corpus/bcmath/2 create mode 100644 sapi/fuzzer/corpus/bcmath/3 create mode 100644 sapi/fuzzer/corpus/bcmath/4 create mode 100644 sapi/fuzzer/corpus/bcmath/5 create mode 100644 sapi/fuzzer/corpus/bcmath/6 create mode 100644 sapi/fuzzer/fuzzer-bcmath.c diff --git a/sapi/fuzzer/Makefile.frag b/sapi/fuzzer/Makefile.frag index 9608e29d48910..d6cabedde7015 100644 --- a/sapi/fuzzer/Makefile.frag +++ b/sapi/fuzzer/Makefile.frag @@ -31,3 +31,6 @@ $(SAPI_FUZZER_PATH)/php-fuzz-mbstring: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(PHP $(SAPI_FUZZER_PATH)/php-fuzz-mbregex: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(PHP_FUZZER_MBREGEX_OBJS) $(FUZZER_BUILD) $(PHP_FUZZER_MBREGEX_OBJS) -o $@ + +$(SAPI_FUZZER_PATH)/php-fuzz-bcmath: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(PHP_FUZZER_BCMATH_OBJS) + $(FUZZER_BUILD) $(PHP_FUZZER_BCMATH_OBJS) -o $@ diff --git a/sapi/fuzzer/config.m4 b/sapi/fuzzer/config.m4 index 21a44cd6d886e..5da5ea5e71a8a 100644 --- a/sapi/fuzzer/config.m4 +++ b/sapi/fuzzer/config.m4 @@ -63,6 +63,7 @@ if test "$PHP_FUZZER" != "no"; then PHP_FUZZER_TARGET([unserialize], [PHP_FUZZER_UNSERIALIZE_OBJS]) PHP_FUZZER_TARGET([unserializehash], [PHP_FUZZER_UNSERIALIZEHASH_OBJS]) PHP_FUZZER_TARGET([json], [PHP_FUZZER_JSON_OBJS]) + PHP_FUZZER_TARGET([bcmath], [PHP_FUZZER_BCMATH_OBJS]) if test -n "$enable_exif" && test "$enable_exif" != "no"; then PHP_FUZZER_TARGET([exif], [PHP_FUZZER_EXIF_OBJS]) diff --git a/sapi/fuzzer/corpus/bcmath/1 b/sapi/fuzzer/corpus/bcmath/1 new file mode 100644 index 0000000000000..87e56bbe3c16a --- /dev/null +++ b/sapi/fuzzer/corpus/bcmath/1 @@ -0,0 +1 @@ +15,7,0 diff --git a/sapi/fuzzer/corpus/bcmath/2 b/sapi/fuzzer/corpus/bcmath/2 new file mode 100644 index 0000000000000..0fcc6ef088827 --- /dev/null +++ b/sapi/fuzzer/corpus/bcmath/2 @@ -0,0 +1 @@ +14.14,9,10 diff --git a/sapi/fuzzer/corpus/bcmath/3 b/sapi/fuzzer/corpus/bcmath/3 new file mode 100644 index 0000000000000..0b218cc599193 --- /dev/null +++ b/sapi/fuzzer/corpus/bcmath/3 @@ -0,0 +1 @@ +1.23456789,0.56,10 diff --git a/sapi/fuzzer/corpus/bcmath/4 b/sapi/fuzzer/corpus/bcmath/4 new file mode 100644 index 0000000000000..e44b29bd6715e --- /dev/null +++ b/sapi/fuzzer/corpus/bcmath/4 @@ -0,0 +1 @@ +0.00123456789,0.001,10 diff --git a/sapi/fuzzer/corpus/bcmath/5 b/sapi/fuzzer/corpus/bcmath/5 new file mode 100644 index 0000000000000..68de032118588 --- /dev/null +++ b/sapi/fuzzer/corpus/bcmath/5 @@ -0,0 +1 @@ +12345.6789,100,2 diff --git a/sapi/fuzzer/corpus/bcmath/6 b/sapi/fuzzer/corpus/bcmath/6 new file mode 100644 index 0000000000000..ba59d52f5047b --- /dev/null +++ b/sapi/fuzzer/corpus/bcmath/6 @@ -0,0 +1 @@ +12345.6,0.00001,20 diff --git a/sapi/fuzzer/fuzzer-bcmath.c b/sapi/fuzzer/fuzzer-bcmath.c new file mode 100644 index 0000000000000..8a05d5846503c --- /dev/null +++ b/sapi/fuzzer/fuzzer-bcmath.c @@ -0,0 +1,139 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Saki Takamachi | + +----------------------------------------------------------------------+ + */ + + + +#include "fuzzer.h" + +#include "Zend/zend.h" +#include
+#include "main/php_main.h" + +#include +#include +#include + +#include "fuzzer-sapi.h" + +zend_long char_to_size_t(char *c) { + zend_long ret = 0; + if (*c >= '0' && *c <= '9') { + ret *= 10; + ret += *c - '0'; + } + return ret; +} + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + /* num1,num2,scale */ + const uint8_t *Comma1 = memchr(Data, ',', Size); + if (!Comma1) { + return 0; + } + + size_t dividend_len = Comma1 - Data; + char *dividend_str = estrndup((char *) Data, dividend_len); + Data = Comma1 + 1; + Size -= dividend_len + 1; + + const uint8_t *Comma2 = memchr(Data, ',', Size); + if (!Comma2) { + efree(dividend_str); + return 0; + } + + size_t divisor_len = Comma2 - Data; + char *divisor_str = estrndup((char *) Data, divisor_len); + Data = Comma2 + 1; + Size -= divisor_len + 1; + + char *scale_str = malloc(Size + 1); + memcpy(scale_str, Data, Size); + scale_str[Size] = '\0'; + + zend_long scale = char_to_size_t(scale_str); + free(scale_str); + + if (fuzzer_request_startup() == FAILURE) { + return 0; + } + + fuzzer_setup_dummy_frame(); + + zval result; + ZVAL_UNDEF(&result); + + zval args[4]; + ZVAL_COPY_VALUE(&args[0], &result); + ZVAL_STRINGL(&args[1], dividend_str, dividend_len); + ZVAL_STRINGL(&args[2], divisor_str, divisor_len); + ZVAL_LONG(&args[3], scale); + + fuzzer_call_php_func_zval("bcdiv", 4, args); + + zval_ptr_dtor(&result); + zval_ptr_dtor(&args[1]); + zval_ptr_dtor(&args[2]); + efree(dividend_str); + efree(divisor_str); + + fuzzer_request_shutdown(); + + return 0; +} + +size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, size_t MaxSize, unsigned int Seed) { + char buf[64]; + size_t len = 0; + + /* num1 integer */ + len += snprintf(buf + len, sizeof(buf) - len, "%ld", random()); + if (rand() & 1) { + /* num1 fraction */ + buf[len] = '.'; + len++; + len += snprintf(buf + len, sizeof(buf) - len, "%ld", random()); + } + + buf[len] = ','; + len++; + /* num2 integer */ + len += snprintf(buf + len, sizeof(buf) - len, "%ld", random()); + if (rand() & 1) { + /* num2 fraction */ + buf[len] = '.'; + len++; + len += snprintf(buf + len, sizeof(buf) - len, "%ld", random()); + } + + buf[len] = ','; + len++; + /* scale */ + len += snprintf(buf + len, sizeof(buf) - len, "%d", rand() % 10); + + if (len > MaxSize) { + return 0; + } + memcpy(Data, buf, len); + return len; +} + +int LLVMFuzzerInitialize(int *argc, char ***argv) { + fuzzer_init_php(NULL); + + /* fuzzer_shutdown_php(); */ + return 0; +}