]> git.sesse.net Git - vlc/commitdiff
Fix Array Indexing Vulnerability in sdpplin_parse(). (CVE-2008-0073). (closes #1531).
authorPavlov Konstantin <thresh@altlinux.ru>
Wed, 19 Mar 2008 15:31:07 +0000 (18:31 +0300)
committerPavlov Konstantin <thresh@altlinux.ru>
Wed, 19 Mar 2008 15:31:07 +0000 (18:31 +0300)
Thanks to Alin Rad Pop, Secunia Research.
Ported from libxine.

modules/access/rtsp/real_sdpplin.c
modules/access/rtsp/real_sdpplin.h

index f12836734c3c96e7b4d9b96ef7072ac22c571d00..229501cb6b152c8600eebc430de428b89d8745bd 100644 (file)
@@ -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);
index 6014ee638a204f3d5cf989551f0c34d64cb8e676..10d37b8247592ae3fb50873fce84c4dcbedb7b94 100644 (file)
@@ -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;