• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)27 void 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