From: Pavlov Konstantin Date: Wed, 19 Mar 2008 15:31:07 +0000 (+0300) Subject: Fix Array Indexing Vulnerability in sdpplin_parse(). (CVE-2008-0073). (closes #1531). X-Git-Tag: 0.9.0-test0~1989 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=f351efa7d22645625d20204f86a44b194fde8352;p=vlc Fix Array Indexing Vulnerability in sdpplin_parse(). (CVE-2008-0073). (closes #1531). Thanks to Alin Rad Pop, Secunia Research. Ported from libxine. --- diff --git a/modules/access/rtsp/real_sdpplin.c b/modules/access/rtsp/real_sdpplin.c index f12836734c..229501cb6b 100644 --- a/modules/access/rtsp/real_sdpplin.c +++ b/modules/access/rtsp/real_sdpplin.c @@ -138,9 +138,16 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) { handled=0; if(filter(*data,"a=control:streamid=",&buf, BUFLEN)) { - desc->stream_id=atoi(buf); - handled=1; - *data=nl(*data); + /* This way negative values are mapped to unfeasibly high + * values, and will be discarded afterward + */ + unsigned long tmp = strtoul(buf, NULL, 10); + if ( tmp > UINT16_MAX ) + lprintf("stream id out of bound: %lu\n", tmp); + else + desc->stream_id=tmp; + handled=1; + *data=nl(*data); } if(filter(*data,"a=MaxBitRate:integer;",&buf, BUFLEN)) { desc->max_bit_rate=atoi(buf); @@ -254,7 +261,10 @@ sdpplin_t *sdpplin_parse(char *data) { } stream=sdpplin_parse_stream(&data); lprintf("got data for stream id %u\n", stream->stream_id); - desc->stream[stream->stream_id]=stream; + if ( stream->stream_id >= desc->stream_count ) + lprintf("stream id %u is greater than stream count %u\n", stream->stream_id, desc->stream_count); + else + desc->stream[stream->stream_id]=stream; continue; } if(filter(data,"a=Title:buffer;",&buf, BUFLEN)) { @@ -290,10 +300,17 @@ sdpplin_t *sdpplin_parse(char *data) { } } if(filter(data,"a=StreamCount:integer;",&buf, BUFLEN)) { - desc->stream_count=atoi(buf); - desc->stream = malloc(sizeof(sdpplin_stream_t*)*desc->stream_count); - handled=1; - data=nl(data); + /* This way negative values are mapped to unfeasibly high + * values, and will be discarded afterward + */ + unsigned long tmp = strtoul(buf, NULL, 10); + if ( tmp > UINT16_MAX ) + lprintf("stream count out of bound: %lu\n", tmp); + else + desc->stream_count = tmp; + desc->stream = malloc(sizeof(sdpplin_stream_t*)*desc->stream_count); + handled=1; + data=nl(data); } if(filter(data,"a=Flags:integer;",&buf, BUFLEN)) { desc->flags=atoi(buf); diff --git a/modules/access/rtsp/real_sdpplin.h b/modules/access/rtsp/real_sdpplin.h index 6014ee638a..10d37b8247 100644 --- a/modules/access/rtsp/real_sdpplin.h +++ b/modules/access/rtsp/real_sdpplin.h @@ -31,7 +31,7 @@ typedef struct { char *id; char *bandwidth; - int stream_id; + uint16_t stream_id; char *range; char *length; char *rtpmap; @@ -75,7 +75,7 @@ typedef struct { int flags; int is_real_data_type; - int stream_count; + uint16_t stream_count; char *title; char *author; char *copyright;