Template argument and corpora for Audio Processing Fuzzer.

We found out that

  int16_t x = test::FuzzDataHelper::ReadOrDefaultValue(0)

reads 4 bytes from the fuzzer input instead of 2. That means that
almost half the bits in the input data to audio_processing_fuzzer are
ignored. This change adds template arguments to force reading 2 bytes
when we only need 2.

We also add a small manually generated corpus. During local testing we
let the fuzzer run for a few hours on an empty corpus. Adding the
manually-generated files resulted in an immediate coverage increase by
~3%, and then by another 3% over the next few hours.

The manually generated corpus contains a short segment of speech with
real echo. We suspect that triggering Voice Activity Detection or echo
estimation filter convergence can be difficult for an automatic
fuzzer.

We remove the Level Controller config. We read 20 bytes extra after the
config to guard against future configuration changes.

Bug: webrtc:7820
Change-Id: If60c04f53b27c519c349a40bd13664eef7999368
Reviewed-on: https://webrtc-review.googlesource.com/58744
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Commit-Queue: Alex Loiko <aleloi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22269}
This commit is contained in:
Alex Loiko 2018-03-02 13:53:09 +01:00 committed by Commit Bot
parent 3e871ea047
commit 38c15d3995
8 changed files with 18 additions and 8 deletions

View File

@ -449,6 +449,7 @@ webrtc_fuzzer_test("audio_processing_fuzzer") {
"../../modules/audio_processing/aec3",
"../../rtc_base:rtc_base_approved",
]
seed_corpus = "corpora/audio_processing-corpus"
}
webrtc_fuzzer_test("comfort_noise_decoder_fuzzer") {

View File

@ -27,7 +27,6 @@ std::unique_ptr<AudioProcessing> CreateApm(test::FuzzDataHelper* fuzz_data) {
bool da = fuzz_data->ReadOrDefaultValue(true);
bool ie = fuzz_data->ReadOrDefaultValue(true);
bool red = fuzz_data->ReadOrDefaultValue(true);
bool lc = fuzz_data->ReadOrDefaultValue(true);
bool hpf = fuzz_data->ReadOrDefaultValue(true);
bool aec3 = fuzz_data->ReadOrDefaultValue(true);
@ -40,6 +39,18 @@ std::unique_ptr<AudioProcessing> CreateApm(test::FuzzDataHelper* fuzz_data) {
bool use_agc_limiter = fuzz_data->ReadOrDefaultValue(true);
bool use_agc2_limiter = fuzz_data->ReadOrDefaultValue(true);
// Read an int8 value, but don't let it be too large or small.
const float gain_controller2_gain_db =
rtc::SafeClamp<int>(fuzz_data->ReadOrDefaultValue<int8_t>(0), -50, 50);
// Ignore a few bytes. Bytes from this segment will be used for
// future config flag changes. We assume 40 bytes is enough for
// configuring the APM.
constexpr size_t kSizeOfConfigSegment = 40;
RTC_DCHECK(kSizeOfConfigSegment >= fuzz_data->BytesRead());
static_cast<void>(
fuzz_data->ReadByteArray(kSizeOfConfigSegment - fuzz_data->BytesRead()));
// Filter out incompatible settings that lead to CHECK failures.
if (use_aecm && use_aec) {
return nullptr;
@ -71,14 +82,10 @@ std::unique_ptr<AudioProcessing> CreateApm(test::FuzzDataHelper* fuzz_data) {
webrtc::AudioProcessing::Config apm_config;
apm_config.residual_echo_detector.enabled = red;
apm_config.level_controller.enabled = lc;
apm_config.high_pass_filter.enabled = hpf;
apm_config.gain_controller2.enabled = use_agc2_limiter;
// Read an int8 value, but don't let it be too large or small.
const float gain_db =
rtc::SafeClamp<int>(fuzz_data->ReadOrDefaultValue<int8_t>(0), -50, 50);
apm_config.gain_controller2.fixed_gain_db = gain_db;
apm_config.gain_controller2.fixed_gain_db = gain_controller2_gain_db;
apm->ApplyConfig(apm_config);

View File

@ -50,7 +50,7 @@ void GenerateFixedFrame(test::FuzzDataHelper* fuzz_data,
RTC_DCHECK_LE(samples_per_input_channel * num_channels,
AudioFrame::kMaxDataSizeSamples);
for (size_t i = 0; i < samples_per_input_channel * num_channels; ++i) {
fixed_frame->mutable_data()[i] = fuzz_data->ReadOrDefaultValue(0);
fixed_frame->mutable_data()[i] = fuzz_data->ReadOrDefaultValue<int16_t>(0);
}
}
} // namespace
@ -81,7 +81,7 @@ void FuzzAudioProcessing(test::FuzzDataHelper* fuzz_data,
static_cast<size_t>(fuzz_data->SelectOneOf(rate_kinds));
const bool num_channels = fuzz_data->ReadOrDefaultValue(true) ? 2 : 1;
const uint8_t stream_delay = fuzz_data->ReadOrDefaultValue(0);
const uint8_t stream_delay = fuzz_data->ReadOrDefaultValue<uint8_t>(0);
// API call needed for AEC-2 and AEC-m to run.
apm->set_stream_delay_ms(stream_delay);

View File

@ -79,6 +79,8 @@ class FuzzDataHelper {
return data_.subview(index_to_return, bytes);
}
size_t BytesRead() const { return data_ix_; }
private:
rtc::ArrayView<const uint8_t> data_;
size_t data_ix_ = 0;