1 /*
2 * Copyright (C) 2021 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 <MediaExtractorService.h>
19 #include <MediaPlayerService.h>
20 #include <StagefrightMetadataRetriever.h>
21 #include <binder/ProcessState.h>
22 #include <datasource/FileSource.h>
23 #include <media/IMediaHTTPService.h>
24 #include <media/stagefright/foundation/MediaDefs.h>
25 #include <media/stagefright/foundation/base64.h>
26
27 #include <fuzzer/FuzzedDataProvider.h>
28
29 using namespace std;
30 using namespace android;
31
32 const char *kMimeTypes[] = {MEDIA_MIMETYPE_IMAGE_JPEG, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC,
33 MEDIA_MIMETYPE_VIDEO_VP8, MEDIA_MIMETYPE_VIDEO_VP9,
34 MEDIA_MIMETYPE_VIDEO_AV1, MEDIA_MIMETYPE_VIDEO_AVC,
35 MEDIA_MIMETYPE_VIDEO_HEVC, MEDIA_MIMETYPE_VIDEO_MPEG4,
36 MEDIA_MIMETYPE_VIDEO_H263, MEDIA_MIMETYPE_VIDEO_MPEG2,
37 MEDIA_MIMETYPE_VIDEO_RAW, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION,
38 MEDIA_MIMETYPE_VIDEO_SCRAMBLED, MEDIA_MIMETYPE_VIDEO_DIVX,
39 MEDIA_MIMETYPE_VIDEO_DIVX3, MEDIA_MIMETYPE_VIDEO_XVID,
40 MEDIA_MIMETYPE_VIDEO_MJPEG, MEDIA_MIMETYPE_AUDIO_AMR_NB,
41 MEDIA_MIMETYPE_AUDIO_AMR_WB, MEDIA_MIMETYPE_AUDIO_MPEG,
42 MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
43 MEDIA_MIMETYPE_AUDIO_MIDI, MEDIA_MIMETYPE_AUDIO_AAC,
44 MEDIA_MIMETYPE_AUDIO_QCELP, MEDIA_MIMETYPE_AUDIO_VORBIS,
45 MEDIA_MIMETYPE_AUDIO_OPUS, MEDIA_MIMETYPE_AUDIO_G711_ALAW,
46 MEDIA_MIMETYPE_AUDIO_G711_MLAW, MEDIA_MIMETYPE_AUDIO_RAW,
47 MEDIA_MIMETYPE_AUDIO_FLAC, MEDIA_MIMETYPE_AUDIO_AAC_ADTS,
48 MEDIA_MIMETYPE_AUDIO_MSGSM, MEDIA_MIMETYPE_AUDIO_AC3,
49 MEDIA_MIMETYPE_AUDIO_EAC3, MEDIA_MIMETYPE_AUDIO_EAC3_JOC,
50 MEDIA_MIMETYPE_AUDIO_AC4, MEDIA_MIMETYPE_AUDIO_SCRAMBLED,
51 MEDIA_MIMETYPE_AUDIO_ALAC, MEDIA_MIMETYPE_AUDIO_WMA,
52 MEDIA_MIMETYPE_AUDIO_MS_ADPCM, MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM,
53 MEDIA_MIMETYPE_CONTAINER_MPEG4, MEDIA_MIMETYPE_CONTAINER_WAV,
54 MEDIA_MIMETYPE_CONTAINER_OGG, MEDIA_MIMETYPE_CONTAINER_MATROSKA,
55 MEDIA_MIMETYPE_CONTAINER_MPEG2TS, MEDIA_MIMETYPE_CONTAINER_AVI,
56 MEDIA_MIMETYPE_CONTAINER_MPEG2PS, MEDIA_MIMETYPE_CONTAINER_HEIF,
57 MEDIA_MIMETYPE_TEXT_3GPP, MEDIA_MIMETYPE_TEXT_SUBRIP,
58 MEDIA_MIMETYPE_TEXT_VTT, MEDIA_MIMETYPE_TEXT_CEA_608,
59 MEDIA_MIMETYPE_TEXT_CEA_708, MEDIA_MIMETYPE_DATA_TIMED_ID3,
60 MEDIA_MIMETYPE_IMAGE_AVIF, MEDIA_MIMETYPE_AUDIO_MPEGH_MHA1,
61 MEDIA_MIMETYPE_AUDIO_MPEGH_MHM1, MEDIA_MIMETYPE_AUDIO_MPEGH_BL_L3,
62 MEDIA_MIMETYPE_AUDIO_MPEGH_BL_L4, MEDIA_MIMETYPE_AUDIO_MPEGH_LC_L3,
63 MEDIA_MIMETYPE_AUDIO_MPEGH_LC_L4, MEDIA_MIMETYPE_AUDIO_DTS,
64 MEDIA_MIMETYPE_AUDIO_DTS_HD, MEDIA_MIMETYPE_AUDIO_DTS_HD_MA,
65 MEDIA_MIMETYPE_AUDIO_DTS_UHD, MEDIA_MIMETYPE_AUDIO_DTS_UHD_P1,
66 MEDIA_MIMETYPE_AUDIO_DTS_UHD_P2, MEDIA_MIMETYPE_AUDIO_EVRC,
67 MEDIA_MIMETYPE_AUDIO_EVRCB, MEDIA_MIMETYPE_AUDIO_EVRCWB,
68 MEDIA_MIMETYPE_AUDIO_EVRCNW, MEDIA_MIMETYPE_AUDIO_AMR_WB_PLUS,
69 MEDIA_MIMETYPE_AUDIO_APTX, MEDIA_MIMETYPE_AUDIO_DRA,
70 MEDIA_MIMETYPE_AUDIO_DOLBY_MAT, MEDIA_MIMETYPE_AUDIO_DOLBY_TRUEHD,
71 MEDIA_MIMETYPE_AUDIO_DOLBY_MAT_1_0,MEDIA_MIMETYPE_AUDIO_AAC_MP4,
72 MEDIA_MIMETYPE_AUDIO_DOLBY_MAT_2_0,MEDIA_MIMETYPE_AUDIO_DOLBY_MAT_2_1,
73 MEDIA_MIMETYPE_AUDIO_AAC_MAIN, MEDIA_MIMETYPE_AUDIO_AAC_LC,
74 MEDIA_MIMETYPE_AUDIO_AAC_SSR, MEDIA_MIMETYPE_AUDIO_AAC_LTP,
75 MEDIA_MIMETYPE_AUDIO_AAC_HE_V1, MEDIA_MIMETYPE_AUDIO_AAC_SCALABLE,
76 MEDIA_MIMETYPE_AUDIO_AAC_ERLC, MEDIA_MIMETYPE_AUDIO_AAC_ADTS_MAIN,
77 MEDIA_MIMETYPE_AUDIO_AAC_HE_V2, MEDIA_MIMETYPE_AUDIO_AAC_ADTS_HE_V1,
78 MEDIA_MIMETYPE_AUDIO_AAC_XHE, MEDIA_MIMETYPE_AUDIO_AAC_ADTS_HE_V2,
79 MEDIA_MIMETYPE_AUDIO_AAC_LD, MEDIA_MIMETYPE_AUDIO_AAC_ADTS_LC,
80 MEDIA_MIMETYPE_AUDIO_AAC_ADTS_SSR, MEDIA_MIMETYPE_AUDIO_AAC_ADTS_LTP,
81 MEDIA_MIMETYPE_AUDIO_AAC_ADIF, MEDIA_MIMETYPE_AUDIO_IEC60958,
82 MEDIA_MIMETYPE_AUDIO_AAC_ADTS_ERLC,MEDIA_MIMETYPE_AUDIO_AAC_ADTS_LD,
83 MEDIA_MIMETYPE_AUDIO_AAC_ELD, MEDIA_MIMETYPE_AUDIO_AAC_LATM_HE_V1,
84 MEDIA_MIMETYPE_AUDIO_AAC_ADTS_XHE, MEDIA_MIMETYPE_AUDIO_AAC_LATM_LC,
85 MEDIA_MIMETYPE_AUDIO_AAC_ADTS_ELD, MEDIA_MIMETYPE_AUDIO_AAC_LATM_HE_V2,
86 MEDIA_MIMETYPE_AUDIO_IEC61937,
87 MEDIA_MIMETYPE_AUDIO_AAC_ADTS_SCALABLE,};
88
89 constexpr size_t kMaxSize = 100;
90
91 class MetadataRetrieverFuzzer {
92 public:
MetadataRetrieverFuzzer(const uint8_t * data,size_t size)93 MetadataRetrieverFuzzer(const uint8_t *data, size_t size)
94 : mFdp(data, size), mMdRetriever(new StagefrightMetadataRetriever()) {}
95 bool setDataSource(const uint8_t *data, size_t size);
96 void getData();
97
98 private:
99 FuzzedDataProvider mFdp;
100 sp<StagefrightMetadataRetriever> mMdRetriever = nullptr;
101 int32_t mDataSourceFd;
102 };
103
getData()104 void MetadataRetrieverFuzzer::getData() {
105 while (mFdp.remaining_bytes()) {
106 auto invokeMediaApi = mFdp.PickValueInArray<const std::function<void()>>({
107 [&]() {
108 mMdRetriever->getFrameAtTime(mFdp.ConsumeIntegral<int64_t>() /* timeUs */,
109 mFdp.ConsumeIntegral<int32_t>() /* option */,
110 mFdp.ConsumeIntegral<int32_t>() /* colorFormat */,
111 mFdp.ConsumeBool() /* metaOnly */);
112 },
113 [&]() {
114 mMdRetriever->getImageAtIndex(mFdp.ConsumeIntegral<int32_t>() /* index */,
115 mFdp.ConsumeIntegral<int32_t>() /* colorFormat */,
116 mFdp.ConsumeBool() /* metaOnly */,
117 mFdp.ConsumeBool() /* thumbnail */);
118 },
119 [&]() {
120 mMdRetriever->getImageRectAtIndex(
121 mFdp.ConsumeIntegral<int32_t>() /* index */,
122 mFdp.ConsumeIntegral<int32_t>() /* colorFormat */,
123 mFdp.ConsumeIntegral<int32_t>() /* left */,
124 mFdp.ConsumeIntegral<int32_t>() /* top */,
125 mFdp.ConsumeIntegral<int32_t>() /* right */,
126 mFdp.ConsumeIntegral<int32_t>() /* bottom */);
127 },
128 [&]() {
129 mMdRetriever->getFrameAtIndex(mFdp.ConsumeIntegral<int32_t>() /* index */,
130 mFdp.ConsumeIntegral<int32_t>() /* colorFormat */,
131 mFdp.ConsumeBool() /* metaOnly */);
132 },
133 [&]() { mMdRetriever->extractAlbumArt(); },
134 [&]() {
135 mMdRetriever->extractMetadata(mFdp.ConsumeIntegral<int32_t>() /* keyCode */);
136 },
137 });
138 invokeMediaApi();
139 }
140 }
141
setDataSource(const uint8_t * data,size_t size)142 bool MetadataRetrieverFuzzer::setDataSource(const uint8_t *data, size_t size) {
143 status_t status = -1;
144 std::unique_ptr<std::FILE, decltype(&fclose)> fp(tmpfile(), &fclose);
145 mDataSourceFd = fileno(fp.get());
146 if (mDataSourceFd < 0) {
147 return false;
148 }
149
150 enum DataSourceChoice {FromHttp, FromFd, FromFileSource, kMaxValue = FromFileSource};
151 switch (mFdp.ConsumeEnum<DataSourceChoice>()) {
152 case FromHttp: {
153 KeyedVector<String8, String8> mHeaders;
154 mHeaders.add(String8(mFdp.ConsumeRandomLengthString().c_str()),
155 String8(mFdp.ConsumeRandomLengthString().c_str()));
156
157 uint32_t dataBlobSize = mFdp.ConsumeIntegralInRange<uint16_t>(0, min(kMaxSize,size));
158 vector<uint8_t> uriSuffix = mFdp.ConsumeBytes<uint8_t>(dataBlobSize);
159
160 string uri("data:");
161 uri += ";base64,";
162 AString out;
163 encodeBase64(uriSuffix.data(), uriSuffix.size(), &out);
164 uri += out.c_str();
165 status = mMdRetriever->setDataSource(nullptr /*httpService*/, uri.c_str(), &mHeaders);
166 break;
167 }
168 case FromFd: {
169 write(mDataSourceFd, data, size);
170
171 status = mMdRetriever->setDataSource(mDataSourceFd, 0, size);
172 break;
173 }
174 case FromFileSource: {
175 write(mDataSourceFd, data, size);
176
177 sp<DataSource> dataSource = new FileSource(dup(mDataSourceFd), 0, size);
178 status = mMdRetriever->setDataSource(dataSource, mFdp.PickValueInArray(kMimeTypes));
179 break;
180 }
181 }
182
183 if (status != 0) {
184 return false;
185 }
186 return true;
187 }
188
LLVMFuzzerInitialize(int *,char ***)189 extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
190 MediaPlayerService::instantiate();
191 MediaExtractorService::instantiate();
192 return 0;
193 }
194
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)195 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
196 MetadataRetrieverFuzzer mrtFuzzer(data, size);
197 ProcessState::self()->startThreadPool();
198 if (mrtFuzzer.setDataSource(data, size)) {
199 mrtFuzzer.getData();
200 }
201 return 0;
202 }
203