I instrumented the host-based mp3 decoder test and asked the open source fuzzer aflplusplus to find crashes in it.
After running for an hour or two it found 95 distinct crashes:
crashes.zip
some (many) of the crashes require use of the extra "-fsanitize=address" checker on the host. More info on how I built & tested to find these problems will be forthcoming, but to reproduce on a linux based computer you should just need to add "-fsanitize=address" to the Makefile, make then run on each input with a commandine like ./decoder <input> /dev/null. If the exit status is not 0 or 2 then a problem was detected.
One example:
=================================================================
==896588==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61d000000890 at pc 0x7ffff7848061 bp 0x7fffffffd9e0 sp 0x7fffffffd190
WRITE of size 41823 at 0x61d000000890 thread T0
#0 0x7ffff7848060 in __interceptor_memcpy ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827
#1 0x55555556e6d3 in MP3Decode ../../src/mp3dec.c:351
#2 0x555555557928 in main /home/jepler/src/circuitpython/lib/mp3/examples/standalone/main.c:159
#3 0x7ffff7646249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#4 0x7ffff7646304 in __libc_start_main_impl ../csu/libc-start.c:360
#5 0x555555557ca0 in _start (/home/jepler/src/circuitpython/lib/mp3/examples/standalone/decoder+0x3ca0)
0x61d000000890 is located 0 bytes to the right of 2064-byte region [0x61d000000080,0x61d000000890)
allocated by thread T0 here:
#0 0x7ffff78b83b7 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:77
#1 0x55555555ce3c in xmp3_AllocateBuffers ../../src/buffers.c:111
#2 0x55555557d17f (/home/jepler/src/circuitpython/lib/mp3/examples/standalone/decoder+0x2917f)
Here, an inappropriate amount of memory is copied, possibly because the value mp3DecInfo->nSlots is not adequately validated.
here are the locations of the detected problems (1st and 2nd stack frames, sorted and uniq'd):
#0 0x5555555580b3 in RefillBitstreamCache ../../src/bitstream.c:102
#0 0x55555555c71c in RefillBitstreamCache ../../src/bitstream.c:93
#0 0x55555555c72c in RefillBitstreamCache ../../src/bitstream.c:95
#0 0x555555560e64 in xmp3_Dequantize ../../src/dequant.c:139
#0 0x555555563910 in xmp3_DecodeHuffman ../../src/huffman.c:451
#0 0x55555556d4c5 in MP3FindSyncWord ../../src/mp3dec.c:110
#0 0x55555556eea8 in MP3ClearBadFrame ../../src/mp3dec.c:256
#0 0x55555556f0a6 in MP3ClearBadFrame ../../src/mp3dec.c:256
#0 0x55555556f1d4 in MP3ClearBadFrame ../../src/mp3dec.c:256
#0 0x55555556fa69 in xmp3_PolyphaseMono ../../src/polyphase.c:145
#0 0x555555576e87 in xmp3_IntensityProcMPEG1 ../../src/stproc.c:146
#0 0x7ffff7848060 in __interceptor_memcpy ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827
#0 0x7ffff78481b7 in __interceptor_memcpy ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827
#1 0x5555555577f9 in mp3file_find_sync_word /home/jepler/src/circuitpython/lib/mp3/examples/standalone/main.c:48
#1 0x5555555580b3 in xmp3_GetBits ../../src/bitstream.c:142
#1 0x55555555c71c in xmp3_GetBits ../../src/bitstream.c:142
#1 0x55555555c72c in xmp3_GetBits ../../src/bitstream.c:142
#1 0x555555560cb8 in xmp3_Dequantize ../../src/dequant.c:139
#1 0x55555556e349 in MP3Decode ../../src/mp3dec.c:389
#1 0x55555556e6d3 in MP3Decode ../../src/mp3dec.c:351
#1 0x55555556e734 in MP3Decode ../../src/mp3dec.c:400
#1 0x55555556eb32 in MP3Decode ../../src/mp3dec.c:359
#1 0x55555556eea8 in MP3ClearBadFrame ../../src/mp3dec.c:248
#1 0x55555556f0a6 in MP3ClearBadFrame ../../src/mp3dec.c:248
#1 0x55555556f1d4 in MP3ClearBadFrame ../../src/mp3dec.c:248
#1 0x555555577d90 in xmp3_Subband ../../src/subband.c:86
Happily there appear to be a lot fewer than 95 distinct crash sites. (aflplusplus considers other details to make for different "paths": I think a different if/else path, or a different number of loop counts, or a different size of access can all create different crashes as far as aflpluslus is concerned, for instance)
I instrumented the host-based mp3 decoder test and asked the open source fuzzer aflplusplus to find crashes in it.
After running for an hour or two it found 95 distinct crashes: crashes.zip
some (many) of the crashes require use of the extra "-fsanitize=address" checker on the host. More info on how I built & tested to find these problems will be forthcoming, but to reproduce on a linux based computer you should just need to add "-fsanitize=address" to the Makefile,
make
then run on each input with a commandine like./decoder <input> /dev/null
. If the exit status is not 0 or 2 then a problem was detected.One example:
Here, an inappropriate amount of memory is copied, possibly because the value
mp3DecInfo->nSlots
is not adequately validated.here are the locations of the detected problems (1st and 2nd stack frames, sorted and uniq'd):
Happily there appear to be a lot fewer than 95 distinct crash sites. (aflplusplus considers other details to make for different "paths": I think a different if/else path, or a different number of loop counts, or a different size of access can all create different crashes as far as aflpluslus is concerned, for instance)