Opened 11 years ago

Closed 11 years ago

#1865 closed defect (fixed)

sctp.c: abort() call can be hit by bad user input

Reported by: Rudolf Polzer Owned by:
Priority: important Component: avformat
Version: git-master Keywords: crash abort sctp
Cc: Blocked By:
Blocking: Reproduced by developer: yes
Analyzed by developer: no

Description

Summary of the bug:
Because ffmpeg is a library, a mere bad URL passed to avio/ffurl code really shouldn't be able to cause a hard abort. However, exactly this is the case...

How to reproduce:
First set up a sctp listener:

% withsctp nc -vlp 127.0.0.1 1234

On another shell:

% catchsegv ./ffmpeg -f lavfi -i "life [out0]" -f nut "sctp://127.0.0.1:1234?max_streams=1"
ffmpeg version N-46130-g67420b3 Copyright (c) 2000-2012 the FFmpeg developers
  built on Oct 29 2012 16:09:38 with gcc 4.7.2 (GCC)
  configuration: 
  libavutil      52.  1.100 / 52.  1.100
  libavcodec     54. 69.100 / 54. 69.100
  libavformat    54. 35.100 / 54. 35.100
  libavdevice    54.  3.100 / 54.  3.100
  libavfilter     3. 20.106 /  3. 20.106
  libswscale      2.  1.101 /  2.  1.101
  libswresample   0. 16.100 /  0. 16.100
[lavfi @ 0x23cf260] Estimating duration from bitrate, this may be inaccurate
Input #0, lavfi, from 'life [out0]':
  Duration: N/A, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: rawvideo (B0W1 / 0x31573042), monob, 320x240 [SAR 1:1 DAR 4:3], 25 tbr, 25 tbn, 25 tbc
Aborted

Why does it crash? Because the option max_streams in sctp.c causes packets to be required to start with the stream index in the first 16 bits of each packet to send. And e.g. the nut muxer does not ensure this.

The danger is that any generic code using avio and letting the URL come from user - or worse - untrusted sources (possibly after verifying protocol and host name) can crash this way.

This error condition probably should rather cause a log message with error return to packet sending, instead... or the max_streams option should rather be implemented in a way so it's not part of the URL, but rather a parameter the calling code has to set using a function.

Change History (4)

comment:1 by Carl Eugen Hoyos, 11 years ago

Priority: normalimportant

comment:2 by Rudolf Polzer, 11 years ago

Oops, some typos:

The nc command is "withsctp nc -vlp 1234 127.0.0.1", of course. But any other sctp listener will do as well.

Also, I did not use catchsegv. It doesn't catch abort() anyway, and I know exactly I am hitting the one abort() call in sctp.c anyway.

comment:3 by Carl Eugen Hoyos, 11 years ago

Keywords: crash abort sctp added
Reproduced by developer: set
Status: newopen
(gdb) r -f lavfi -i "life [out0]" -f nut "sctp://127.0.0.1:1234?max_streams=1"
Starting program: ffmpeg_g -f lavfi -i "life [out0]" -f nut "sctp://127.0.0.1:1234?max_streams=1"
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
ffmpeg version N-46146-g11d695d Copyright (c) 2000-2012 the FFmpeg developers
  built on Oct 30 2012 00:50:29 with gcc 4.7 (SUSE Linux)
  configuration: --enable-gpl
  libavutil      52.  1.100 / 52.  1.100
  libavcodec     54. 69.100 / 54. 69.100
  libavformat    54. 35.100 / 54. 35.100
  libavdevice    54.  3.100 / 54.  3.100
  libavfilter     3. 20.109 /  3. 20.109
  libswscale      2.  1.101 /  2.  1.101
  libswresample   0. 16.100 /  0. 16.100
  libpostproc    52.  1.100 / 52.  1.100
[lavfi @ 0x159f2a0] Estimating duration from bitrate, this may be inaccurate
Input #0, lavfi, from 'life [out0]':
  Duration: N/A, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: rawvideo (B0W1 / 0x31573042), monob, 320x240 [SAR 1:1 DAR 4:3], 25 tbr, 25 tbn, 25 tbc
[New Thread 0x7ffff5e02700 (LWP 18810)]
[New Thread 0x7ffff5601700 (LWP 18811)]
[New Thread 0x7ffff4e00700 (LWP 18812)]
[New Thread 0x7ffff45ff700 (LWP 18813)]
[New Thread 0x7ffff3dfe700 (LWP 18814)]
[New Thread 0x7ffff35fd700 (LWP 18815)]
[New Thread 0x7ffff2dfc700 (LWP 18816)]
[New Thread 0x7ffff25fb700 (LWP 18817)]
[New Thread 0x7ffff1dfa700 (LWP 18818)]

Program received signal SIGABRT, Aborted.
0x00007ffff6558d25 in raise () from /lib64/libc.so.6
(gdb) bt
#0  0x00007ffff6558d25 in raise () from /lib64/libc.so.6
#1  0x00007ffff655a1a8 in abort () from /lib64/libc.so.6
#2  0x000000000057b5db in sctp_write (h=h@entry=0x159c3e0, buf=buf@entry=0x15ddf20 "nut/multimedia container",
    size=size@entry=268) at libavformat/sctp.c:300
#3  0x00000000004dddd3 in retry_transfer_wrapper (transfer_func=0x57b4a0 <sctp_write>, size_min=268, size=268,
    buf=0x15ddf20 "nut/multimedia container", h=0x159c3e0) at libavformat/avio.c:262
#4  ffurl_write (h=0x159c3e0, buf=0x15ddf20 "nut/multimedia container", size=268) at libavformat/avio.c:313
#5  0x00000000004dee0e in writeout (len=268, data=<optimized out>, s=0x159e4e0) at libavformat/aviobuf.c:125
#6  flush_buffer (s=0x159e4e0) at libavformat/aviobuf.c:136
#7  avio_flush (s=s@entry=0x159e4e0) at libavformat/aviobuf.c:189
#8  0x000000000054d29c in nut_write_header (s=0x159c520) at libavformat/nutenc.c:751
#9  0x000000000053b4b7 in avformat_write_header (s=s@entry=0x159c520, options=0x159fe48) at libavformat/mux.c:391
#10 0x0000000000461dc9 in transcode_init () at ffmpeg.c:2319
#11 0x000000000045036a in transcode () at ffmpeg.c:2947
#12 main (argc=8, argv=0x7fffffffddd8) at ffmpeg.c:3160

comment:4 by Michael Niedermayer, 11 years ago

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