[vlc-commits] demux/aiff: integer-overflow leads to infinite loop

Filip Roséen git at videolan.org
Tue Dec 6 16:13:52 CET 2016


vlc/vlc-2.2 | branch: master | Filip Roséen <filip at atch.se> | Mon Oct 31 01:13:31 2016 +0100| [07283a71bf29d324c9b2b7fc34f71e4de5939397] | committer: Jean-Baptiste Kempf

demux/aiff: integer-overflow leads to infinite loop

Given that the previous implementation stored the size of the current
chunk-payload in an uint32_t, it would potentially overflow when
adding the size of the chunk header and conditional padding.

These changes fixes the previously described by storing the
chunk-total size in a larger integer type, as well as making sure that
we do not pass a too big of a value to vlc_stream_Read (that would
cause problems on 32bit platforms).

Fixes #17562

Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
(cherry picked from commit 6a08e8e3b1cdfa7193d48cc842f1ae7e3fa0593e)
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>

> http://git.videolan.org/gitweb.cgi/vlc/vlc-2.2.git/?a=commit;h=07283a71bf29d324c9b2b7fc34f71e4de5939397
---

 modules/demux/aiff.c | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/modules/demux/aiff.c b/modules/demux/aiff.c
index 8a7dd28..afeab81 100644
--- a/modules/demux/aiff.c
+++ b/modules/demux/aiff.c
@@ -32,6 +32,7 @@
 #include <vlc_common.h>
 #include <vlc_plugin.h>
 #include <vlc_demux.h>
+#include <limits.h>
 
 /* TODO:
  *  - ...
@@ -123,14 +124,14 @@ static int Open( vlc_object_t *p_this )
 
     for( ;; )
     {
-        uint32_t i_size;
-
         if( stream_Peek( p_demux->s, &p_peek, 8 ) < 8 )
             goto error;
 
-        i_size = GetDWBE( &p_peek[4] );
+        uint32_t i_data_size = GetDWBE( &p_peek[4] );
+        uint64_t i_chunk_size = UINT64_C( 8 ) + i_data_size + ( i_data_size & 1 );
 
-        msg_Dbg( p_demux, "chunk fcc=%4.4s size=%d", p_peek, i_size );
+        msg_Dbg( p_demux, "chunk fcc=%4.4s size=%" PRIu64 " data_size=%" PRIu32,
+            p_peek, i_chunk_size, i_data_size );
 
         if( !memcmp( p_peek, "COMM", 4 ) )
         {
@@ -152,7 +153,7 @@ static int Open( vlc_object_t *p_this )
                 goto error;
 
             p_sys->i_ssnd_pos = stream_Tell( p_demux->s );
-            p_sys->i_ssnd_size = i_size;
+            p_sys->i_ssnd_size = i_data_size;
             p_sys->i_ssnd_offset = GetDWBE( &p_peek[8] );
             p_sys->i_ssnd_blocksize = GetDWBE( &p_peek[12] );
 
@@ -165,14 +166,19 @@ static int Open( vlc_object_t *p_this )
             break;
         }
 
-        /* Skip this chunk */
-        i_size += 8;
-        if( (i_size % 2) != 0 )
-            i_size++;
-        if( stream_Read( p_demux->s, NULL, i_size ) != (int)i_size )
+        /* consume chunk data */
+        for( ssize_t i_req; i_chunk_size; i_chunk_size -= i_req )
         {
-            msg_Warn( p_demux, "incomplete file" );
-            goto error;
+#if SSIZE_MAX < UINT64_MAX
+            i_req = __MIN( SSIZE_MAX, i_chunk_size );
+#else
+            i_req = i_chunk_size;
+#endif
+            if( stream_Read( p_demux->s, NULL, i_req ) != i_req )
+            {
+                msg_Warn( p_demux, "incomplete file" );
+                goto error;
+            }
         }
     }
 



More information about the vlc-commits mailing list