xref: /aosp_15_r20/external/webrtc/test/fuzzers/rtp_packet_fuzzer.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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)29 void 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