Bug 1467938 - Fix out-of-bounds memory access in WebRTC VP9 Missing Frame Processing. r=ng
authorNils Ohlmeier [:drno] <drno@ohlmeier.org>
Fri, 08 Jun 2018 19:49:40 -0700
changeset 478813 44ae071a453f285f841d4c3cc13e0b21427ace92
parent 478812 f7e936e667e9bc408aecbd6ec7588ae40bc12996
child 478814 874dedd55599e4b87fe37a497a968c079f1cca69
child 478827 05e64334b8eb7fe444ca377058a615f4f5580694
push id1757
push userffxbld-merge
push dateFri, 24 Aug 2018 17:02:43 +0000
treeherdermozilla-release@736023aebdb1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersng
bugs1467938
milestone62.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 1467938 - Fix out-of-bounds memory access in WebRTC VP9 Missing Frame Processing. r=ng
media/webrtc/trunk/webrtc/modules/video_coding/rtp_frame_reference_finder.cc
--- a/media/webrtc/trunk/webrtc/modules/video_coding/rtp_frame_reference_finder.cc
+++ b/media/webrtc/trunk/webrtc/modules/video_coding/rtp_frame_reference_finder.cc
@@ -429,18 +429,21 @@ void RtpFrameReferenceFinder::ManageFram
   gof_info_.erase(gof_info_.begin(), clean_gof_info_to);
 
   if (frame->frame_type() == kVideoFrameKey) {
     // When using GOF all keyframes must include the scalability structure.
     if (!codec_header.ss_data_available)
       LOG(LS_WARNING) << "Received keyframe without scalability structure";
 
     frame->num_references = 0;
-    GofInfo info = gof_info_.find(codec_header.tl0_pic_idx)->second;
-    FrameReceivedVp9(frame->picture_id, &info);
+    auto gof_info_it = gof_info_.find(codec_header.tl0_pic_idx);
+    if (gof_info_it == gof_info_.end())
+      return;
+
+    FrameReceivedVp9(frame->picture_id, &gof_info_it->second);
     CompletedFrameVp9(std::move(frame));
     return;
   }
 
   auto gof_info_it = gof_info_.find(
       (codec_header.temporal_idx == 0 && !codec_header.ss_data_available)
           ? codec_header.tl0_pic_idx - 1
           : codec_header.tl0_pic_idx);
@@ -503,16 +506,22 @@ void RtpFrameReferenceFinder::ManageFram
 
 bool RtpFrameReferenceFinder::MissingRequiredFrameVp9(uint16_t picture_id,
                                                       const GofInfo& info) {
   size_t diff =
       ForwardDiff<uint16_t, kPicIdLength>(info.gof->pid_start, picture_id);
   size_t gof_idx = diff % info.gof->num_frames_in_gof;
   size_t temporal_idx = info.gof->temporal_idx[gof_idx];
 
+  if (temporal_idx >= kMaxTemporalLayers) {
+    LOG(LS_WARNING) << "At most " << kMaxTemporalLayers << " temporal "
+                    << "layers are supported.";
+    return true;
+  }
+
   // For every reference this frame has, check if there is a frame missing in
   // the interval (|ref_pid|, |picture_id|) in any of the lower temporal
   // layers. If so, we are missing a required frame.
   uint8_t num_references = info.gof->num_ref_pics[gof_idx];
   for (size_t i = 0; i < num_references; ++i) {
     uint16_t ref_pid =
         Subtract<kPicIdLength>(picture_id, info.gof->pid_diff[gof_idx][i]);
     for (size_t l = 0; l < temporal_idx; ++l) {