Opened 12 years ago
Closed 12 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 , 12 years ago
Priority: | normal → important |
---|
comment:2 by , 12 years ago
comment:3 by , 12 years ago
Keywords: | crash abort sctp added |
---|---|
Reproduced by developer: | set |
Status: | new → 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 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | open → closed |
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.