Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!

Bug 103555

Summary: media-video/mplayer: buffer overflow (CAN-2005-2718)
Product: Gentoo Security Reporter: Sune Kloppenborg Jeppesen (RETIRED) <jaervosz>
Component: VulnerabilitiesAssignee: Gentoo Security <security>
Status: RESOLVED FIXED    
Severity: major CC: carlo, media-video, ogolberg, rockoo
Priority: High    
Version: unspecified   
Hardware: All   
OS: Linux   
Whiteboard: A2 [glsa] jaervosz
Package list:
Runtime testing required: ---
Attachments:
Description Flags
poc none

Description Sune Kloppenborg Jeppesen (RETIRED) gentoo-dev 2005-08-23 22:20:02 UTC
Not sure this one is valid. Auditors please confirm: 
 
Advisory: mplayer buffer overflow 
 
Product:          mplayer 
Affected Version: 1.0_pre7 (tested), 1.0_pre6-r4 (tested), 
1.0pre6-3.3.5-20050130 (confirmed) 
OS affected:      Linux 2.4.* (tested), 2.6.* (confirmed), other OS not 
tested 
Date:             24.08.2005 
Author:           Sven Tantau - http://www.sven-tantau.de/ 
Advisory-URL: 
http://www.sven-tantau.de/public_files/mplayer/mplayer_20050824.txt 
Vendor-URL:       http://www.mplayerhq.hu/ 
Vendor-Status:    informed 
 
 
Product 
======= 
 
>> man mplayer 
 
DESCRIPTION 
mplayer  is  a movie player for Linux (runs on many other platforms and 
CPU architectures, see the documentation).  It plays most 
MPEG/VOB, AVI, ASF/WMA/WMV, RM, QT/MOV/MP4, OGG/OGM, MKV, VIVO, FLI, 
NuppelVideo, yuv4mpeg, FILM and RoQ files, supported by many 
native and binary codecs.  You can watch VideoCD, SVCD, DVD, 3ivx, DivX 
3/4/5 and even WMV movies, too. 
 
... 
 
Details 
======= 
 
For high values of the 2 bytes strf parameter in the audio header of a 
video file, it is possible to overflow sh_audio->a_buffer, overwrite the 
instruction pointer and execute arbitrary code. 
 
Not sure, but I think the problem is in: 
 
af.c: int af_calc_insize_constrained(af_stream_t* s, int len,int 
max_outsize,int max_insize); 
 
...as this function is used to calculate declen in dec_audio.c, and 
declen is supposed to prevent an overflow. 
 
Instruction pointer gets overwritten in: 
libmpdemux/demuxer.c: int demux_read_data(demux_stream_t *ds,unsigned 
char* mem,int len); 
 
If would like to reproduce this or write an exploit: 
Get a copy of 'Animaniacs - Nations of the World.avi'. 
(md5: 5ef6428a55c7b00095e2cb5554490acf sha1: 
1deeb9640f9864cd5b3db04ffc9a660039a172e4) 
Watch it.  :) 
Patch offset 0x12B to 0xFF. Use gdb. Have fun. 
 
 
History 
======= 
 
2005-08-10 issue found by Sven Tantau 
2005-08-16 vendor contacted and public disclosure 
2005-08-24 no reaction from mplayer team, posting to full disclosure
Comment 1 Thierry Carrez (RETIRED) gentoo-dev 2005-08-24 07:13:12 UTC
Setting to Auditing pending a confirmation.
Comment 2 Tavis Ormandy (RETIRED) gentoo-dev 2005-08-25 07:19:00 UTC
*** Bug 103690 has been marked as a duplicate of this bug. ***
Comment 3 Tavis Ormandy (RETIRED) gentoo-dev 2005-08-25 07:19:25 UTC
confirmed, definitely exploitable.
Comment 4 Tavis Ormandy (RETIRED) gentoo-dev 2005-08-25 10:38:12 UTC
Created attachment 66878 [details]
poc

the quick code I wrote to confirm vulnerability.
Comment 5 Reimar Döffinger 2005-08-26 05:44:49 UTC
This should fix it: http://www1.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
libmpcodecs/ad_pcm.c.diff?r1=1.18&r2=1.19
A workaround without recompiling should be adding "ac=-pcm," to the config file.
Exploiting this in more recent version should be more difficult due to a 
behaviour change that causes audio not to be played.
Comment 6 Tavis Ormandy (RETIRED) gentoo-dev 2005-08-26 10:34:48 UTC
*** Bug 103842 has been marked as a duplicate of this bug. ***
Comment 7 Luca Barbato gentoo-dev 2005-08-26 18:58:37 UTC
pre7-r1 in cvs waiting for stabilization
Comment 8 Thierry Carrez (RETIRED) gentoo-dev 2005-08-27 01:33:33 UTC
Arches, please test and mark stable.
Target KEYWORDS="alpha amd64 hppa ia64 ppc ppc64 sparc x86"

Let the maintainer know if some of you need a backport on pre6...
Comment 9 Reimar Döffinger 2005-08-27 01:46:11 UTC
Who can reproduce the exploit? Because I compiled pre7 on Debian and it did have 
no effect at all on eip (but it seemed to break the X Display info, so it 
crashed later on). My Gentoo system is 64bit, so it won't work there either...
Comment 10 Tavis Ormandy (RETIRED) gentoo-dev 2005-08-27 02:23:23 UTC
(In reply to comment #9)
> Who can reproduce the exploit? Because I compiled pre7 on Debian and it did 
have 
> no effect at all on eip (but it seemed to break the X Display info, so it 
> crashed later on). My Gentoo system is 64bit, so it won't work there either...

Reimar, it was only a quick example to reproduce the crash as the instructions 
provided in the original advisory were not very helpful. It would take much more 
work to make a general purpose, work everywhere exploit and my motivation was 
simply to satisfy myself that this issue could be exploited. If you want to 
confirm it can be exploited, you will have to modify it to work on your system:

run mplayer on the exploit.avi in gdb, and break on the decode_video function:

$ gdb -q
(gdb) file mplayer
Reading symbols from /usr/bin/mplayer...done.
Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) break decode_video
Breakpoint 1 at 0x80ed814: file dec_video.c, line 303.
(gdb) r -really-quiet -vo sdl exploit.avi 
[Thread debugging using libthread_db enabled]
[New Thread 1091755168 (LWP 8887)]
[Switching to Thread 1091755168 (LWP 8887)]

Breakpoint 1, decode_video (sh_video=0x86949d8, 
    start=0x8715d58 '\220' <repeats 200 times>..., in_size=141647192, 
    drop_frame=0) at dec_video.c:303
303     unsigned int t=GetTimer();

confirm the buffer at *start contains the exploit code:

(gdb) x/10x 0x8715d58
0x8715d58:      0x90909090      0x90909090      0x90909090      0x90909090
0x8715d68:      0x90909090      0x90909090      0x90909090      0x90909090
0x8715d78:      0x90909090      0x90909090

yes, this is the nop sled..

now recompile the exploit with the ADDR defined as somewhere in this buffer.

$ mplayer -really-quiet -vo sdl /home/taviso/exploit.avi 
SDL: Using driver: x11
SDL: deactivating XScreensaver/DPMS
SDL: X11 Resolution 1280x1024
SDL: Using 0x32315659 (Planar YV12) image format
SDL: using hardware-surface
uid=1000(taviso) gid=100(users) groups=5(tty),6(disk),10(wheel)

You must use sdl, as the exploit overwrites one of libsdl's function pointers 
that gets executed via vo_sdl, there are other targets, but this was only a 
quick demonstration. If I set the exploit to use 0xdeadbeef, you can see how it 
reaches the sdl function pointer:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1091755168 (LWP 9195)]
0xdeadbeef in ?? ()
(gdb) bt
#0  0xdeadbeef in ?? ()
#1  0x407f19c2 in SDL_ListModes (format=0xdeadbeef, flags=3221225473)
    at SDL_video.c:341
#2  0x080d6615 in sdl_open (plugin=0x0, name=0x0) at vo_sdl.c:478
#3  0x080d6c60 in config (width=156, height=88, d_width=156, d_height=88, 
    flags=0, title=0xc0000001 <Address 0xc0000001 out of bounds>, 
    format=842094169) at vo_sdl.c:850
#4  0x080f6ba4 in config (vf=0x873e270, width=156, height=88, d_width=156, 
    d_height=88, flags=0, outfmt=842094169) at vf_vo.c:48
#5  0x080edd6c in mpcodecs_config_vo (sh=0x86949d8, w=88, h=156, 
    preferred_outfmt=3221225473) at vd.c:312
#6  0x080f0d63 in init_vo (sh=0x86949d8, pix_fmt=PIX_FMT_YUV420P)
    at vd_ffmpeg.c:512
#7  0x080f0ea4 in get_buffer (avctx=0x873d3a0, pic=0x8745028)
    at vd_ffmpeg.c:563
#8  0x083049e5 in cinepak_decode_frame (avctx=0x873d3a0, data=0x873e390, 
    data_size=0xc0000001, buf=0xc0000001 <Address 0xc0000001 out of bounds>, 
    buf_size=8192) at cinepak.c:396
#9  0x081d5f80 in avcodec_decode_video (avctx=0x873d3a0, picture=0xc0000001, 
    got_picture_ptr=0xbfffc3fc, 
    buf=0xc0000001 <Address 0xc0000001 out of bounds>, buf_size=-1073741823)
    at utils.c:536
#10 0x080f12db in decode (sh=0x86949d8, data=0x8715d60, len=8192, flags=0)
    at vd_ffmpeg.c:765
#11 0x080ed83e in decode_video (sh_video=0x86949d8, 
    start=0xc0000001 <Address 0xc0000001 out of bounds>, in_size=-1073741823, 
    drop_frame=0) at dec_video.c:309
#12 0x080a0a90 in main (argc=2, argv=0xbfffd804) at mplayer.c:2302
(gdb) ptype current_video 
type = struct SDL_VideoDevice {
    const char *name;
    int (*VideoInit)(SDL_VideoDevice *, SDL_PixelFormat *);
    SDL_Rect **(*ListModes)(SDL_VideoDevice *, SDL_PixelFormat *, Uint32);
...
(gdb) info addr current_video
Symbol "current_video" is static storage at address 0x4081a400.
(gdb) info symbol 0x4081a400
current_video in section .bss

The function pointer overwritten is part of the `current_video` struct owned by 
libSDL. It's possible you're using different features or configuration that 
means something else gets interrupted before sdl gets a chance to init, if so 
you will just have to take my word that this is definitely a serious security 
issue that could be exploited by someone willing to put some work into 
developing a reliable exploit.

SDL_Rect ** SDL_ListModes (SDL_PixelFormat *format, Uint32 flags)
{
    SDL_VideoDevice *video = current_video;
    SDL_VideoDevice *this  = current_video;
    SDL_Rect **modes;

    modes = NULL;
    if ( SDL_VideoSurface ) {
        if ( format == NULL ) {
            format = SDL_VideoSurface->format;
        }
        modes = video->ListModes(this, format, flags); /* <--- */
    }
    return(modes);
}
Comment 11 Reimar Döffinger 2005-08-27 04:31:12 UTC
Thanks for that extensive reply, I asked mostly out of personal interest.
And also because I wanted to know what we have lying around on the heap, maybe 
some of it can be moved to read-only places, making exploits more difficult.
Would be an interesting project if I happen to have too much time somewhen *g*.
Comment 12 Luca Barbato gentoo-dev 2005-08-27 05:16:09 UTC
hppa and ia64 were already pre7
ppc marked.

Removing them.
Comment 13 Markus Rothe (RETIRED) gentoo-dev 2005-08-27 05:37:46 UTC
stable on ppc64
Comment 14 Marcus D. Hanwell (RETIRED) gentoo-dev 2005-08-27 17:28:01 UTC
Stable on amd64. 
Comment 15 Thierry Carrez (RETIRED) gentoo-dev 2005-08-29 00:45:53 UTC
CAN number was asked.
Comment 16 Thierry Carrez (RETIRED) gentoo-dev 2005-08-30 00:22:34 UTC
======================================================
Candidate: CAN-2005-2718
URL: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-2718
Reference: FULLDISC:20050824 mplayer overflow
Reference: URL:http://marc.theaimsgroup.com/?l=full-disclosure&m=112484733122809&w=2
Reference: MISC:http://www.sven-tantau.de/public_files/mplayer/mplayer_20050824.txt
Reference: CONFIRM:https://bugs.gentoo.org/show_bug.cgi?id=103555

Buffer overflow in ad_pcm.c in MPlayer 1.0pre7 and earlier allows
remote attackers to execute arbitrary code via a video file with an
audio header containing a large value in a strf parameter.
Comment 17 Gustavo Zacarias (RETIRED) gentoo-dev 2005-08-30 06:09:22 UTC
Stable on sparc - not flawless but it never was anyway.
Comment 18 Ian Leitch (RETIRED) gentoo-dev 2005-08-30 06:30:40 UTC
Sorry about the wait, x86 will be done in a few houres.
Comment 19 Ian Leitch (RETIRED) gentoo-dev 2005-08-30 10:53:18 UTC
Stable on x86.
Comment 20 Thierry Carrez (RETIRED) gentoo-dev 2005-09-01 01:07:53 UTC
Alpha was apparently marked stable without comment.
Comment 21 Thierry Carrez (RETIRED) gentoo-dev 2005-09-01 04:48:10 UTC
GLSA 200509-01
Comment 22 Reimar Döffinger 2005-09-08 07:20:14 UTC
IMHO none of the advisories/whatever describes the issue 100% correctly.

> Buffer overflow in ad_pcm.c in MPlayer 1.0pre7 and earlier allows
> remote attackers to execute arbitrary code via a video file with an
> audio header containing a large value in a strf parameter.

It is not a strf parameter, it is a strf chunk. And in this case the
one for the audio that contains the WAVEHEADEREX struct.
High values in nChannels and wBitsPerSample in that struct can be used
to exploit it.
Also it should be possible to exploit with any container, i.e. wav, mov,
etc. Anything that can contain raw PCM and allows to set either sample
size or channel count to arbitrary numbers.
Correct me if you think I'm wrong.
Comment 23 Thierry Carrez (RETIRED) gentoo-dev 2005-09-08 07:55:46 UTC
You must be correct, as I'm getting lost in chunks, structs and headers...
Would the following change in our GLSA describe the issue more correctly :

"Sven Tantau discovered a heap overflow in the code handling the WAVEHEADEREX
struct of raw PCM audio streams."

Do you see any other needed change (like in the Title or Synopsis) ?
Comment 24 Reimar Döffinger 2005-09-09 11:04:31 UTC
I'd suggest
"Sven Tantau discovered a heap overflow in the code handling raw PCM audio 
streams with large channel count or sample size."
Mentioning WAVEHEADEREX is confusing IMHO, since it does not really matter how 
the number of channels/samplesize was specified.