-
Notifications
You must be signed in to change notification settings - Fork 37.7k
fuzz: replace every fuzzer-controlled while loop with a macro #22508
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
Conversation
There are several loops in the fuzz test where the number of iterations is directly controlled by the fuzzer, which oftentimes will go for millions of iterations, leading to certain fuzz tests taking forever on a single core. This PR limits these fuzzer-controlled loops to 1000 iterations, an arbitrary high number. IMHO letting the fuzzer control the number of iterations directly like this, with no restrictions, is a bad idea because the fuzzer will naturally try to hit super high numbers. I'm looking for a concept ACK (should we limit these) and an approach ACK (is doing this with a macro a reasonable way to go?). Actual ACKs/merges would also be nice :). |
On an EPYC 7502 with 256Gb of RAM, just running before, -j1
after, -j1
before, -j32
after, -j32
|
Concept ACK. @DrahtBot please list the conflicts for the alternative solution that has been proposed. |
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
Ok, that didn't work. Basically, it would be nice to be able to still overwrite the limit per fuzz target: |
@MarcoFalke I added a #define variable and capped the |
5b26624
to
9b7a105
Compare
Concept ACK Nice idea! |
9b7a105
to
be655e8
Compare
Redid the PR. Now it takes the macro from #22649 and just applies it to every single remaining fuzzer loop. |
Thanks for fixing this! Is the mixing of ACK modulo spacing consistency :) |
Concept and code review ACK be655e8 I would slightly prefer this "arbitrary high number" to be a constant as it's repeated everywhere. |
I'd say the number is dependent on the test context. The current ones in master are 30, 300, 3000, and 30000. I think each number needs to be picked carefully to be in the right 10^x.
clang-format(-diff) should take care of those in any case. |
Oops, I will fix the spacing inconsistency. It probably happened when I switched from manual edits to using sed. @MarcoFalke I think we could probably start with an "anbitrary high number", say 30000 (or 10000), and then when when tests reveal that certain tests are taking too long we can reduce them in individual cases. The current situation effectively has a limit of infinity and things are mostly OK, so I don' t think this'll be a big deal. Once we're at 5-digit numbers I don't think there are any situations where we'd want to increase them. |
Sorry, will review soon |
be655e8
to
9116bc1
Compare
Rebased and changed formatting to be consistent. |
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.
ACK, beside comments
src/test/fuzz/rpc.cpp
Outdated
@@ -348,7 +348,7 @@ FUZZ_TARGET_INIT(rpc, initialize_rpc) | |||
return; | |||
} | |||
std::vector<std::string> arguments; | |||
while (fuzzed_data_provider.ConsumeBool()) { | |||
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000) { |
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 seems a bit high? ConsumeRPCArgument
might call ConsumeArrayRPCArgument
, so the limit is 100'000'000. A user shouldn't be passing in more than 100 items. So any value between 100-1000 seems more appropriate.
See also https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=40648
Which is running base58 encoding (expensive) of one rpc arg 6000 times, thus times out. Your limit of 10000 wouldn't affect that, I think.
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.
ACK. I reduced it to 100.
I worry that reducing this will meaningfully affect test coverage since we presumably want to test what happens when you give gazillions of RPC arguments ... but probably a general-purpose fuzz test is the wrong place to try to hit that.
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.
Sorry, I also meant in the line above in this file. 100 * 100 is still 10k.
9116bc1
to
6cfcbda
Compare
6cfcbda
to
244eb3c
Compare
src/test/fuzz/rpc.cpp
Outdated
@@ -294,7 +294,7 @@ std::string ConsumeScalarRPCArgument(FuzzedDataProvider& fuzzed_data_provider) | |||
std::string ConsumeArrayRPCArgument(FuzzedDataProvider& fuzzed_data_provider) | |||
{ | |||
std::vector<std::string> scalar_arguments; | |||
while (fuzzed_data_provider.ConsumeBool()) { | |||
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000) { |
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 one I meant, too ;)
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.
Blindly chose a cap of 10000 iterations for every loop, except for the two in script_ops.cpp and scriptnum_ops.cpp which appeared to (sometimes) be deserializing individual bytes; capped those to one million to ensure that sometimes we try working with massive scripts. There was also one fuzzer-controlled loop in timedata.cpp which was already capped, so I left that alone. git grep 'while (fuzz' should now run clean except for timedata.cpp
244eb3c
to
214d905
Compare
Some times: master | this | relative | name
|
So yeah, this should fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=40648 |
cr ACK 214d905 |
… with a macro 214d905 fuzz: replace every fuzzer-controlled loop with a LIMITED_WHILE loop (Andrew Poelstra) Pull request description: Limits the number of iterations to 1000 rather than letting the fuzzer do millions or billions of iterations on a single core. ACKs for top commit: MarcoFalke: cr ACK 214d905 Tree-SHA512: 9741c32ccd126ea656e5c93371b7136eaa2f92dc9a490dd4d39642503b1a41174f3368245153e508c3b608fe37ab89800b67ada97b740e3b5a3728bb506429d3
Limits the number of iterations to 1000 rather than letting the fuzzer do millions or billions of iterations on a single core.