Opened 6 years ago

Closed 6 years ago

#2293 closed defect (fixed)

Apple HTTP Live Streaming demuxer does invalid accesses to avio internals

Reported by: gjdfgh Owned by:
Priority: important Component: avformat
Version: git-master Keywords: crash SIGSEGV hls
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

The "Apple HTTP Live Streaming" demuxer (hls.c) expects that the AVIOContext is libavformat's HTTP implementation, and accesses it like that without doing further checks. This leads to a segfault if the AVIOContext is actually created by the application.

You can find the following lines in hls.c in hls_read_header():

static int hls_read_header(AVFormatContext *s)
{
    URLContext *u = s->pb->opaque;
    ...
        av_opt_get(u->priv_data, "user-agent", 0, (uint8_t**)&(c->user_agent));

Obviously this fails if pb is a custom context, and pb->opaque is something user created.

Consider adding some other, API-visible mechanism to transfer data between AVIOContext and AVFormatContext for things that are not part of the bytestream? At the very least, the checks whether it's ok to poke around in AVIOContext internals must be improved.

Happened with git master from some days ago (9f16cb9e5), unknown whether this is a regression.

This can't be reproduced with ffmpeg and ffplay, naturally.

Change History (6)

comment:1 Changed 6 years ago by cehoyos

  • Component changed from undetermined to avformat
  • Keywords crash added
  • Priority changed from normal to important

Please add a backtrace of the crash including disassembly and register content.

comment:2 Changed 6 years ago by gjdfgh

Program received signal SIGSEGV, Segmentation fault.
av_opt_find2 (obj=obj@entry=0xffffffff, 
    name=name@entry=0x899a711 "user-agent", search_flags=search_flags@entry=0, 
    target_obj=target_obj@entry=0xbffff18c, opt_flags=0, unit=0x0)
    at libavutil/opt.c:1158
1158	    c= *(AVClass**)obj;
(gdb) bt
#0  av_opt_find2 (obj=obj@entry=0xffffffff, 
    name=name@entry=0x899a711 "user-agent", search_flags=search_flags@entry=0, 
    target_obj=target_obj@entry=0xbffff18c, opt_flags=0, unit=0x0)
    at libavutil/opt.c:1158
#1  0x088f524a in av_opt_get (obj=0xffffffff, 
    name=name@entry=0x899a711 "user-agent", search_flags=search_flags@entry=0, 
    out_val=out_val@entry=0x91f6f6c) at libavutil/opt.c:530
#2  0x081fc0fb in hls_read_header (s=0x91dcf80) at libavformat/hls.c:488
#3  0x082bec5a in avformat_open_input (ps=0xbffff330, 
    filename=0x91d4870 "http://fms3.mediadirect.ro/live3/_definst_/dolcesport/playlist.m3u8?publisher=6", fmt=0x8bd6740, options=0x0)
    at libavformat/utils.c:626
#4  0x0810d6dc in demux_open_lavf (demuxer=0x91f61b8) at demux/demux_lavf.c:535
(rest omitted)
(gdb) disas
Dump of assembler code for function av_opt_find2:
   0x088f29a0 <+0>:	push   %ebp
   0x088f29a1 <+1>:	push   %edi
   0x088f29a2 <+2>:	mov    %eax,%edi
   0x088f29a4 <+4>:	push   %esi
   0x088f29a5 <+5>:	push   %ebx
   0x088f29a6 <+6>:	sub    $0x3c,%esp
   0x088f29a9 <+9>:	test   %eax,%eax
   0x088f29ab <+11>:	mov    %ecx,0x1c(%esp)
   0x088f29af <+15>:	je     0x88f2a70 <av_opt_find2+208>
   0x088f29b5 <+21>:	test   $0x1,%cl
   0x088f29b8 <+24>:	mov    %edx,%ebx
=> 0x088f29ba <+26>:	mov    (%eax),%esi
   0x088f29bc <+28>:	je     0x88f2a10 <av_opt_find2+112>
   0x088f29be <+30>:	test   $0x2,%cl
   0x088f29c1 <+33>:	je     0x88f2a90 <av_opt_find2+240>
   0x088f29c7 <+39>:	movl   $0x0,0x2c(%esp)
   0x088f29cf <+47>:	xor    %edx,%edx
   0x088f29d1 <+49>:	mov    %ecx,%ebp
   0x088f29d3 <+51>:	jmp    0x88f2a05 <av_opt_find2+101>
   0x088f29d5 <+53>:	lea    0x0(%esi),%esi
   0x088f29d8 <+56>:	mov    %edx,(%esp)
   0x088f29db <+59>:	call   *%eax
---Type <return> to continue, or q <return> to quit---
Quit
(gdb) info registers
eax            0xffffffff	-1
ecx            0x0	0
edx            0x899a711	144287505
ebx            0x899a711	144287505
esp            0xbffff110	0xbffff110
ebp            0xbffff2cc	0xbffff2cc
esi            0x91f6f6c	153055084
edi            0xffffffff	-1
eip            0x88f29ba	0x88f29ba <av_opt_find2+26>
eflags         0x10246	[ PF ZF IF RF ]
cs             0x73	115
ss             0x7b	123
ds             0x7b	123
es             0x7b	123
fs             0x0	0
gs             0x33	51

comment:3 Changed 6 years ago by cehoyos

  • Keywords SIGSEGV hls added
  • Status changed from new to open

comment:4 follow-up: Changed 6 years ago by reimar

There is a patch on the ffmpeg-devel list, testing is welcome (I only tested it in MPlayer).
Note that the fix means you won't have support for e.g. cookies in HLS requests.

comment:5 in reply to: ↑ 4 Changed 6 years ago by gjdfgh

Note that the fix means you won't have support for e.g. cookies in HLS requests.

It would be nice if it worked somehow anyway. Maybe add a mechanism for out-of-band data like libavformat/libavcodec use for packets?

comment:6 Changed 6 years ago by reimar

  • Resolution set to fixed
  • Status changed from open to closed

Fix pushed.
Since that code is in the read_header function I'd expect that completely ordinary demuxer-specific options should work fine for specifying cookies from thirdparty applications.
While that would involve some extra work I still think it would be a reasonable start.
However since I know almost nothing about HLS and barely care about it I'm not the right person to discuss this with.

Note: See TracTickets for help on using tickets.