[FFmpeg-devel] [PATCH 0/1][TOOL][HACK] Allocation NULL check fuzzer
Derek Buitenhuis
derek.buitenhuis at gmail.com
Fri Nov 24 21:45:46 EET 2017
I've had this kicking around for like 4 years, maybe it can be of use to some people.
I haven't done full scale fuzzing with this because laziness. I just sometimes run it
when I'm bored. It's not thread-safe, but it would be trivial to make it so.
It's based off my old LD_PRELOAD hack from here:
https://gist.github.com/dwbuiten/7101755
Optionally takes two env vars, MALLOC_SEED (the seed), and MALLOC_FAILPROB for the
probability of failing.
I've been running it directly integrated inside FFmpeg's allocator because it makes
it easier to run under gdb to find where it actually crashes, if the stack trace of
the failure is not enough info/context.
Currently FFmpeg has a lot of unchecked allocations - just one single FATE run with
this found:
daemon404 at bbvm:~/dev/f/ffmpeg/tests/data/fate$ grep Seg *.err
adpcm-ima-amv.err:Segmentation fault
adpcm-ima-apc.err:Segmentation fault
caf.err:Segmentation fault
filter-mergeplanes.err:Segmentation fault
filter-paletteuse-bayer.err:Segmentation fault
filter-paletteuse-sierra2_4a.err:Segmentation fault
lavf-wav.err:Segmentation fault
lavf-wav_peak.err:Segmentation fault
lavf-wav_peak_only.err:Segmentation fault
vorbis-encode.err:Segmentation fault
vsynth1-msvideo1.err:Segmentation fault
Plus an infinite EAGAIN loop with av_usleep ffmpeg.c, that I'm still trying to
debug.
It prints a stack trace when it fails so that you know which allocation failed:
daemon404 at bbvm:~/dev/f/ffmpeg/tests/data/fate$ cat vorbis-encode.err
[... snip ...]
FAILED. Iteration = 9789, Seed = 1511549218.
my_posix_memalign:77 in libavutil/posixmemalign.c
av_malloc:89 in libavutil/mem.c
av_mallocz:240 in libavutil/mem.c
av_frame_alloc:152 in libavutil/frame.c
av_frame_clone:499 in libavutil/frame.c
vorbis_encode_frame:1098 in libavcodec/vorbisenc.c
avcodec_encode_audio2:198 in libavcodec/encode.c
do_encode:377 in libavcodec/encode.c
avcodec_send_frame:423 in libavcodec/encode.c
do_audio_out:931 in fftools/ffmpeg.c
reap_filters:1507 in fftools/ffmpeg.c
transcode_step:4562 in fftools/ffmpeg.c
transcode:4606 in fftools/ffmpeg.c
main:4812 in fftools/ffmpeg.c
(null):0 in (null)
(null):0 in (null)
(null):0 in (null)
Segmentation fault
The (null) stuff is noise from libbacktrace, and could be skipped with a proper
callback.
And e.g. to reproduce this under gdb:
$ MALLOC_SEED=1511549218 gdb --args /home/daemon404/dev/f/ffmpeg/ffmpeg_g \
-nostdin -nostats -cpuflags all -hwaccel none -threads 1 -thread_type frame+slice \
-i /home/daemon404/fate/audio-reference/luckynight_2ch_44kHz_s16.wav -c:a vorbis \
-strict experimental -f ogg -y /home/daemon404/dev/f/ffmpeg/tests/data/fate/vorbis-encode.ogg
(Obtained from 'make fate-vorbis-encode V=1'.)
Currently it's using libbacktrace from GCC, which can be build entirely separately from
GDB (cd libbacktrace && ./configure && make && cp backtrace.h /usr/local/include &&
cp .libs/libbacktrace.a /usr/local/lib). Add -lbacktrace to extra-libs. Hacky? Yeah...
Derek Buitenhuis (1):
Allocation NULL check fuzzing tool
libavutil/mem.c | 4 ++-
libavutil/posixmemalign.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 89 insertions(+), 1 deletion(-)
create mode 100644 libavutil/posixmemalign.c
--
2.15.0
More information about the ffmpeg-devel
mailing list