diff --git a/chromecast/media/cma/backend/mixer/mixer_input.cc b/chromecast/media/cma/backend/mixer/mixer_input.cc --- a/chromecast/media/cma/backend/mixer/mixer_input.cc +++ b/chromecast/media/cma/backend/mixer/mixer_input.cc @@ -179,7 +179,8 @@ void MixerInput::CreateChannelMixer(int playout_channel, FilterGroup* filter_group) { int effective_channels = num_channels_; ::media::ChannelLayout channel_layout = channel_layout_; - if (playout_channel != kChannelAll && playout_channel < num_channels_) { + if (playout_channel != kChannelAll && playout_channel >= 0 && + playout_channel < num_channels_) { effective_channels = 1; channel_layout = ::media::CHANNEL_LAYOUT_MONO; } @@ -270,7 +271,8 @@ void MixerInput::RenderInterleaved(int num_output_frames) { // doing nothing anyway. float* data = prerender_pipeline_->GetOutputBuffer(); - if (playout_channel_ != kChannelAll && playout_channel_ < num_channels_) { + if (playout_channel_ != kChannelAll && playout_channel_ >= 0 && + playout_channel_ < num_channels_) { // Keep only the samples from the selected channel. float* dest = interleaved_.data(); for (int f = 0; f < num_output_frames; ++f) { diff --git a/chromecast/media/cma/backend/mixer/mixer_input_connection.cc b/chromecast/media/cma/backend/mixer/mixer_input_connection.cc --- a/chromecast/media/cma/backend/mixer/mixer_input_connection.cc +++ b/chromecast/media/cma/backend/mixer/mixer_input_connection.cc @@ -420,6 +420,9 @@ MixerInputConnection::MixerInputConnection( DCHECK(mixer_); DCHECK(socket_); CHECK_GT(num_channels_, 0); + // channel_selection arrives over an unauthenticated local socket; reject + // values that would index before the interleaved buffer in RenderInterleaved. + CHECK_GE(playout_channel_, kChannelAll); CHECK_GT(input_samples_per_second_, 0); DCHECK_LE(start_threshold_frames_, max_queued_frames_);