[opus] Integer overflow in opus_packet_parse_impl

Jüri Aedla aedla at google.com
Tue Nov 13 00:01:43 PST 2012


Hello,

there is a chance for an integer overflow in opus_packet_parse_impl():

   int padding=0;
   int p;
   do {
      if (len<=0)
         return OPUS_INVALID_PACKET;
      p = *data++;
      len--;
      padding += p==255 ? 254: p;
   } while (p==255);
   len -= padding;
   ...
   if (len<0)
      return OPUS_INVALID_PACKET;

When ~16 MB of 0xff bytes is fed to the decoder, the padding variable overflows
which leads to out-of-bounds read. It would be good to add a check for the
overflow even if most cases won't allow that much data to be fed to the decoder.


Here is a reproducer:

#include <string.h>
#include "opus.h"

unsigned char in_buf[16909318];
unsigned short out_buf[11520];

int main() {
  OpusDecoder *decoder;
  int result;
  int error;

  in_buf[0] = 0xff;
  in_buf[1] = 0x41;
  memset(in_buf + 2, 0xff, 16909315);
  in_buf[16909317] = 0x0b;

  decoder = opus_decoder_create(48000, 2, &error);
  result = opus_decode(decoder, in_buf, 16909318, out_buf, 5760, 0);
}


Here is the patch I'm suggesting:

--- opus_decoder_old.c	2012-11-12 23:35:03.289595241 -0800
+++ opus_decoder.c	2012-11-12 23:36:44.550437586 -0800
@@ -34,6 +34,7 @@
 #endif

 #include <stdarg.h>
+#include <limits.h>
 #include "celt.h"
 #include "opus.h"
 #include "entdec.h"
@@ -619,6 +620,8 @@
                return OPUS_INVALID_PACKET;
             p = *data++;
             len--;
+            if (padding > INT_MAX - p)
+               return OPUS_INVALID_PACKET;
             padding += p==255 ? 254: p;
          } while (p==255);
          len -= padding;

Cheers,
Jüri


More information about the opus mailing list