xref: /aosp_15_r20/frameworks/av/media/libstagefright/rtsp/fuzzer/rtp_writer_fuzzer.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 #include <fuzzer/FuzzedDataProvider.h>
19 #include <media/stagefright/MediaBuffer.h>
20 #include <media/stagefright/MediaDefs.h>
21 #include <media/stagefright/rtsp/ARTPWriter.h>
22 
23 constexpr int32_t kMinSize = 0;
24 constexpr int32_t kMaxSize = 65536;
25 constexpr int32_t kMaxTime = 1000;
26 constexpr int32_t kMaxBytes = 128;
27 constexpr int32_t kAMRNBFrameSizes[] = {13, 14, 16, 18, 20, 21, 27, 32};
28 constexpr int32_t kAMRWBFrameSizes[] = {18, 24, 33, 37, 41, 47, 51, 59, 61};
29 constexpr int32_t kAMRIndexOffset = 8;
30 
31 using namespace android;
32 
33 const char* kKeyMimeTypeArray[] = {MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_HEVC,
34                                    MEDIA_MIMETYPE_VIDEO_H263, MEDIA_MIMETYPE_AUDIO_AMR_NB,
35                                    MEDIA_MIMETYPE_AUDIO_AMR_WB};
36 
37 struct TestMediaSource : public MediaSource {
38   public:
TestMediaSourceTestMediaSource39     TestMediaSource(FuzzedDataProvider& mFdp) : mTestMetaData(new MetaData) {
40         int32_t vectorSize = 0;
41         mAllowRead = mFdp.ConsumeBool();
42         mKeySps = mFdp.ConsumeIntegral<int32_t>();
43         mKeyVps = mFdp.ConsumeIntegral<int32_t>();
44         mKeyPps = mFdp.ConsumeIntegral<int32_t>();
45         mKeyTime = mFdp.ConsumeIntegralInRange<int64_t>(kMinSize, kMaxTime);
46 
47         mMimeType = mFdp.PickValueInArray(kKeyMimeTypeArray);
48         mTestMetaData->setCString(kKeyMIMEType, mMimeType);
49         if (mMimeType == MEDIA_MIMETYPE_AUDIO_AMR_NB) {
50             int32_t index =
51                     mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, std::size(kAMRNBFrameSizes) - 1);
52             vectorSize = kAMRNBFrameSizes[index];
53             mData.push_back(kAMRIndexOffset * index);
54         } else if (mMimeType == MEDIA_MIMETYPE_AUDIO_AMR_WB) {
55             int32_t index =
56                     mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, std::size(kAMRWBFrameSizes) - 1);
57             vectorSize = kAMRWBFrameSizes[index];
58             mData.push_back(kAMRIndexOffset * index);
59         } else if (mMimeType == MEDIA_MIMETYPE_VIDEO_H263) {
60             // Required format for H263 media data
61             mData.push_back(0);
62             mData.push_back(0);
63             vectorSize = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize);
64         } else {
65             vectorSize = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize);
66         }
67         for (size_t idx = mData.size(); idx < vectorSize; ++idx) {
68             mData.push_back(mFdp.ConsumeIntegral<uint8_t>());
69         }
70     }
startTestMediaSource71     virtual status_t start(MetaData* /*params*/) { return OK; }
stopTestMediaSource72     virtual status_t stop() { return OK; }
getFormatTestMediaSource73     virtual sp<MetaData> getFormat() { return mTestMetaData; }
readTestMediaSource74     virtual status_t read(MediaBufferBase** buffer, const ReadOptions* /*options*/) {
75         if (!mAllowRead) {
76             return -1;
77         }
78         *buffer = new MediaBuffer(mData.data() /*data*/, mData.size() /*size*/);
79         if (mKeySps) {
80             (*buffer)->meta_data().setInt32(kKeySps, mKeySps);
81         }
82         if (mKeyVps) {
83             (*buffer)->meta_data().setInt32(kKeyVps, mKeyVps);
84         }
85         if (mKeyPps) {
86             (*buffer)->meta_data().setInt32(kKeyPps, mKeyPps);
87         }
88         (*buffer)->meta_data().setInt64(kKeyTime, mKeyTime);
89         return OK;
90     }
91 
92   private:
93     int32_t mKeySps;
94     int32_t mKeyVps;
95     int32_t mKeyPps;
96     int64_t mKeyTime;
97     bool mAllowRead;
98     const char* mMimeType;
99     sp<MetaData> mTestMetaData;
100     std::vector<uint8_t> mData;
101 };
102 
103 class ARTPWriterFuzzer {
104   public:
ARTPWriterFuzzer(const uint8_t * data,size_t size)105     ARTPWriterFuzzer(const uint8_t* data, size_t size)
106         : mDataSourceFd(memfd_create("InputFile", MFD_ALLOW_SEALING)), mFdp(data, size) {}
~ARTPWriterFuzzer()107     ~ARTPWriterFuzzer() { close(mDataSourceFd); }
108     void process();
109 
110   private:
111     void createARTPWriter();
112     const int32_t mDataSourceFd;
113     FuzzedDataProvider mFdp;
114     sp<ARTPWriter> mArtpWriter;
115 };
116 
createARTPWriter()117 void ARTPWriterFuzzer::createARTPWriter() {
118     String8 localIp = String8(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str());
119     String8 remoteIp = String8(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str());
120     mArtpWriter = sp<ARTPWriter>::make(
121             mDataSourceFd, localIp, mFdp.ConsumeIntegral<uint16_t>() /* localPort */, remoteIp,
122             mFdp.ConsumeIntegral<uint16_t>() /* remotePort */,
123             mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize) /* seqNo */);
124 }
125 
process()126 void ARTPWriterFuzzer::process() {
127     if (mFdp.ConsumeBool()) {
128         mArtpWriter = sp<ARTPWriter>::make(mDataSourceFd);
129         if (mArtpWriter->getSequenceNum() > kMaxSize) {
130             createARTPWriter();
131         }
132     } else {
133         createARTPWriter();
134     }
135 
136     mArtpWriter->addSource(sp<TestMediaSource>::make(mFdp) /* source */);
137 
138     while (mFdp.remaining_bytes()) {
139         auto invokeRTPWriterFuzzer = mFdp.PickValueInArray<const std::function<void()>>({
140                 [&]() {
141                     sp<MetaData> metaData = sp<MetaData>::make();
142                     if (mFdp.ConsumeBool()) {
143                         metaData->setInt32(kKeySelfID, mFdp.ConsumeIntegral<int32_t>());
144                     }
145                     if (mFdp.ConsumeBool()) {
146                         metaData->setInt32(kKeyPayloadType, mFdp.ConsumeIntegral<int32_t>());
147                     }
148                     if (mFdp.ConsumeBool()) {
149                         metaData->setInt32(kKeyRtpExtMap, mFdp.ConsumeIntegral<int32_t>());
150                     }
151                     if (mFdp.ConsumeBool()) {
152                         metaData->setInt32(kKeyRtpCvoDegrees, mFdp.ConsumeIntegral<int32_t>());
153                     }
154                     if (mFdp.ConsumeBool()) {
155                         metaData->setInt32(kKeyRtpDscp, mFdp.ConsumeIntegral<int32_t>());
156                     }
157                     if (mFdp.ConsumeBool()) {
158                         metaData->setInt64(kKeySocketNetwork, mFdp.ConsumeIntegral<int64_t>());
159                     }
160                     mArtpWriter->start(metaData.get() /*param*/);
161                 },
162                 [&]() {
163                     mArtpWriter->setTMMBNInfo(mFdp.ConsumeIntegral<uint32_t>() /* opponentID */,
164                                               mFdp.ConsumeIntegral<uint32_t>() /* bitrate */);
165                 },
166                 [&]() { mArtpWriter->stop(); },
167                 [&]() {
168                     mArtpWriter->updateCVODegrees(mFdp.ConsumeIntegral<int32_t>() /* cvoDegrees */);
169                 },
170                 [&]() {
171                     mArtpWriter->updatePayloadType(
172                             mFdp.ConsumeIntegral<int32_t>() /* payloadType */);
173                 },
174 
175         });
176         invokeRTPWriterFuzzer();
177     }
178 }
179 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)180 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
181     ARTPWriterFuzzer artpWriterFuzzer(data, size);
182     artpWriterFuzzer.process();
183     return 0;
184 }
185