race condition in audio.c on uninit
3kyo0 opened this issue · 6 comments
mpv version and platform
mpv 0.29.1
mpv 0.29.0-353-g65b1c2d065-dirty
MacOS 10.13.6 (17G6030)
Reproduction steps
run script ./fuzz.sh
https://github.com/3kyo0/fuzz_samples/blob/master/fuzz.sh
Expected behavior
crash with Segmentation fault: 11
[mkv] SeekHead position beyond end of file - incomplete file?
(+) Video --vid=1 () (h264 720x432 25.000fps)
(+) Audio --aid=1 --alang=fre () (ac3 2ch)
(+) Subs --sid=1 --slang=fre (*) (dvd_subtitle)
[mkv] Invalid EBML length at position 13124
[mkv] Corrupt file detected. Trying to resync starting from position 13124...
No video PTS! Making something up. Using 25.000000 FPS.
[ffmpeg/audio] ac3: expacc 126 is out-of-range
[ffmpeg/audio] ac3: error decoding the audio block
Audio: no audio
Segmentation fault: 11
Actual behavior
crash
Log file
https://github.com/3kyo0/fuzz_samples/blob/master/crashreport.txt
https://github.com/3kyo0/fuzz_samples/blob/master/HONGGFUZZ.REPORT.TXT
Sample files
Can't reproduce on Linux with mpv 0.29.0-353-g65b1c2d065
and ffmpeg N-94185-gca576833e4
.
For fuzzing you might want to use --no-config
to ensure the crash doesn't depend on any of your local configuration.
Can't reproduce on Linux with mpv
0.29.0-353-g65b1c2d065
and ffmpegN-94185-gca576833e4
.
For fuzzing you might want to use--no-config
to ensure the crash doesn't depend on any of your local configuration.
Only MacOS
seems ao_c->filter pointer broken.there is two debug info.
1、Normal info:
Playing: ./SIGSEGV.EXC_BAD_ACCESS.PC.000000010ed954bf.STACK.0000000f38a4c8be.ADDR.000000004d555462.fuzz
[mkv] SeekHead position beyond end of file - incomplete file?
(+) Video --vid=1 () (h264 720x432 25.000fps)
(+) Audio --aid=1 --alang=fre () (ac3 2ch)
(+) Subs --sid=1 --slang=fre (*) (dvd_subtitle)
[vo/gpu] opengl cocoa backend is deprecated, use vo=libmpv instead
[debug]ao_c->filter->f->pins[1]:0x7f8e2f5418d0
[debug]mpctx:0x7f8e32004840
[debug]ao_c:0x7f8e2f5351b0
[debug]ao_c->filter:0x7f8e2f5414f8
[debug]ao_c->filter->got_output_eof:0x0
[debug]mpctx->audio_status:0x0
[debug]
[mkv] Invalid EBML length at position 13124
[mkv] Corrupt file detected. Trying to resync starting from position 13124...
[ffmpeg/audio] ac3: expacc 126 is out-of-range
[ffmpeg/audio] ac3: error decoding the audio block
No video PTS! Making something up. Using 25.000000 FPS.
[debug]ao_c->filter->f->pins[1]:0x7f8e2f5418d0
Audio: no audio
[debug]mpctx:0x7f8e32004840
[debug]ao_c:0x7f8e2f5351b0
[debug]ao_c->filter:0x7f8e2f5414f8
[debug]ao_c->filter->got_output_eof:0x0
[debug]mpctx->audio_status:0x5
[debug]
VO: [gpu] 720x432 => 1455x432 yuv420p
V: -00:00:00 / 00:00:00 (0%)
Exiting... (End of file)
2、Crashed info
Playing: ./SIGSEGV.EXC_BAD_ACCESS.PC.000000010ed954bf.STACK.0000000f38a4c8be.ADDR.000000004d555462.fuzz
[mkv] SeekHead position beyond end of file - incomplete file?
(+) Video --vid=1 () (h264 720x432 25.000fps)
(+) Audio --aid=1 --alang=fre () (ac3 2ch)
(+) Subs --sid=1 --slang=fre (*) (dvd_subtitle)
[vo/gpu] opengl cocoa backend is deprecated, use vo=libmpv instead
[debug]ao_c->filter->f->pins[1]:0x7f8ebc1211c0
[debug]mpctx:0x7f8ebe000040
[debug]ao_c:0x7f8ebc120d30
[debug]ao_c->filter:0x7f8ebc120858
[debug]ao_c->filter->got_output_eof:0x0
[debug]mpctx->audio_status:0x0
[debug]
[mkv] Invalid EBML length at position 13124
[mkv] Corrupt file detected. Trying to resync starting from position 13124...
No video PTS! Making something up. Using 25.000000 FPS.
[ffmpeg/audio] ac3: expacc 126 is out-of-range
[ffmpeg/audio] ac3: error decoding the audio block
[debug]ao_c->filter->f->pins[1]:0x7f8ebc1211c0
Audio: no audio
[debug]mpctx:0x7f8ebe000040
[debug]ao_c:0x7f8ebc120d30
[debug]ao_c->filter:0x312d320a6572662d
UndefinedBehaviorSanitizer:DEADLYSIGNAL
==3033==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000000000 (pc 0x0001012bb3f9 bp 0x7000039f3dc0 sp 0x7000039f3d00 T61145)
After debugging I think this is an Use after free Vulnerability.
audio.c:425 uinit_audio_chain(mpctx); this line free the ao_c
audio.c:810 if(ao_c->filter->got_output_eof && . this line reuse it
i don't think the uninit in line 425 is the culprit. it's called in order and before the code in line 810. it's some race condition in another part of the code.
I think @3kyo0 was right, that's exactly what I observed.