From ef83cc5458bf87cde1fe137ca909d7eb68f8411b Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Fri, 20 Sep 2019 12:24:56 +0200 Subject: [PATCH] Add fuzzer testing for Dependency Descriptor rtp header extension Bug: webrtc:10342 Change-Id: I46c61b9a137a7148ed80ad38da62132dacb270f8 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/153662 Commit-Queue: Danil Chapovalov Reviewed-by: Sam Zackrisson Cr-Commit-Position: refs/heads/master@{#29255} --- .../rtp_dependency_descriptor_reader.cc | 5 + test/fuzzers/BUILD.gn | 13 +++ .../dependency-descriptor-0 | Bin 0 -> 136 bytes .../dependency-descriptor-1 | Bin 0 -> 118 bytes .../dependency-descriptor-10 | Bin 0 -> 51 bytes .../dependency-descriptor-11 | 1 + .../dependency-descriptor-12 | Bin 0 -> 48 bytes .../dependency-descriptor-13 | Bin 0 -> 349 bytes .../dependency-descriptor-14 | Bin 0 -> 1872 bytes .../dependency-descriptor-15 | Bin 0 -> 48 bytes .../dependency-descriptor-16 | Bin 0 -> 349 bytes .../dependency-descriptor-2 | Bin 0 -> 12 bytes .../dependency-descriptor-3 | Bin 0 -> 12 bytes .../dependency-descriptor-4 | Bin 0 -> 2958 bytes .../dependency-descriptor-5 | Bin 0 -> 25 bytes .../dependency-descriptor-6 | Bin 0 -> 109 bytes .../dependency-descriptor-7 | Bin 0 -> 8 bytes .../dependency-descriptor-8 | 2 + .../dependency-descriptor-9 | Bin 0 -> 13 bytes .../rtp_dependency_descriptor_fuzzer.cc | 91 ++++++++++++++++++ 20 files changed, 112 insertions(+) create mode 100644 test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-0 create mode 100644 test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-1 create mode 100644 test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-10 create mode 100644 test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-11 create mode 100644 test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-12 create mode 100644 test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-13 create mode 100644 test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-14 create mode 100644 test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-15 create mode 100644 test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-16 create mode 100644 test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-2 create mode 100644 test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-3 create mode 100644 test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-4 create mode 100644 test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-5 create mode 100644 test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-6 create mode 100644 test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-7 create mode 100644 test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-8 create mode 100644 test/fuzzers/corpora/dependency_descriptor-corpus/dependency-descriptor-9 create mode 100644 test/fuzzers/rtp_dependency_descriptor_fuzzer.cc 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 0000000000000000000000000000000000000000..fc56e0e5911276d3505b136f162eee841f29d600 GIT binary patch literal 136 zcmWf#x3gz7Y-Ruh7BC4FP=JU5Np6N)w{F~mgQ#2o81}@f{{R0Uq(aF4zX|(ZL&l%X ZQ1xK#F;EVOLeqW=NqZ$&JHu%P1^{8dE;axF literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..b5c147f9f3535857556449a017dacd228945f26e GIT binary patch literal 118 zcmcDsXEbbPKnFjdz#2&N10{KYSOB6(P{{tj3Hx3K&Y#Nvn13-E0GSLwxEYwBMtuEm X$he=Efq@aq2XaJ2plo|6&A@|%Uj2Zs_{0{*7F$uE( literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..4d126eacc351389607962f14fc0bb7d1e6bf56fe GIT binary patch literal 48 vcmWf)|No!sKNAB3gM$5k1}+AMy~o>u90vCPYaJN=!)SYkRX{ewe|rW1fD;eh literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..847e67b79a931cb426e40821555706c8ec65eb50 GIT binary patch literal 349 zcmWf#|8K&+mx0lqnIgbKvTg=A5P~}4Co{7yvN23B6)-_27z0Av*~c0-!_>g(A5dWZ j11Kc;gPVbifq@w+i_nj3Hc*miCm>89!1}4orOXTfq!1YX literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..f5efdd131796026df3939a5389bb91c424604b2b GIT binary patch literal 1872 zcmb7FJ5B>Z4E2T;iBoJSkPsE3;uDbQ5fW*TxB-F&A<^al6xlQsoPZ0Y;|LUR0V)ba z#T8HrCArF5dl1 ztpqrhL^y1gBTvEe8@_r42M(R7hyh?6zk{)c#DJ28Ts6r!E5N?wTA^CAe2Z{?oV#>F z#0dkgPaXIgc@|R*OJ9 zWI7>=rw}2?v-+zL;5K=zo7|gF)pU?pb=)K$K_)~xdZ%5{({2IXGr9HHwSHqE9#AjcHyzSBBR3YF_`02V7!>o> xg$?^^#DR}%ACwec^YNV|3oE^9l7H;(0S6_UdlAw!qv%%txwAH>{tro;@CWMQ##{gZ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..830dc8a679724421c197da7ffb704ce3a1e20c61 GIT binary patch literal 48 zcmZQ(VE7+s4+Nf^oSY0?_JM)&_V%B)ef!2~&#-D0gSk82~At B3ZVc1 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..06017917dcd222fffa8d261a02d6cfcf060a70af GIT binary patch literal 349 zcmcDsXEbbPKnFjdz#2#c_VbEdx$*#=xk6pzSC?;h8--LZH1LIE} zkk~(V20f@4BZJOf_Mc#NJTPTUI)6aMtOMd|utxj;|Nk@DTZ7DCWcdHz7%0KWP*+#y zqYjjS0n`5sVEMBDAkEYO_Wz^pffn%|JogW5oDt)GUWmE+H*UcI17jsKkPW0X7zzu4 c(jX-)K+FtM>czke1-38-kiK;b6cjK407Cas5dZ)H literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..43cf72619cb7a7219bd3c00130c407114ab8d875 GIT binary patch literal 12 Tcmcb-U*$6Me+~buVco|z`*!FhJgV98UO=G literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..ff5785f0c3fb012a77ffbdb99ebf25d39afb02b8 GIT binary patch literal 2958 zcmcguPiqu06#r#MH`*<&PEQ^@t%Ax5c6SRxWn--;>o+JKy!#0}h|mw<&2Qkrn_@45 z1ENR4vuyncdJqI>swBR=Wd3Ysx*f3YgGpXqGB5AXFE5Fe*_Q%iX^1+z;?rx(miEVa^bf^|4NbpR@EPAxziwJF9gBfv=>8;~v63(!#%J)zY2342tZLw9!R^whEI|9g zR6l>`(M}pxtr{Y0G{K(vo=3kC8FA9gJDd5^mc6wriq?3WS~JNw`d+^6dzK{_h)njE zw7j&@anQ6G9$3*8)>#X>?t{)@8HhF0u!w5uf3eK%KR$jebDM?7tg)~id%GNwLRMa$?#2o~2A8AC z&DrXP5z8fni>MULJTE?{^g_{p-UL827f9i8Ky=Y^JKN2w4xYrjU`Am(Xt#=19;+fi z1#@(y8nabBIAsZ2(9LY0fD3#wF&yZ%8y2Q&(p%-|EtemcgG}3ZDytq^$yKC0Vc)7u U$#q~S%SU +#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