Commit 3de60bf5 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

wav: fix integer overflow (CVE-2008-2430)

When i_size is sufficiently large, we would overflow malloc(), and then
overwrite the heap with stream_Read().

Bug reported by: Alin Rad Pop, Secunia Research.

(cherry-picked from commit 95e2f0ff579a5b987cbde9454aa1fc86080528e2)
parent 9512f7de
/***************************************************************************** /*****************************************************************************
* wav.c : wav file input module for vlc * wav.c : wav file input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001-2007 the VideoLAN team * Copyright (C) 2001-2008 the VideoLAN team
* $Id$ * $Id$
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
...@@ -106,7 +106,8 @@ static int Open( vlc_object_t * p_this ) ...@@ -106,7 +106,8 @@ static int Open( vlc_object_t * p_this )
demux_sys_t *p_sys; demux_sys_t *p_sys;
const uint8_t *p_peek; const uint8_t *p_peek;
unsigned int i_size, i_extended; uint32_t i_size;
unsigned int i_extended;
const char *psz_name; const char *psz_name;
WAVEFORMATEXTENSIBLE *p_wf_ext = NULL; WAVEFORMATEXTENSIBLE *p_wf_ext = NULL;
...@@ -139,7 +140,8 @@ static int Open( vlc_object_t * p_this ) ...@@ -139,7 +140,8 @@ static int Open( vlc_object_t * p_this )
msg_Err( p_demux, "cannot find 'fmt ' chunk" ); msg_Err( p_demux, "cannot find 'fmt ' chunk" );
goto error; goto error;
} }
if( i_size < sizeof( WAVEFORMATEX ) - 2 ) /* XXX -2 isn't a typo */ i_size += 2;
if( i_size < sizeof( WAVEFORMATEX ) )
{ {
msg_Err( p_demux, "invalid 'fmt ' chunk" ); msg_Err( p_demux, "invalid 'fmt ' chunk" );
goto error; goto error;
...@@ -147,14 +149,15 @@ static int Open( vlc_object_t * p_this ) ...@@ -147,14 +149,15 @@ static int Open( vlc_object_t * p_this )
stream_Read( p_demux->s, NULL, 8 ); /* Cannot fail */ stream_Read( p_demux->s, NULL, 8 ); /* Cannot fail */
/* load waveformatex */ /* load waveformatex */
p_wf_ext = malloc( __EVEN( i_size ) + 2 ); p_wf_ext = malloc( i_size );
if( p_wf_ext == NULL ) if( p_wf_ext == NULL )
goto error; goto error;
p_wf = (WAVEFORMATEX *)p_wf_ext; p_wf = (WAVEFORMATEX *)p_wf_ext;
p_wf->cbSize = 0; p_wf->cbSize = 0;
if( stream_Read( p_demux->s, i_size -= 2;
p_wf, __EVEN( i_size ) ) < (int)__EVEN( i_size ) ) if( stream_Read( p_demux->s, p_wf, i_size ) != (int)i_size
|| ( ( i_size & 1 ) && stream_Read( p_demux->s, NULL, 1 ) != 1 ) )
{ {
msg_Err( p_demux, "cannot load 'fmt ' chunk" ); msg_Err( p_demux, "cannot load 'fmt ' chunk" );
goto error; goto error;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment