9b5b2d8f21
CVE-2008-3732, CVE-2008-3794 ok sthen@
302 lines
13 KiB
Plaintext
302 lines
13 KiB
Plaintext
$OpenBSD: patch-modules_demux_ogg_c,v 1.7 2008/09/04 22:58:23 brad Exp $
|
|
--- modules/demux/ogg.c.orig Tue Jul 8 16:59:23 2008
|
|
+++ modules/demux/ogg.c Tue Sep 2 02:07:40 2008
|
|
@@ -105,20 +105,21 @@ struct demux_sys_t
|
|
};
|
|
|
|
/* OggDS headers for the new header format (used in ogm files) */
|
|
-typedef struct stream_header_video
|
|
+typedef struct
|
|
{
|
|
ogg_int32_t width;
|
|
ogg_int32_t height;
|
|
-} stream_header_video;
|
|
+} stream_header_video_t;
|
|
|
|
-typedef struct stream_header_audio
|
|
+typedef struct
|
|
{
|
|
ogg_int16_t channels;
|
|
+ ogg_int16_t padding;
|
|
ogg_int16_t blockalign;
|
|
ogg_int32_t avgbytespersec;
|
|
-} stream_header_audio;
|
|
+} stream_header_audio_t;
|
|
|
|
-typedef struct stream_header
|
|
+typedef struct
|
|
{
|
|
char streamtype[8];
|
|
char subtype[4];
|
|
@@ -131,15 +132,16 @@ typedef struct stream_header
|
|
|
|
ogg_int32_t buffersize;
|
|
ogg_int16_t bits_per_sample;
|
|
+ ogg_int16_t padding;
|
|
|
|
union
|
|
{
|
|
/* Video specific */
|
|
- stream_header_video video;
|
|
+ stream_header_video_t video;
|
|
/* Audio specific */
|
|
- stream_header_audio audio;
|
|
+ stream_header_audio_t audio;
|
|
} sh;
|
|
-} stream_header;
|
|
+} stream_header_t;
|
|
|
|
#define OGG_BLOCK_SIZE 4096
|
|
|
|
@@ -193,6 +195,8 @@ static int Open( vlc_object_t * p_this )
|
|
p_demux->pf_demux = Demux;
|
|
p_demux->pf_control = Control;
|
|
p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
|
|
+ if( !p_sys )
|
|
+ return VLC_ENOMEM;
|
|
|
|
memset( p_sys, 0, sizeof( demux_sys_t ) );
|
|
p_sys->i_bitrate = 0;
|
|
@@ -506,7 +510,7 @@ static void Ogg_DecodePacket( demux_t *p_demux,
|
|
|
|
if( p_stream->b_force_backup )
|
|
{
|
|
- uint8_t *p_extra;
|
|
+ uint8_t *p_sav;
|
|
vlc_bool_t b_store_size = VLC_TRUE;
|
|
|
|
p_stream->i_packets_backup++;
|
|
@@ -543,27 +547,34 @@ static void Ogg_DecodePacket( demux_t *p_demux,
|
|
|
|
/* Backup the ogg packet (likely an header packet) */
|
|
p_stream->p_headers =
|
|
- realloc( p_stream->p_headers, p_stream->i_headers +
|
|
+ realloc( p_sav = p_stream->p_headers, p_stream->i_headers +
|
|
p_oggpacket->bytes + (b_store_size ? 2 : 0) );
|
|
- p_extra = p_stream->p_headers + p_stream->i_headers;
|
|
- if( b_store_size )
|
|
+ if( p_stream->p_headers )
|
|
{
|
|
- *(p_extra++) = p_oggpacket->bytes >> 8;
|
|
- *(p_extra++) = p_oggpacket->bytes & 0xFF;
|
|
- }
|
|
- memcpy( p_extra, p_oggpacket->packet, p_oggpacket->bytes );
|
|
- p_stream->i_headers += p_oggpacket->bytes + (b_store_size ? 2 : 0);
|
|
+ uint8_t *p_extra = p_stream->p_headers + p_stream->i_headers;
|
|
+ if( b_store_size )
|
|
+ {
|
|
+ *(p_extra++) = p_oggpacket->bytes >> 8;
|
|
+ *(p_extra++) = p_oggpacket->bytes & 0xFF;
|
|
+ }
|
|
+ memcpy( p_extra, p_oggpacket->packet, p_oggpacket->bytes );
|
|
+ p_stream->i_headers += p_oggpacket->bytes + (b_store_size ? 2 : 0);
|
|
|
|
- if( !p_stream->b_force_backup )
|
|
+ if( !p_stream->b_force_backup )
|
|
+ {
|
|
+ /* Last header received, commit changes */
|
|
+ p_stream->fmt.i_extra = p_stream->i_headers;
|
|
+ p_stream->fmt.p_extra =
|
|
+ realloc( p_stream->fmt.p_extra, p_stream->i_headers );
|
|
+ memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
|
|
+ p_stream->i_headers );
|
|
+ es_out_Control( p_demux->out, ES_OUT_SET_FMT,
|
|
+ p_stream->p_es, &p_stream->fmt );
|
|
+ }
|
|
+ }
|
|
+ else
|
|
{
|
|
- /* Last header received, commit changes */
|
|
- p_stream->fmt.i_extra = p_stream->i_headers;
|
|
- p_stream->fmt.p_extra =
|
|
- realloc( p_stream->fmt.p_extra, p_stream->i_headers );
|
|
- memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
|
|
- p_stream->i_headers );
|
|
- es_out_Control( p_demux->out, ES_OUT_SET_FMT,
|
|
- p_stream->p_es, &p_stream->fmt );
|
|
+ p_stream->p_headers = p_sav;
|
|
}
|
|
|
|
b_selected = VLC_FALSE; /* Discard the header packet */
|
|
@@ -728,8 +739,6 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
|
|
ogg_page oggpage;
|
|
int i_stream;
|
|
|
|
-#define p_stream p_ogg->pp_stream[p_ogg->i_streams - 1]
|
|
-
|
|
while( Ogg_ReadPage( p_demux, &oggpage ) == VLC_SUCCESS )
|
|
{
|
|
if( ogg_page_bos( &oggpage ) )
|
|
@@ -739,12 +748,15 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
|
|
* We found the beginning of our first logical stream. */
|
|
while( ogg_page_bos( &oggpage ) )
|
|
{
|
|
- p_ogg->i_streams++;
|
|
- p_ogg->pp_stream =
|
|
- realloc( p_ogg->pp_stream, p_ogg->i_streams *
|
|
- sizeof(logical_stream_t *) );
|
|
+ logical_stream_t **pp_sav = p_ogg->pp_stream;
|
|
+ logical_stream_t *p_stream;
|
|
|
|
p_stream = malloc( sizeof(logical_stream_t) );
|
|
+ if( !p_stream )
|
|
+ return VLC_ENOMEM;
|
|
+
|
|
+ TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
|
|
+
|
|
memset( p_stream, 0, sizeof(logical_stream_t) );
|
|
p_stream->p_headers = 0;
|
|
p_stream->secondary_header_packets = 0;
|
|
@@ -916,12 +928,15 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
|
|
p_stream->fmt.i_cat = AUDIO_ES;
|
|
|
|
i_extra_size = GetWLE((oggpacket.packet+140));
|
|
- if( i_extra_size )
|
|
+ if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
|
|
{
|
|
p_stream->fmt.i_extra = i_extra_size;
|
|
p_stream->fmt.p_extra = malloc( i_extra_size );
|
|
- memcpy( p_stream->fmt.p_extra,
|
|
- oggpacket.packet + 142, i_extra_size );
|
|
+ if( p_stream->fmt.p_extra )
|
|
+ memcpy( p_stream->fmt.p_extra,
|
|
+ oggpacket.packet + 142, i_extra_size );
|
|
+ else
|
|
+ p_stream->fmt.i_extra = 0;
|
|
}
|
|
|
|
i_format_tag = GetWLE((oggpacket.packet+124));
|
|
@@ -966,15 +981,27 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
|
|
p_ogg->i_streams--;
|
|
}
|
|
}
|
|
- else if( (*oggpacket.packet & PACKET_TYPE_BITS )
|
|
- == PACKET_TYPE_HEADER &&
|
|
- oggpacket.bytes >= (int)sizeof(stream_header)+1 )
|
|
+ else if( (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER &&
|
|
+ oggpacket.bytes >= 56+1 )
|
|
{
|
|
- stream_header *st = (stream_header *)(oggpacket.packet+1);
|
|
+ stream_header_t tmp;
|
|
+ stream_header_t *st = &tmp;
|
|
|
|
+ memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
|
|
+ memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
|
|
+ st->size = GetDWLE( &oggpacket.packet[1+12] );
|
|
+ st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
|
|
+ st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
|
|
+ st->default_len = GetDWLE( &oggpacket.packet[1+32] );
|
|
+ st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
|
|
+ st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
|
|
+
|
|
/* Check for video header (new format) */
|
|
if( !strncmp( st->streamtype, "video", 5 ) )
|
|
{
|
|
+ st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
|
|
+ st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
|
|
+
|
|
p_stream->fmt.i_cat = VIDEO_ES;
|
|
|
|
/* We need to get rid of the header packet */
|
|
@@ -987,16 +1014,13 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
|
|
(char *)&p_stream->fmt.i_codec );
|
|
|
|
p_stream->fmt.video.i_frame_rate = 10000000;
|
|
- p_stream->fmt.video.i_frame_rate_base =
|
|
- GetQWLE(&st->time_unit);
|
|
- p_stream->f_rate = 10000000.0 /
|
|
- GetQWLE(&st->time_unit);
|
|
- p_stream->fmt.video.i_bits_per_pixel =
|
|
- GetWLE(&st->bits_per_sample);
|
|
- p_stream->fmt.video.i_width =
|
|
- GetDWLE(&st->sh.video.width);
|
|
- p_stream->fmt.video.i_height =
|
|
- GetDWLE(&st->sh.video.height);
|
|
+ p_stream->fmt.video.i_frame_rate_base = st->time_unit;
|
|
+ if( st->time_unit <= 0 )
|
|
+ st->time_unit = 400000;
|
|
+ p_stream->f_rate = 10000000.0 / st->time_unit;
|
|
+ p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
|
|
+ p_stream->fmt.video.i_width = st->sh.video.width;
|
|
+ p_stream->fmt.video.i_height = st->sh.video.height;
|
|
|
|
msg_Dbg( p_demux,
|
|
"fps: %f, width:%i; height:%i, bitcount:%i",
|
|
@@ -1009,36 +1033,42 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
|
|
else if( !strncmp( st->streamtype, "audio", 5 ) )
|
|
{
|
|
char p_buffer[5];
|
|
+ unsigned int i_extra_size;
|
|
int i_format_tag;
|
|
|
|
+ st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
|
|
+ st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
|
|
+ st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
|
|
+
|
|
p_stream->fmt.i_cat = AUDIO_ES;
|
|
|
|
/* We need to get rid of the header packet */
|
|
ogg_stream_packetout( &p_stream->os, &oggpacket );
|
|
|
|
- p_stream->fmt.i_extra = GetQWLE(&st->size) -
|
|
- sizeof(stream_header);
|
|
- if( p_stream->fmt.i_extra )
|
|
+ i_extra_size = st->size - 56;
|
|
+
|
|
+ if( i_extra_size > 0 &&
|
|
+ i_extra_size < oggpacket.bytes - 1 - 56 )
|
|
{
|
|
- p_stream->fmt.p_extra =
|
|
- malloc( p_stream->fmt.i_extra );
|
|
- memcpy( p_stream->fmt.p_extra, st + 1,
|
|
- p_stream->fmt.i_extra );
|
|
+ p_stream->fmt.i_extra = i_extra_size;
|
|
+ p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
|
|
+ if( p_stream->fmt.p_extra )
|
|
+ memcpy( p_stream->fmt.p_extra, st + 1,
|
|
+ p_stream->fmt.i_extra );
|
|
+ else
|
|
+ p_stream->fmt.i_extra = 0;
|
|
}
|
|
|
|
memcpy( p_buffer, st->subtype, 4 );
|
|
p_buffer[4] = '\0';
|
|
i_format_tag = strtol(p_buffer,NULL,16);
|
|
- p_stream->fmt.audio.i_channels =
|
|
- GetWLE(&st->sh.audio.channels);
|
|
- p_stream->f_rate = p_stream->fmt.audio.i_rate =
|
|
- GetQWLE(&st->samples_per_unit);
|
|
- p_stream->fmt.i_bitrate =
|
|
- GetDWLE(&st->sh.audio.avgbytespersec) * 8;
|
|
- p_stream->fmt.audio.i_blockalign =
|
|
- GetWLE(&st->sh.audio.blockalign);
|
|
- p_stream->fmt.audio.i_bitspersample =
|
|
- GetWLE(&st->bits_per_sample);
|
|
+ p_stream->fmt.audio.i_channels = st->sh.audio.channels;
|
|
+ if( st->time_unit <= 0 )
|
|
+ st->time_unit = 10000000;
|
|
+ p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
|
|
+ p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
|
|
+ p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
|
|
+ p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
|
|
|
|
wf_tag_to_fourcc( i_format_tag,
|
|
&p_stream->fmt.i_codec, 0 );
|
|
@@ -1116,7 +1146,6 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
|
|
return VLC_SUCCESS;
|
|
}
|
|
}
|
|
-#undef p_stream
|
|
|
|
return VLC_EGENERIC;
|
|
}
|
|
@@ -1374,7 +1403,7 @@ static void Ogg_ReadAnnodexHeader( vlc_object_t *p_thi
|
|
uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
|
|
p_oggpacket->bytes - 1 );
|
|
if( p && p[0] == '\r' && p[1] == '\n' )
|
|
- sscanf( (char*)(&p_oggpacket->packet[42]), "%1024s\r\n",
|
|
+ sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
|
|
content_type_string );
|
|
}
|
|
|