Bug 816994 - Skip Opus packets with invalid lengths. r=derf a=bajaj
authorRalph Giles <giles@mozilla.com>
Tue, 11 Dec 2012 11:25:10 -0800
changeset 117776 a3e6bd7f973610b06ef3ccaf39ccbd4cd2cc3992
parent 117773 8b2da786634a136f1397043be8ecdd978aefdfd1
child 117777 f4467b37dfef0ab3dcb31622943e2774affdfb00
push id75
push userdbaron@mozilla.com
push dateSat, 22 Dec 2012 00:41:31 +0000
reviewersderf, bajaj
bugs816994
milestone18.0
Bug 816994 - Skip Opus packets with invalid lengths. r=derf a=bajaj Reject Opus packets less than 2.5 ms or more than 120 ms in length, which are invalid by the spec. Also explicitly check for error after opus_packet_get_nb_frames() since this could indicate the subsequent call to opus_packet_get_samples_per_frame() call will segfault because the packet buffer length is invalid. Based on a patch by Tim Terriberry. --- content/media/ogg/nsOggReader.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
content/media/ogg/nsOggReader.cpp
--- a/content/media/ogg/nsOggReader.cpp
+++ b/content/media/ogg/nsOggReader.cpp
@@ -405,24 +405,27 @@ nsresult nsOggReader::DecodeVorbis(ogg_p
     }
   }
   return NS_OK;
 }
 #ifdef MOZ_OPUS
 nsresult nsOggReader::DecodeOpus(ogg_packet* aPacket) {
   NS_ASSERTION(aPacket->granulepos != -1, "Must know opus granulepos!");
 
-  // Maximum value is 63*2880.
+  // Maximum value is 63*2880, so there's no chance of overflow.
   int32_t frames_number = opus_packet_get_nb_frames(aPacket->packet,
                                                     aPacket->bytes);
+  if (frames_number <= 0)
+    return NS_ERROR_FAILURE; // Invalid packet header.
   int32_t samples = opus_packet_get_samples_per_frame(aPacket->packet,
                                                       (opus_int32) mOpusState->mRate);
   int32_t frames = frames_number*samples;
 
-  if (frames <= 0)
+  // A valid Opus packet must be between 2.5 and 120 ms long.
+  if (frames < 120 || frames > 5760)
     return NS_ERROR_FAILURE;
   uint32_t channels = mOpusState->mChannels;
   nsAutoArrayPtr<AudioDataValue> buffer(new AudioDataValue[frames * channels]);
 
   // Decode to the appropriate sample type.
 #ifdef MOZ_SAMPLE_TYPE_FLOAT32
   int ret = opus_multistream_decode_float(mOpusState->mDecoder,
                                           aPacket->packet, aPacket->bytes,