-
Notifications
You must be signed in to change notification settings - Fork 8k
ext/bcmath: Added fuzzer for divide #18045
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: PHP-8.4
Are you sure you want to change the base?
Changes from 1 commit
24003b5
5341ef7
1fb2cd1
82ed67d
bd630e3
a2c3f56
13319aa
e1fa2fa
3d52e01
39cca77
cddaede
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 15,7,0 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 14.14,9,10 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 1.23456789,0.56,10 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 0.00123456789,0.001,10 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 12345.6789,100,2 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 12345.6,0.00001,20 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,165 @@ | ||
| /* | ||
| +----------------------------------------------------------------------+ | ||
| | 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 | | ||
| | [email protected] so we can mail you a copy immediately. | | ||
| +----------------------------------------------------------------------+ | ||
| | Authors: Saki Takamachi <[email protected]> | | ||
| +----------------------------------------------------------------------+ | ||
| */ | ||
|
|
||
|
|
||
|
|
||
| #include "fuzzer.h" | ||
|
|
||
| #include "Zend/zend.h" | ||
| #include <main/php_config.h> | ||
| #include "main/php_main.h" | ||
|
|
||
| #include <stdio.h> | ||
| #include <stdint.h> | ||
| #include <stdlib.h> | ||
|
|
||
| #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) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should happen earlier to not leak memory. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed unnecessary memory allocations and relocated code. |
||
| 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; | ||
| } | ||
|
|
||
| #define BUF_SIZE 128 | ||
|
|
||
| static inline bool rand_bool() { | ||
| return rand() & 1; | ||
| } | ||
|
|
||
| static inline size_t generate_random_num_fraction(char *buf, size_t len) { | ||
| int zeros = rand() % 10; | ||
| for (int i = 0; i < zeros; i++) { | ||
| buf[len] = '0'; | ||
| len++; | ||
| } | ||
| len += snprintf(buf + len, BUF_SIZE - len, "%ld", random()); | ||
| return len; | ||
| } | ||
|
|
||
| static inline size_t generate_random_num(char *buf, size_t len) { | ||
| if (rand_bool()) { | ||
| /* num < 1 */ | ||
| buf[len] = '0'; | ||
| buf[len + 1]= '.'; | ||
| len += 2; | ||
| /* fraction */ | ||
| len = generate_random_num_fraction(buf, len); | ||
| } else { | ||
| /* integer */ | ||
| len += snprintf(buf + len, BUF_SIZE - len, "%ld", random()); | ||
| if (rand_bool()) { | ||
| /* fraction */ | ||
| buf[len] = '.'; | ||
| len++; | ||
| len = generate_random_num_fraction(buf, len); | ||
| } | ||
| } | ||
|
|
||
| return len; | ||
| } | ||
|
|
||
| size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, size_t MaxSize, unsigned int Seed) { | ||
|
||
| char buf[BUF_SIZE]; | ||
| size_t len = 0; | ||
|
|
||
| /* num1 */ | ||
| len = generate_random_num(buf, len); | ||
| buf[len] = ','; | ||
| len++; | ||
|
|
||
| /* num2 */ | ||
| len = generate_random_num(buf, len); | ||
| buf[len] = ','; | ||
| len++; | ||
|
|
||
| /* scale */ | ||
| len += snprintf(buf + len, BUF_SIZE - 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; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could also cause overflow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 82ed67d
Parsing scale was left unfinished code...