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