Opened 7 years ago

Closed 7 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


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)

jacosub.jss (63 bytes ) - added by Carl Eugen Hoyos 7 years ago.

Download all attachments as: .zip

Change History (3)

by Carl Eugen Hoyos, 7 years ago

Attachment: jacosub.jss added

comment:1 by Carl Eugen Hoyos, 7 years ago

Keywords: jacosub deadlock added
Priority: normalimportant
Reproduced by developer: set
Status: newopen

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/".
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/
(gdb) bt
#0  0x00007ffff62752d0 in __read_nocancel () from /lib64/
#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

comment:2 by Michael Niedermayer, 7 years ago

Resolution: fixed
Status: openclosed
Note: See TracTickets for help on using tickets.