1 /* 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include <bitset> 12 #include <vector> 13 14 #include "absl/types/optional.h" 15 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h" 16 #include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h" 17 #include "modules/rtp_rtcp/source/rtp_header_extensions.h" 18 #include "modules/rtp_rtcp/source/rtp_packet_received.h" 19 #include "modules/rtp_rtcp/source/rtp_video_layers_allocation_extension.h" 20 21 namespace webrtc { 22 // We decide which header extensions to register by reading four bytes 23 // from the beginning of `data` and interpreting it as a bitmask over 24 // the RTPExtensionType enum. This assert ensures four bytes are enough. 25 static_assert(kRtpExtensionNumberOfExtensions <= 32, 26 "Insufficient bits read to configure all header extensions. Add " 27 "an extra byte and update the switches."); 28 FuzzOneInput(const uint8_t * data,size_t size)29void FuzzOneInput(const uint8_t* data, size_t size) { 30 if (size <= 4) 31 return; 32 33 // Don't use the configuration byte as part of the packet. 34 std::bitset<32> extensionMask(*reinterpret_cast<const uint32_t*>(data)); 35 data += 4; 36 size -= 4; 37 38 RtpPacketReceived::ExtensionManager extensions(/*extmap_allow_mixed=*/true); 39 // Start at local_id = 1 since 0 is an invalid extension id. 40 int local_id = 1; 41 // Skip i = 0 since it maps to kRtpExtensionNone. 42 for (int i = 1; i < kRtpExtensionNumberOfExtensions; i++) { 43 RTPExtensionType extension_type = static_cast<RTPExtensionType>(i); 44 if (extensionMask[i]) { 45 // Extensions are registered with an ID, which you signal to the 46 // peer so they know what to expect. This code only cares about 47 // parsing so the value of the ID isn't relevant. 48 extensions.RegisterByType(local_id++, extension_type); 49 } 50 } 51 52 RtpPacketReceived packet(&extensions); 53 packet.Parse(data, size); 54 55 // Call packet accessors because they have extra checks. 56 packet.Marker(); 57 packet.PayloadType(); 58 packet.SequenceNumber(); 59 packet.Timestamp(); 60 packet.Ssrc(); 61 packet.Csrcs(); 62 63 // Each extension has its own getter. It is supported behaviour to 64 // call GetExtension on an extension which was not registered, so we 65 // don't check the bitmask here. 66 for (int i = 0; i < kRtpExtensionNumberOfExtensions; i++) { 67 switch (static_cast<RTPExtensionType>(i)) { 68 case kRtpExtensionNone: 69 case kRtpExtensionNumberOfExtensions: 70 break; 71 case kRtpExtensionTransmissionTimeOffset: 72 int32_t offset; 73 packet.GetExtension<TransmissionOffset>(&offset); 74 break; 75 case kRtpExtensionAudioLevel: 76 bool voice_activity; 77 uint8_t audio_level; 78 packet.GetExtension<AudioLevel>(&voice_activity, &audio_level); 79 break; 80 case kRtpExtensionCsrcAudioLevel: { 81 std::vector<uint8_t> audio_levels; 82 packet.GetExtension<CsrcAudioLevel>(&audio_levels); 83 break; 84 } 85 case kRtpExtensionAbsoluteSendTime: 86 uint32_t sendtime; 87 packet.GetExtension<AbsoluteSendTime>(&sendtime); 88 break; 89 case kRtpExtensionAbsoluteCaptureTime: { 90 AbsoluteCaptureTime extension; 91 packet.GetExtension<AbsoluteCaptureTimeExtension>(&extension); 92 break; 93 } 94 case kRtpExtensionVideoRotation: 95 uint8_t rotation; 96 packet.GetExtension<VideoOrientation>(&rotation); 97 break; 98 case kRtpExtensionTransportSequenceNumber: 99 uint16_t seqnum; 100 packet.GetExtension<TransportSequenceNumber>(&seqnum); 101 break; 102 case kRtpExtensionTransportSequenceNumber02: { 103 uint16_t seqnum; 104 absl::optional<FeedbackRequest> feedback_request; 105 packet.GetExtension<TransportSequenceNumberV2>(&seqnum, 106 &feedback_request); 107 break; 108 } 109 case kRtpExtensionPlayoutDelay: { 110 VideoPlayoutDelay playout; 111 packet.GetExtension<PlayoutDelayLimits>(&playout); 112 break; 113 } 114 case kRtpExtensionVideoContentType: 115 VideoContentType content_type; 116 packet.GetExtension<VideoContentTypeExtension>(&content_type); 117 break; 118 case kRtpExtensionVideoTiming: { 119 VideoSendTiming timing; 120 packet.GetExtension<VideoTimingExtension>(&timing); 121 break; 122 } 123 case kRtpExtensionRtpStreamId: { 124 std::string rsid; 125 packet.GetExtension<RtpStreamId>(&rsid); 126 break; 127 } 128 case kRtpExtensionRepairedRtpStreamId: { 129 std::string rsid; 130 packet.GetExtension<RepairedRtpStreamId>(&rsid); 131 break; 132 } 133 case kRtpExtensionMid: { 134 std::string mid; 135 packet.GetExtension<RtpMid>(&mid); 136 break; 137 } 138 case kRtpExtensionGenericFrameDescriptor00: { 139 RtpGenericFrameDescriptor descriptor; 140 packet.GetExtension<RtpGenericFrameDescriptorExtension00>(&descriptor); 141 break; 142 } 143 case kRtpExtensionColorSpace: { 144 ColorSpace color_space; 145 packet.GetExtension<ColorSpaceExtension>(&color_space); 146 break; 147 } 148 case kRtpExtensionInbandComfortNoise: { 149 absl::optional<uint8_t> noise_level; 150 packet.GetExtension<InbandComfortNoiseExtension>(&noise_level); 151 break; 152 } 153 case kRtpExtensionVideoLayersAllocation: { 154 VideoLayersAllocation allocation; 155 packet.GetExtension<RtpVideoLayersAllocationExtension>(&allocation); 156 break; 157 } 158 case kRtpExtensionVideoFrameTrackingId: { 159 uint16_t tracking_id; 160 packet.GetExtension<VideoFrameTrackingIdExtension>(&tracking_id); 161 break; 162 } 163 case kRtpExtensionGenericFrameDescriptor02: 164 // This extension requires state to read and so complicated that 165 // deserves own fuzzer. 166 break; 167 } 168 } 169 170 // Check that zero-ing mutable extensions wouldn't cause any problems. 171 packet.ZeroMutableExtensions(); 172 } 173 } // namespace webrtc 174