Opened 5 years ago

Closed 5 years ago

#1865 closed defect (fixed)

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

Reported by: divVerent 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 Changed 5 years ago by cehoyos

  • Priority changed from normal to important

comment:2 Changed 5 years ago by divVerent

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 Changed 5 years ago by cehoyos

  • Keywords crash abort sctp added
  • Reproduced by developer set
  • Status changed from new to open
(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 Changed 5 years ago by michael

  • Resolution set to fixed
  • Status changed from open to closed
Note: See TracTickets for help on using tickets.