Fix temporal index overflow in RtpPayloadParams H264ToGeneric() and Vp8ToGeneric() accepted temporal indices up to 7 but sized the decode target indications for kMaxTemporalStreams (4) temporal layers, so indices 4-7 hit a DCHECK or wrote past the end of the vector. Reject them like larger indices. Fixed: webrtc:566486041 Change-Id: Ifdb3f6554a6aabbcec79f0f866aa5ced578b655a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/505682 Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org> Cr-Commit-Position: refs/heads/main@{#48755}
diff --git a/call/rtp_payload_params.cc b/call/rtp_payload_params.cc index d5be15c..cf32a43 100644 --- a/call/rtp_payload_params.cc +++ b/call/rtp_payload_params.cc
@@ -451,6 +451,12 @@ last_frame_id_[0][0] = frame_id; } +// H264ToGeneric() and Vp8ToGeneric() only check the temporal index against +// kMaxTemporalStreams, which is sufficient as long as `last_frame_id_` can +// hold that many temporal layers. +static_assert(kMaxTemporalStreams <= + RtpGenericFrameDescriptor::kMaxTemporalLayers); + void RtpPayloadParams::H264ToGeneric(const CodecSpecificInfoH264& h264_info, int64_t frame_id, bool is_keyframe, @@ -458,7 +464,7 @@ const int temporal_index = h264_info.temporal_idx != kNoTemporalIdx ? h264_info.temporal_idx : 0; - if (temporal_index >= RtpGenericFrameDescriptor::kMaxTemporalLayers) { + if (temporal_index >= int{kMaxTemporalStreams}) { RTC_LOG(LS_WARNING) << "Temporal and/or spatial index is too high to be " "used with generic frame descriptor."; return; @@ -471,7 +477,6 @@ generic.temporal_index = temporal_index; // Generate decode target indications. - RTC_DCHECK_LT(temporal_index, kMaxTemporalStreams); generic.decode_target_indications.resize(kMaxTemporalStreams); auto it = std::fill_n(generic.decode_target_indications.begin(), temporal_index, DecodeTargetIndication::kNotPresent); @@ -525,7 +530,7 @@ const int temporal_index = vp8_header.temporalIdx != kNoTemporalIdx ? vp8_header.temporalIdx : 0; - if (temporal_index >= RtpGenericFrameDescriptor::kMaxTemporalLayers || + if (temporal_index >= int{kMaxTemporalStreams} || spatial_index >= RtpGenericFrameDescriptor::kMaxSpatialLayers) { RTC_LOG(LS_WARNING) << "Temporal and/or spatial index is too high to be " "used with generic frame descriptor."; @@ -540,7 +545,6 @@ generic.temporal_index = temporal_index; // Generate decode target indications. - RTC_DCHECK_LT(temporal_index, kMaxTemporalStreams); generic.decode_target_indications.resize(kMaxTemporalStreams); auto it = std::fill_n(generic.decode_target_indications.begin(), temporal_index, DecodeTargetIndication::kNotPresent);
diff --git a/call/rtp_payload_params_unittest.cc b/call/rtp_payload_params_unittest.cc index 18a3cdf..e6ccbc9 100644 --- a/call/rtp_payload_params_unittest.cc +++ b/call/rtp_payload_params_unittest.cc
@@ -29,7 +29,6 @@ #include "api/video/video_rotation.h" #include "call/rtp_config.h" #include "common_video/generic_frame_descriptor/generic_frame_info.h" -#include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h" #include "modules/rtp_rtcp/source/rtp_video_header.h" #include "modules/video_coding/codecs/interface/common_constants.h" #include "modules/video_coding/codecs/vp8/include/vp8_globals.h" @@ -557,8 +556,7 @@ encoded_image.set_frame_type(VideoFrameType::kVideoFrameDelta); CodecSpecificInfo codec_info; codec_info.codecType = kVideoCodecVP8; - codec_info.codecSpecific.VP8.temporalIdx = - RtpGenericFrameDescriptor::kMaxTemporalLayers; + codec_info.codecSpecific.VP8.temporalIdx = kMaxTemporalStreams; codec_info.codecSpecific.VP8.layerSync = false; RTPVideoHeader header = @@ -1400,8 +1398,7 @@ encoded_image.set_frame_type(VideoFrameType::kVideoFrameDelta); CodecSpecificInfo codec_info; codec_info.codecType = kVideoCodecH264; - codec_info.codecSpecific.H264.temporal_idx = - RtpGenericFrameDescriptor::kMaxTemporalLayers; + codec_info.codecSpecific.H264.temporal_idx = kMaxTemporalStreams; codec_info.codecSpecific.H264.base_layer_sync = false; RTPVideoHeader header =