Bug 1200148 - Sanity check header lengths in Vorbis CodecData. r=derf
authorMatthew Gregan <kinetik@flim.org>
Tue, 08 Sep 2015 11:44:45 +1200
changeset 294353 78050272add479077443c9cc8dfba6f55be933b9
parent 294352 10e3f62dc8a66c514fd1b3b42604cc5b7be8ebdc
child 294354 d8f6186e342570f0853f537c398714be359cbc86
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersderf
bugs1200148
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1200148 - Sanity check header lengths in Vorbis CodecData. r=derf
media/libnestegg/README_MOZILLA
media/libnestegg/src/nestegg.c
--- a/media/libnestegg/README_MOZILLA
+++ b/media/libnestegg/README_MOZILLA
@@ -1,8 +1,8 @@
 The source from this directory was copied from the nestegg
 git repository using the update.sh script.  The only changes
 made were those applied by update.sh and the addition of
 Makefile.in build files for the Mozilla build system.
 
 The nestegg git repository is: git://github.com/kinetiknz/nestegg.git
 
-The git commit ID used was d90e2ccac66e90c4a6f25318f8092b8596c97a67.
+The git commit ID used was c84eed87f214e2a551a971b7e9fffd9a0223d6c2.
--- a/media/libnestegg/src/nestegg.c
+++ b/media/libnestegg/src/nestegg.c
@@ -1112,35 +1112,16 @@ ne_parse(nestegg * ctx, struct ebml_elem
 
   if (r != 1)
     while (ctx->ancestor)
       ne_ctx_pop(ctx);
 
   return r;
 }
 
-static uint64_t
-ne_xiph_lace_value(unsigned char ** np)
-{
-  uint64_t lace;
-  uint64_t value;
-  unsigned char * p = *np;
-
-  lace = *p++;
-  value = lace;
-  while (lace == 255) {
-    lace = *p++;
-    value += lace;
-  }
-
-  *np = p;
-
-  return value;
-}
-
 static int
 ne_read_xiph_lace_value(nestegg_io * io, uint64_t * value, size_t * consumed)
 {
   int r;
   uint64_t lace;
 
   r = ne_read_uint(io, &lace, 1);
   if (r != 1)
@@ -2259,58 +2240,73 @@ nestegg_track_codec_data_count(nestegg *
 }
 
 int
 nestegg_track_codec_data(nestegg * ctx, unsigned int track, unsigned int item,
                          unsigned char ** data, size_t * length)
 {
   struct track_entry * entry;
   struct ebml_binary codec_private;
-  uint64_t sizes[3], total;
+  uint64_t sizes[3], size, total, avail;
   unsigned char * p;
   unsigned int count, i;
 
   *data = NULL;
   *length = 0;
+  count = 1;
 
   entry = ne_find_track_entry(ctx, track);
   if (!entry)
     return -1;
 
   if (nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_VORBIS
       && nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_OPUS)
     return -1;
 
   if (ne_get_binary(entry->codec_private, &codec_private) != 0)
     return -1;
 
   if (nestegg_track_codec_id(ctx, track) == NESTEGG_CODEC_VORBIS) {
     p = codec_private.data;
+    avail = codec_private.length;
+    if (avail < 1)
+      return -1;
+
     count = *p++ + 1;
-
-    if (count > 3)
+    avail -= 1;
+
+    if (count > 3 || item >= count)
       return -1;
 
-    i = 0;
     total = 0;
-    while (--count) {
-      sizes[i] = ne_xiph_lace_value(&p);
-      total += sizes[i];
-      i += 1;
+    for (i = 0; i < count - 1; ++i) {
+      size = 0;
+      do {
+        if (avail - total <= size) {
+          return -1;
+        }
+        size += *p;
+        avail -= 1;
+      } while (*p++ == 255);
+      if (avail - total < size)
+        return -1;
+      sizes[i] = size;
+      total += size;
     }
-    sizes[i] = codec_private.length - total - (p - codec_private.data);
+    sizes[i] = avail - total;
 
     for (i = 0; i < item; ++i) {
-      if (sizes[i] > LIMIT_FRAME)
-        return -1;
       p += sizes[i];
     }
     *data = p;
     *length = sizes[item];
   } else {
+    if (item >= count)
+      return -1;
+
     *data = codec_private.data;
     *length = codec_private.length;
   }
 
   return 0;
 }
 
 int