Skip to content
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

Fuzzing crashes for SDL_LoadWAV #2674

Closed
SDLBugzilla opened this issue Feb 11, 2021 · 0 comments
Closed

Fuzzing crashes for SDL_LoadWAV #2674

SDLBugzilla opened this issue Feb 11, 2021 · 0 comments

Comments

@SDLBugzilla
Copy link
Collaborator

SDLBugzilla commented Feb 11, 2021

This bug report was migrated from our old Bugzilla tracker.

These attachments are available in the static archive:

Reported in version: HG 2.0
Reported for operating system, platform: All, All

Comments on the original bug report:

On 2017-10-18 18:12:52 +0000, Ryan C. Gordon wrote:

Created attachment 3010
Archive of test cases.

Here's a zipfile of data that crashes SDL_LoadWAV. These are likely not valid wave files, but just carefully crafted binary data that convinces SDL_LoadWAV to overflow buffers, etc, instead of merely returning an error.

This data was generated by American Fuzzy Lop (AFL), a fuzzer that makes finding these sort of bugs pretty easy.

http://lcamtuf.coredump.cx/afl/

--ryan.

On 2017-10-18 18:14:20 +0000, Ryan C. Gordon wrote:

Created attachment 3011
Test program to reproduce crashes.

Here's the test program AFL was using. You could just run it like:

for f in SDL-loadwav-fuzzing-crashes/* ; do ./testwav $f ; done

To see every crash.

Easy to compile: gcc -g -o testwav testwav.c sdl2-config --cflags --libs

On 2018-03-22 08:39:20 +0000, Simon Hug wrote:

Created attachment 3193
Draft patch that makes SDL_LoadWAV_RW much more robust.

I had a look at this and made some additions to SDL_wave.c.

The attached patch adds many checks and error messages. For some reason I also added A-law and µ-law decoders. Forgot exactly why... but hey, they're small.

The WAVE format is seriously underspecified (at least by the documents that are publicly available on the internet) and it's a shame Microsoft never put something better out there. The language used in them is so loose at times, it's not surprising the encoders and decoders behave very differently. The Windows Media Player doesn't even support MS ADPCM correctly.

The patch also adds some hints to make the decoder more strict at the cost of compatibility with weird WAVE files.

I still think it needs a bit of cleaning up (Not happy with the MultiplySize function. Don't like the name and other SDL code may want to use something like this too.) and some duplicated code may be folded together. It does work in this state and I have thrown all kinds of WAVE files at it. The AFL files also pass with it and some even play (obviously just noise). Crafty little fuzzer.

Any critique would be welcome. I have a fork of SDL with a audio-loadwav branch over here if someone wants to use the commenting feature of Bitbucket:

https://bitbucket.org/ChliHug/SDL

I also cobbled some Lua scripts together to create WAVE test files:

https://bitbucket.org/ChliHug/gendat

On 2018-03-23 16:05:07 +0000, Ozkan Sezer wrote:

A few bits I noticed:

In new static procedure WaveLoad(): count <= SDL_MAX_UINT32 is always
true, because count is an unsigned int.

New procedure MultiplySize() having SDL_bool return type but returning
SDL_TRUE upon overflow is confusing and wrong: if overflow is an error
as the procedure description implies, the return should be to be an int
and returned values should be changed to 1 or -1 for overflow and 0 for
normal case.

On 2018-03-24 04:10:03 +0000, Simon Hug wrote:

Thank you for the feedback.

It took me a minute to realize why I wrote that check. It's probably safe to assume that all modern compilers that target the most used architectures always use 32 bits for the int type. However, that's not guaranteed by C. Maybe the ILP64 data model gets popular in the (far?) future.

The usual error return values are of course better for the the multiply function. I made the correction.

On 2018-03-24 17:33:25 +0000, Sam Lantinga wrote:

Wow...

In general the SDL WAV loader is designed to be simpler and the one in SDL_mixer is intended to support more formats. I'm not opposed to the changes you present here, but can you also port them to SDL_mixer for the next release?

I'll be happy to accept both patches at the same time.

Thanks!

On 2018-03-24 21:31:53 +0000, Simon Hug wrote:

Oh, I forgot about SDL_mixer. I'm not familiar with its code base, but I'll give it a try.

On 2019-05-18 18:48:55 +0000, Ryan C. Gordon wrote:

Tagging a bunch of bugs with "target-2.0.10" so we have a clear list of things to address before a 2.0.10 release.

Please note that "addressing" one of these bugs might mean deciding to defer on it until after 2.0.10, or resolving it as WONTFIX, etc. This is just here to tell us we should look at it carefully, and soon.

If you have new information or feedback on this issue, this is a good time to add it to the conversation, as we're likely to be paying attention to this specific report in the next few days/weeks.

Thanks!

--ryan.

On 2019-06-09 01:55:43 +0000, Sam Lantinga wrote:

Simon, can you take a look at this patch again? It doesn't cleanly apply against the code in Mercurial anymore.

On 2019-06-09 02:03:41 +0000, Sam Lantinga wrote:

Actually, I backed out the other change and applied this patch to SDL, as it's way more robust and fixes the other CVE issues as well.
https://hg.libsdl.org/SDL/rev/b06fa7da012b

It may make sense to drop SDL_mixer's WAVE loading code in favor of this code in SDL. Is there anything that the SDL_mixer code does that the SDL WAVE loader doesn't do now?

On 2019-06-09 18:20:06 +0000, Simon Hug wrote:

Created attachment 3811
Minor cleanup patch for tip.

I'm sorry for never getting back to this.

The chunk part of SDL_mixer uses SDL's SDL_LoadWAV_RW to load wave files. The music part can only do 8 and 16-bit PCM and no extensible header. It seems to support loops and samples, but I haven't tested that yet. I'm trying to integrate the code from this patch into SDL_mixer now. Don't hold up the new SDL release for that, though!

Attached is a minor cleanup patch. It changes the option name of one hint to something better, puts one or two more checks in, and adds explicit casting where warnings could appear otherwise.

I hope the naming of the hints and their options is acceptable. It would be kind of awkward to change them after they get released with an official SDL version.

Oh, and the #ifdef'd debugging code was never meant to be included in the final patch (it's kind of ugly to look at), but if you want to leave it in that's ok.

On 2019-06-09 19:33:15 +0000, Simon Hug wrote:

Created attachment 3812
Minor cleanup patch for tip.

I see that there was an issue with the struct initialization in may code. Updated the cleanup patch to reflect that.

On 2019-06-09 19:46:44 +0000, Sam Lantinga wrote:

The cleanup is in:
https://hg.libsdl.org/SDL/rev/572f29f98da0

If the debug code would be helpful in the future, feel free to leave it in.

On 2019-10-23 07:42:03 +0000, Sylvain wrote:

Maybe double-check this commit:
bug 4842 - https://hg.libsdl.org/SDL/rev/26581b48aef9
TruncVeryStrict was check twice !

On 2020-04-13 18:36:05 +0000, Ryan C. Gordon wrote:

(In reply to Sylvain from comment # 13)

Maybe double-check this commit:
bug 4842 - https://hg.libsdl.org/SDL/rev/26581b48aef9
TruncVeryStrict was check twice !

That commit looks correct.

This bug looks like it can be closed; is there anything pending that prevents that?

I'm thinking we don't change SDL_mixer at this time, since it appears to be depending on SDL for the part of WAV decode SDL does anyhow...I'm not sure if anything else is still pending in here.

--ryan.

On 2020-06-27 01:52:08 +0000, Ryan C. Gordon wrote:

Closing this bug, as it appears to be resolved. Please reopen if there's more work to be done!

--ryan.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant