diff --git a/modules/rtp_rtcp/source/rtp_dependency_descriptor_reader.cc b/modules/rtp_rtcp/source/rtp_dependency_descriptor_reader.cc index 8f0dcedf7b..517057822c 100644 --- a/modules/rtp_rtcp/source/rtp_dependency_descriptor_reader.cc +++ b/modules/rtp_rtcp/source/rtp_dependency_descriptor_reader.cc @@ -66,6 +66,11 @@ void RtpDependencyDescriptorReader::ReadTemplateDependencyStructure() { descriptor_->attached_structure = std::make_unique(); descriptor_->attached_structure->structure_id = ReadBits(6); + if (descriptor_->attached_structure->structure_id == + kExtendedFieldsIndicator) { + parsing_failed_ = true; + return; + } descriptor_->attached_structure->num_decode_targets = ReadBits(5) + 1; ReadTemplateLayers(); diff --git a/test/fuzzers/BUILD.gn b/test/fuzzers/BUILD.gn index 9c1c028156..0703a8961f 100644 --- a/test/fuzzers/BUILD.gn +++ b/test/fuzzers/BUILD.gn @@ -545,6 +545,19 @@ webrtc_fuzzer_test("comfort_noise_decoder_fuzzer") { ] } +webrtc_fuzzer_test("rtp_dependency_descriptor_fuzzer") { + sources = [ + "rtp_dependency_descriptor_fuzzer.cc", + ] + seed_corpus = "corpora/dependency_descriptor-corpus" + deps = [ + "../../api:array_view", + "../../common_video/generic_frame_descriptor", + "../../modules/rtp_rtcp:rtp_rtcp_format", + "../../rtc_base:checks", + ] +} + webrtc_fuzzer_test("rtp_frame_reference_finder_fuzzer") { sources = [ "rtp_frame_reference_finder_fuzzer.cc", diff --git a/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-0 b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-0 new file mode 100644 index 0000000000..fc56e0e591 Binary files /dev/null and b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-0 differ diff --git a/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-1 b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-1 new file mode 100644 index 0000000000..b5c147f9f3 Binary files /dev/null and b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-1 differ diff --git a/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-10 b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-10 new file mode 100644 index 0000000000..ced48741aa Binary files /dev/null and b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-10 differ diff --git a/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-11 b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-11 new file mode 100644 index 0000000000..53afe97468 --- /dev/null +++ b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-11 @@ -0,0 +1 @@ +ÿÿÿÿÿ°Ë±±o \ No newline at end of file diff --git a/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-12 b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-12 new file mode 100644 index 0000000000..4d126eacc3 Binary files /dev/null and b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-12 differ diff --git a/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-13 b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-13 new file mode 100644 index 0000000000..847e67b79a Binary files /dev/null and b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-13 differ diff --git a/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-14 b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-14 new file mode 100644 index 0000000000..f5efdd1317 Binary files /dev/null and b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-14 differ diff --git a/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-15 b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-15 new file mode 100644 index 0000000000..830dc8a679 Binary files /dev/null and b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-15 differ diff --git a/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-16 b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-16 new file mode 100644 index 0000000000..06017917dc Binary files /dev/null and b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-16 differ diff --git a/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-2 b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-2 new file mode 100644 index 0000000000..43cf72619c Binary files /dev/null and b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-2 differ diff --git a/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-3 b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-3 new file mode 100644 index 0000000000..a2e8e0c9ae Binary files /dev/null and b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-3 differ diff --git a/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-4 b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-4 new file mode 100644 index 0000000000..ff5785f0c3 Binary files /dev/null and b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-4 differ diff --git a/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-5 b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-5 new file mode 100644 index 0000000000..f1196c98aa Binary files /dev/null and b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-5 differ diff --git a/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-6 b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-6 new file mode 100644 index 0000000000..88ce0a1600 Binary files /dev/null and b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-6 differ diff --git a/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-7 b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-7 new file mode 100644 index 0000000000..9adb5c2125 Binary files /dev/null and b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-7 differ diff --git a/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-8 b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-8 new file mode 100644 index 0000000000..5a8f929a61 --- /dev/null +++ b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-8 @@ -0,0 +1,2 @@ +ÿÿÿÞ +‚ÿ diff --git a/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-9 b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-9 new file mode 100644 index 0000000000..bde1b127b3 Binary files /dev/null and b/test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-9 differ diff --git a/test/fuzzers/rtp_dependency_descriptor_fuzzer.cc b/test/fuzzers/rtp_dependency_descriptor_fuzzer.cc new file mode 100644 index 0000000000..fbe7ac32e0 --- /dev/null +++ b/test/fuzzers/rtp_dependency_descriptor_fuzzer.cc @@ -0,0 +1,91 @@ +/* + * 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 +#include +#include +#include +#include + +#include "api/array_view.h" +#include "common_video/generic_frame_descriptor/generic_frame_info.h" +#include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h" +#include "rtc_base/checks.h" +#include "test/fuzzers/fuzz_data_helper.h" + +namespace webrtc { +namespace { + +bool AreSame(const DependencyDescriptor& lhs, const DependencyDescriptor& rhs) { + return lhs.first_packet_in_frame == rhs.first_packet_in_frame && + lhs.last_packet_in_frame == rhs.last_packet_in_frame && + (lhs.attached_structure != nullptr) == + (rhs.attached_structure != nullptr) && + lhs.frame_number == rhs.frame_number && + lhs.resolution == rhs.resolution && + lhs.frame_dependencies == rhs.frame_dependencies; +} + +} // namespace + +void FuzzOneInput(const uint8_t* data, size_t size) { + FrameDependencyStructure structure1; + // nullptr during 1st while loop, after that should point to structure1. + const FrameDependencyStructure* structure1_ptr = nullptr; + std::unique_ptr structure2; + + test::FuzzDataHelper fuzz_data(rtc::MakeArrayView(data, size)); + while (fuzz_data.CanReadBytes(1)) { + // Treat next byte as size of the next extension. That aligns how + // two-byte rtp header extension sizes are written. + size_t next_size = fuzz_data.Read(); + auto raw = + fuzz_data.ReadByteArray(std::min(next_size, fuzz_data.BytesLeft())); + + // Read the random input. + DependencyDescriptor descriptor1; + if (!RtpDependencyDescriptorExtension::Parse(raw, structure1_ptr, + &descriptor1)) { + // Ignore invalid buffer and move on. + continue; + } + if (descriptor1.attached_structure) { + structure1 = *descriptor1.attached_structure; + structure1_ptr = &structure1; + } + RTC_CHECK(structure1_ptr); + + // Write parsed descriptor back into raw buffer. + size_t value_size = + RtpDependencyDescriptorExtension::ValueSize(structure1, descriptor1); + // Check |writer| use minimal number of bytes to pack the descriptor by + // checking it doesn't use more than reader consumed. + RTC_CHECK_LE(value_size, raw.size()); + uint8_t some_memory[256]; + // That should be true because value_size <= next_size < 256 + RTC_CHECK_LT(value_size, 256); + rtc::ArrayView write_buffer(some_memory, value_size); + RTC_CHECK(RtpDependencyDescriptorExtension::Write(write_buffer, structure1, + descriptor1)); + + // Parse what Write assembled. + // Unlike random input that should always succeed. + DependencyDescriptor descriptor2; + RTC_CHECK(RtpDependencyDescriptorExtension::Parse( + write_buffer, structure2.get(), &descriptor2)); + RTC_CHECK(AreSame(descriptor1, descriptor2)); + + if (descriptor2.attached_structure) { + structure2 = std::move(descriptor2.attached_structure); + } + } +} + +} // namespace webrtc