Opened 12 years ago
Closed 12 years ago
#4152 closed defect (fixed)
jacosub: deadlock with fuzzed file
| Reported by: | tholin | Owned by: | |
|---|---|---|---|
| Priority: | important | Component: | avformat |
| Version: | git-master | Keywords: | jacosub deadlock |
| Cc: | Blocked By: | ||
| Blocking: | Reproduced by developer: | yes | |
| Analyzed by developer: | no |
Description
I found a deadlock in mpv with fuzzed file. The problem appears to be in ffmpeg so I report it here directly.
jacosub_read_header() in ffmpeg/libavformat/jacosubdec.c:156 will continuesly call ff_get_line() as long as eof isn't reached.
When ff_get_line() reads a \r it tries to remove the following \n if it exists. If eof is triggered after the first read the next read will return 0 which is not a \n and the stream is rewound one byte and the eof flag is cleared. This puts the stream in the same state as before and jacosub_read_header() loops indefinitely.
int ff_get_line(AVIOContext *s, char *buf, int maxlen) ffmpeg/libavformat/aviobuf.c:669
{
int i = 0;
char c;
do {
c = avio_r8(s); <--- last byte read in stream (\r)
if (c && i < maxlen-1)
buf[i++] = c;
} while (c != '\n' && c != '\r' && c);
if (c == '\r' && avio_r8(s) != '\n') <--- trigger EOF and returns 0
avio_skip(s, -1); <--- rewinds and clears eof_reached flag
buf[i] = 0;
return i;
}
Here is a base64 encoded example file CQoKCgtAMUAxMwoKDQ0NDS4NDQ0LCwsLC6FcgAGhXIABDQ0NDQ0NDQ0NDYABDQ0fDQkNDQ0NDQ0NDQsNDQ0N
Attachments (1)
Change History (3)
by , 12 years ago
| Attachment: | jacosub.jss added |
|---|
comment:1 by , 12 years ago
| Keywords: | jacosub deadlock added |
|---|---|
| Priority: | normal → important |
| Reproduced by developer: | set |
| Status: | new → open |
comment:2 by , 12 years ago
| Resolution: | → fixed |
|---|---|
| Status: | open → closed |



For future tickets: Please understand that while an analysis is helpful, never replace the actual report with an analysis of the bug, always provide the failing command line together with the complete, uncut console output. And please do not compress, encrypt or encode the input sample, simply attach it.
(gdb) r -loglevel 99 -i jacosub.jss Starting program: ffmpeg_g -loglevel 99 -i jacosub.jss [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". ffmpeg version N-68182-g534f901 Copyright (c) 2000-2014 the FFmpeg developers built on Dec 3 2014 15:12:58 with gcc 4.7 (SUSE Linux) configuration: --enable-gpl libavutil 54. 15.100 / 54. 15.100 libavcodec 56. 13.100 / 56. 13.100 libavformat 56. 15.102 / 56. 15.102 libavdevice 56. 3.100 / 56. 3.100 libavfilter 5. 2.103 / 5. 2.103 libswscale 3. 1.101 / 3. 1.101 libswresample 1. 1.100 / 1. 1.100 libpostproc 53. 3.100 / 53. 3.100 Splitting the commandline. Reading option '-loglevel' ... matched as option 'loglevel' (set logging level) with argument '99'. Reading option '-i' ... matched as input file with argument 'jacosub.jss'. Finished splitting the commandline. Parsing a group of options: global . Applying option loglevel (set logging level) with argument 99. Successfully parsed a group of options. Parsing a group of options: input file jacosub.jss. Successfully parsed a group of options. Opening an input file: jacosub.jss. [jacosub @ 0x1a68ba0] Format jacosub probed with size=2048 and score=51 Program received signal SIGINT, Interrupt. 0x00007ffff62752d0 in __read_nocancel () from /lib64/libpthread.so.0 (gdb) bt #0 0x00007ffff62752d0 in __read_nocancel () from /lib64/libpthread.so.0 #1 0x00000000005679eb in file_read (h=<optimized out>, buf=<optimized out>, size=<optimized out>) at libavformat/file.c:86 #2 0x000000000054ac1c in retry_transfer_wrapper (transfer_func=0x5679d0 <file_read>, size_min=1, size=32768, buf=0x1a71210 "\t\n\n\n\v@1@13\n\n\r\r\r\r.\r\r\r\v\v\v\v\v\241\\\200\001\241\\\200\001\r\r\r\r\r\r\r\r\r\r\200\001\r\r\037\r\t\r\r\r\r\r\r\r\r\v\r\r\r\r", h=0x1a67f00) at libavformat/avio.c:303 #3 ffurl_read (h=0x1a67f00, buf=0x1a71210 "\t\n\n\n\v@1@13\n\n\r\r\r\r.\r\r\r\v\v\v\v\v\241\\\200\001\241\\\200\001\r\r\r\r\r\r\r\r\r\r\200\001\r\r\037\r\t\r\r\r\r\r\r\r\r\v\r\r\r\r", size=32768) at libavformat/avio.c:334 #4 0x000000000054b893 in fill_buffer (s=s@entry=0x1a683a0) at libavformat/aviobuf.c:459 #5 0x000000000054fa30 in avio_r8 (s=0x1a683a0) at libavformat/aviobuf.c:511 #6 ff_get_line (s=s@entry=0x1a683a0, buf=buf@entry=0x7fffffffce90 "\r", maxlen=maxlen@entry=512) at libavformat/aviobuf.c:679 #7 0x0000000000588fcf in jacosub_read_header (s=0x1a68ba0) at libavformat/jacosubdec.c:181 #8 0x000000000063eb75 in avformat_open_input (ps=ps@entry=0x7fffffffd5c8, filename=filename@entry=0x7fffffffe203 "jacosub.jss", fmt=fmt@entry=0x0, options=0x1a604d8) at libavformat/utils.c:463 #9 0x000000000047cd5d in open_input_file (o=o@entry=0x7fffffffd680, filename=<optimized out>) at ffmpeg_opt.c:873 #10 0x0000000000475ec4 in open_files (inout=inout@entry=0xef769f "input", open_file=open_file@entry=0x47b6b0 <open_input_file>, l=<optimized out>, l=<optimized out>) at ffmpeg_opt.c:2699 #11 0x000000000047d309 in ffmpeg_parse_options (argc=argc@entry=5, argv=argv@entry=0x7fffffffdd58) at ffmpeg_opt.c:2736 #12 0x000000000046dd58 in main (argc=5, argv=0x7fffffffdd58) at ffmpeg.c:3919