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