-
Notifications
You must be signed in to change notification settings - Fork 2.5k
[flac] Intermediate step towards OOM fuzzing #8302
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
This is an intermediate step towards fuzzing of out-of-memory conditions, which will be accomplished by making the Nth malloc/ calloc/realloc fail. With this intermediate step, hopefully no oss-fuzz build failures will occur
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.
Very nice! We did a similar thing for Fluent Bit fluent/fluent-bit#4689 and it helped find interesting cases! I'd be interested in knowing what results you find, as from my experience it often finds a lot of malloc mishandling.
I've already fuzzed locally, most problems were with not handling reallocs correctly. In libFLAC, on realloc failing some parts of the code expects the original memory to remain intact, other parts assume it to be freed. There were some recently added mallocs that misbehaved and a few of which failure wasn't handled. But mostly the original author did a very good job. Anyway, I guess this kind of fuzzing might not be useful for most projects, but as libFLAC is used in embedded environments it seems a good idea to have this functioning properly. |
@catenacyber I'm not sure, of course FLAC already has this functionality now, I don't know what might be better with this different approach. It might be interesting for other projects to have something like this without having to alter their code. |
So, how did you implement this functionality ? |
FLAC uses a set of malloc, calloc and realloc derivatives that check for overflow, see here: https://github.com/xiph/flac/blob/383512d551de2ebf640a95d010b38ad58b0d12ae/include/share/alloc.h Each of these has a check embedded, only on fuzzing. Certain fuzzers (not all) do fail checks. The fuzzer sets a counter to zero and sets a threshold. For each alloc, the counter is incremented, until the threshold is reached, and the alloc fails. See here: https://github.com/xiph/flac/blob/383512d551de2ebf640a95d010b38ad58b0d12ae/oss-fuzz/seek.cc#L73-L77 By default, these checks are disabled. So, only fuzzers that set a threshold actually use this. Combined with various sanitizers, the code paths that are only triggered on out-of-memory conditions. So fuzzing works with ASAN, UBSAN and MSAN. |
Interesting, one difference I notice is that my nallocfuzz has a pseudo random function to tell when one allocation fails (further allocations will not necessarily fail), instead of a counter and always the same threshold as you do... Did you find interesting stuff with allocations failure and UBSAN and MSAN ? |
I don't remember to be honest. The thing is that FLAC has, in my opinion, quite a lot of places it allocates memory, and it tries to fail gracefully at every allocation. That means there are a lot of code paths that are untested if allocation never fails. So, I mostly did this to improve code coverage. |
By the way @ktmf01 I tried nallocfuzz on Flac, and it looks like it quickly errors because the targets do not handle allocation failures |
This is an intermediate step towards fuzzing of out-of-memory conditions, which will be accomplished by making the Nth malloc/calloc/realloc fail. With this intermediate step, hopefully no oss-fuzz build failures will occur