AEC3: Fix range in filter analyzer

This change prevents FilterAnalyzer from accessing memory out-of-bounds
when the filter is resized.

Bug: chromium:946439
Change-Id: I7e2392c8b1ff0ff55566c663bf6d7a40d7754501
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/129928
Reviewed-by: Per Åhgren <peah@webrtc.org>
Commit-Queue: Gustaf Ullberg <gustaf@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27318}
This commit is contained in:
Gustaf Ullberg 2019-03-27 15:52:03 +01:00 committed by Commit Bot
parent 01d3618a75
commit 3e61c51e7a
4 changed files with 45 additions and 7 deletions

View File

@ -207,6 +207,7 @@ if (rtc_include_tests) {
"erl_estimator_unittest.cc",
"erle_estimator_unittest.cc",
"fft_data_unittest.cc",
"filter_analyzer_unittest.cc",
"frame_blocker_unittest.cc",
"main_filter_update_gain_unittest.cc",
"matched_filter_lag_aggregator_unittest.cc",

View File

@ -144,11 +144,16 @@ void FilterAnalyzer::SetRegionToAnalyze(
rtc::ArrayView<const float> filter_time_domain) {
constexpr size_t kNumberBlocksToUpdate = 1;
auto& r = region_;
r.start_sample_ =
r.end_sample_ == filter_time_domain.size() - 1 ? 0 : r.end_sample_ + 1;
r.end_sample_ =
std::min(r.start_sample_ + kNumberBlocksToUpdate * kBlockSize - 1,
filter_time_domain.size() - 1);
r.start_sample_ =
r.end_sample_ >= filter_time_domain.size() - 1 ? 0 : r.end_sample_ + 1;
r.end_sample_ =
std::min(r.start_sample_ + kNumberBlocksToUpdate * kBlockSize - 1,
filter_time_domain.size() - 1);
// Check range.
RTC_DCHECK_LT(r.start_sample_, filter_time_domain.size());
RTC_DCHECK_LT(r.end_sample_, filter_time_domain.size());
RTC_DCHECK_LE(r.start_sample_, r.end_sample_);
}
FilterAnalyzer::ConsistentFilterDetector::ConsistentFilterDetector(

View File

@ -55,6 +55,9 @@ class FilterAnalyzer {
// Returns the preprocessed filter.
rtc::ArrayView<const float> GetAdjustedFilter() const { return h_highpass_; }
// Public for testing purposes only.
void SetRegionToAnalyze(rtc::ArrayView<const float> filter_time_domain);
private:
void AnalyzeRegion(rtc::ArrayView<const float> filter_time_domain,
const RenderBuffer& render_buffer);
@ -65,8 +68,6 @@ class FilterAnalyzer {
void ResetRegion();
void SetRegionToAnalyze(rtc::ArrayView<const float> filter_time_domain);
struct FilterRegion {
size_t start_sample_;
size_t end_sample_;

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/audio_processing/aec3/filter_analyzer.h"
#include <algorithm>
#include "test/gmock.h"
#include "test/gtest.h"
namespace webrtc {
// Verifies that the filter analyzer handles filter resizes properly.
TEST(FilterAnalyzer, FilterResize) {
EchoCanceller3Config c;
std::vector<float> filter(65, 0.f);
FilterAnalyzer fa(c);
fa.SetRegionToAnalyze(filter);
fa.SetRegionToAnalyze(filter);
filter.resize(32);
fa.SetRegionToAnalyze(filter);
}
} // namespace webrtc