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 <MediaPlayerService.h>
19 #include <camera/Camera.h>
20 #include <datasource/FileSource.h>
21 #include <gui/Surface.h>
22 #include <gui/SurfaceComposerClient.h>
23 #include <media/IMediaCodecList.h>
24 #include <media/IMediaHTTPService.h>
25 #include <media/IMediaPlayer.h>
26 #include <media/IMediaRecorder.h>
27 #include <media/IRemoteDisplay.h>
28 #include <media/IRemoteDisplayClient.h>
29 #include <media/MediaHTTPConnection.h>
30 #include <media/MediaHTTPService.h>
31 #include <media/stagefright/RemoteDataSource.h>
32 #include <media/stagefright/foundation/base64.h>
33 #include <thread>
34 #include "fuzzer/FuzzedDataProvider.h"
35
36 constexpr int32_t kUuidSize = 16;
37 constexpr int32_t kMaxSleepTimeInMs = 100;
38 constexpr int32_t kMinSleepTimeInMs = 0;
39 constexpr int32_t kPlayCountMin = 1;
40 constexpr int32_t kPlayCountMax = 10;
41 constexpr int32_t kMaxDimension = 8192;
42 constexpr int32_t kMinDimension = 0;
43
44 using namespace std;
45 using namespace android;
46
47 constexpr audio_session_t kSupportedAudioSessions[] = {
48 AUDIO_SESSION_DEVICE, AUDIO_SESSION_OUTPUT_STAGE, AUDIO_SESSION_OUTPUT_MIX};
49
50 constexpr audio_timestretch_stretch_mode_t kAudioStretchModes[] = {
51 AUDIO_TIMESTRETCH_STRETCH_DEFAULT, AUDIO_TIMESTRETCH_STRETCH_VOICE};
52
53 constexpr audio_timestretch_fallback_mode_t kAudioFallbackModes[] = {
54 AUDIO_TIMESTRETCH_FALLBACK_CUT_REPEAT, AUDIO_TIMESTRETCH_FALLBACK_DEFAULT,
55 AUDIO_TIMESTRETCH_FALLBACK_MUTE, AUDIO_TIMESTRETCH_FALLBACK_FAIL};
56
57 constexpr media_parameter_keys kMediaParamKeys[] = {
58 KEY_PARAMETER_CACHE_STAT_COLLECT_FREQ_MS, KEY_PARAMETER_AUDIO_CHANNEL_COUNT,
59 KEY_PARAMETER_PLAYBACK_RATE_PERMILLE, KEY_PARAMETER_AUDIO_ATTRIBUTES,
60 KEY_PARAMETER_RTP_ATTRIBUTES};
61
62 constexpr audio_stream_type_t kAudioStreamTypes[] = {
63 AUDIO_STREAM_DEFAULT, AUDIO_STREAM_VOICE_CALL, AUDIO_STREAM_SYSTEM,
64 AUDIO_STREAM_RING, AUDIO_STREAM_MUSIC, AUDIO_STREAM_ALARM,
65 AUDIO_STREAM_NOTIFICATION, AUDIO_STREAM_BLUETOOTH_SCO, AUDIO_STREAM_ENFORCED_AUDIBLE,
66 AUDIO_STREAM_DTMF, AUDIO_STREAM_TTS, AUDIO_STREAM_ASSISTANT};
67
68 constexpr media_event_type kMediaEventTypes[] = {MEDIA_NOP,
69 MEDIA_PREPARED,
70 MEDIA_PLAYBACK_COMPLETE,
71 MEDIA_BUFFERING_UPDATE,
72 MEDIA_SEEK_COMPLETE,
73 MEDIA_SET_VIDEO_SIZE,
74 MEDIA_STARTED,
75 MEDIA_PAUSED,
76 MEDIA_STOPPED,
77 MEDIA_SKIPPED,
78 MEDIA_NOTIFY_TIME,
79 MEDIA_TIMED_TEXT,
80 MEDIA_ERROR,
81 MEDIA_INFO,
82 MEDIA_SUBTITLE_DATA,
83 MEDIA_META_DATA,
84 MEDIA_DRM_INFO,
85 MEDIA_TIME_DISCONTINUITY,
86 MEDIA_IMS_RX_NOTICE,
87 MEDIA_AUDIO_ROUTING_CHANGED};
88
89 constexpr media_info_type kMediaInfoTypes[] = {
90 MEDIA_INFO_UNKNOWN, MEDIA_INFO_STARTED_AS_NEXT,
91 MEDIA_INFO_RENDERING_START, MEDIA_INFO_VIDEO_TRACK_LAGGING,
92 MEDIA_INFO_BUFFERING_START, MEDIA_INFO_BUFFERING_END,
93 MEDIA_INFO_NETWORK_BANDWIDTH, MEDIA_INFO_BAD_INTERLEAVING,
94 MEDIA_INFO_NOT_SEEKABLE, MEDIA_INFO_METADATA_UPDATE,
95 MEDIA_INFO_PLAY_AUDIO_ERROR, MEDIA_INFO_PLAY_VIDEO_ERROR,
96 MEDIA_INFO_TIMED_TEXT_ERROR};
97
98 const char *kUrlPrefix[] = {"data:", "http://", "https://", "rtsp://", "content://", "test://"};
99
100 struct TestStreamSource : public IStreamSource {
setListenerTestStreamSource101 void setListener(const sp<IStreamListener> & /*listener*/) override{};
setBuffersTestStreamSource102 void setBuffers(const Vector<sp<IMemory>> & /*buffers*/) override{};
onBufferAvailableTestStreamSource103 void onBufferAvailable(size_t /*index*/) override{};
onAsBinderTestStreamSource104 IBinder *onAsBinder() { return nullptr; };
105 };
106
107 struct TestMediaHTTPConnection : public MediaHTTPConnection {
108 public:
TestMediaHTTPConnectionTestMediaHTTPConnection109 TestMediaHTTPConnection() {}
~TestMediaHTTPConnectionTestMediaHTTPConnection110 virtual ~TestMediaHTTPConnection() {}
111
connectTestMediaHTTPConnection112 virtual bool connect(const char* /*uri*/, const KeyedVector<String8, String8>* /*headers*/) {
113 return true;
114 }
115
disconnectTestMediaHTTPConnection116 virtual void disconnect() { return; }
117
readAtTestMediaHTTPConnection118 virtual ssize_t readAt(off64_t /*offset*/, void* /*data*/, size_t size) { return size; }
119
getSizeTestMediaHTTPConnection120 virtual off64_t getSize() { return 0; }
getMIMETypeTestMediaHTTPConnection121 virtual status_t getMIMEType(String8* /*mimeType*/) { return NO_ERROR; }
getUriTestMediaHTTPConnection122 virtual status_t getUri(String8* /*uri*/) { return NO_ERROR; }
123
124 private:
125 DISALLOW_EVIL_CONSTRUCTORS(TestMediaHTTPConnection);
126 };
127
128 struct TestMediaHTTPService : public BnInterface<IMediaHTTPService> {
129 public:
TestMediaHTTPServiceTestMediaHTTPService130 TestMediaHTTPService() {}
~TestMediaHTTPServiceTestMediaHTTPService131 ~TestMediaHTTPService(){};
132
makeHTTPConnectionTestMediaHTTPService133 virtual sp<MediaHTTPConnection> makeHTTPConnection() {
134 mMediaHTTPConnection = sp<TestMediaHTTPConnection>::make();
135 return mMediaHTTPConnection;
136 }
137
138 private:
139 sp<TestMediaHTTPConnection> mMediaHTTPConnection = nullptr;
140 DISALLOW_EVIL_CONSTRUCTORS(TestMediaHTTPService);
141 };
142
143 class BinderDeathNotifier : public IBinder::DeathRecipient {
144 public:
binderDied(const wp<IBinder> &)145 void binderDied(const wp<IBinder> &) { abort(); }
146 };
147
148 class MediaPlayerServiceFuzzer {
149 public:
MediaPlayerServiceFuzzer(const uint8_t * data,size_t size)150 MediaPlayerServiceFuzzer(const uint8_t *data, size_t size)
151 : mFdp(data, size), mDataSourceFd(memfd_create("InputFile", MFD_ALLOW_SEALING)){};
~MediaPlayerServiceFuzzer()152 ~MediaPlayerServiceFuzzer() { close(mDataSourceFd); };
153 void process(const uint8_t *data, size_t size);
154
155 private:
156 bool setDataSource(const uint8_t *data, size_t size);
157 void invokeMediaPlayer();
158 FuzzedDataProvider mFdp;
159 sp<IMediaPlayer> mMediaPlayer = nullptr;
160 sp<IMediaPlayerClient> mMediaPlayerClient = nullptr;
161 const int32_t mDataSourceFd;
162 };
163
setDataSource(const uint8_t * data,size_t size)164 bool MediaPlayerServiceFuzzer::setDataSource(const uint8_t *data, size_t size) {
165 status_t status = -1;
166 enum DataSourceType {http, fd, stream, file, socket, kMaxValue = socket};
167 switch (mFdp.ConsumeEnum<DataSourceType>()) {
168 case http: {
169 KeyedVector<String8, String8> headers;
170 headers.add(String8(mFdp.ConsumeRandomLengthString().c_str()),
171 String8(mFdp.ConsumeRandomLengthString().c_str()));
172
173 uint32_t dataBlobSize = mFdp.ConsumeIntegralInRange<uint16_t>(0, size);
174 vector<uint8_t> uriSuffix = mFdp.ConsumeBytes<uint8_t>(dataBlobSize);
175
176 string uri(mFdp.PickValueInArray(kUrlPrefix));
177 uri += ";base64,";
178 AString out;
179 encodeBase64(uriSuffix.data(), uriSuffix.size(), &out);
180 uri += out.c_str();
181 sp<TestMediaHTTPService> testService = sp<TestMediaHTTPService>::make();
182 status =
183 mMediaPlayer->setDataSource(testService /*httpService*/, uri.c_str(), &headers);
184 break;
185 }
186 case fd: {
187 write(mDataSourceFd, data, size);
188
189 status = mMediaPlayer->setDataSource(mDataSourceFd, 0, size);
190 break;
191 }
192 case stream: {
193 sp<IStreamSource> streamSource = sp<TestStreamSource>::make();
194 status = mMediaPlayer->setDataSource(streamSource);
195 break;
196 }
197 case file: {
198 write(mDataSourceFd, data, size);
199
200 sp<DataSource> dataSource = new FileSource(dup(mDataSourceFd), 0, size);
201 sp<IDataSource> iDataSource = RemoteDataSource::wrap(dataSource);
202 if (!iDataSource) {
203 return false;
204 }
205 status = mMediaPlayer->setDataSource(iDataSource);
206 break;
207 }
208 case socket: {
209 String8 rtpParams = String8(mFdp.ConsumeRandomLengthString().c_str());
210 struct sockaddr_in endpoint;
211 endpoint.sin_family = mFdp.ConsumeIntegral<unsigned short>();
212 endpoint.sin_port = mFdp.ConsumeIntegral<uint16_t>();
213 mMediaPlayer->setRetransmitEndpoint(&endpoint);
214 status = mMediaPlayer->setDataSource(rtpParams);
215 break;
216 }
217 }
218
219 if (status != 0) {
220 return false;
221 }
222 return true;
223 }
224
invokeMediaPlayer()225 void MediaPlayerServiceFuzzer::invokeMediaPlayer() {
226 sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
227 String8 name = String8(mFdp.ConsumeRandomLengthString().c_str());
228 uint32_t width = mFdp.ConsumeIntegralInRange<uint32_t>(kMinDimension, kMaxDimension);
229 uint32_t height = mFdp.ConsumeIntegralInRange<uint32_t>(kMinDimension, kMaxDimension);
230 uint32_t pixelFormat = mFdp.ConsumeIntegral<int32_t>();
231 uint32_t flags = mFdp.ConsumeIntegral<int32_t>();
232 sp<SurfaceControl> surfaceControl =
233 composerClient->createSurface(name, width, height, pixelFormat, flags);
234 if (surfaceControl) {
235 sp<Surface> surface = surfaceControl->getSurface();
236 mMediaPlayer->setVideoSurfaceTexture(surface->getIGraphicBufferProducer());
237 }
238
239 BufferingSettings buffering;
240 buffering.mInitialMarkMs = mFdp.ConsumeIntegral<int32_t>();
241 buffering.mResumePlaybackMarkMs = mFdp.ConsumeIntegral<int32_t>();
242 mMediaPlayer->setBufferingSettings(buffering);
243 mMediaPlayer->getBufferingSettings(&buffering);
244
245 mMediaPlayer->prepareAsync();
246 size_t playCount = mFdp.ConsumeIntegralInRange<size_t>(kPlayCountMin, kPlayCountMax);
247 for (size_t Idx = 0; Idx < playCount; ++Idx) {
248 mMediaPlayer->start();
249 this_thread::sleep_for(chrono::milliseconds(
250 mFdp.ConsumeIntegralInRange<int32_t>(kMinSleepTimeInMs, kMaxSleepTimeInMs)));
251 mMediaPlayer->pause();
252 this_thread::sleep_for(chrono::milliseconds(
253 mFdp.ConsumeIntegralInRange<int32_t>(kMinSleepTimeInMs, kMaxSleepTimeInMs)));
254 mMediaPlayer->stop();
255 }
256 bool state;
257 mMediaPlayer->isPlaying(&state);
258
259 AudioPlaybackRate rate;
260 rate.mSpeed = mFdp.ConsumeFloatingPoint<float>();
261 rate.mPitch = mFdp.ConsumeFloatingPoint<float>();
262 rate.mStretchMode = mFdp.PickValueInArray(kAudioStretchModes);
263 rate.mFallbackMode = mFdp.PickValueInArray(kAudioFallbackModes);
264 mMediaPlayer->setPlaybackSettings(rate);
265 mMediaPlayer->getPlaybackSettings(&rate);
266
267 AVSyncSettings *avSyncSettings = new AVSyncSettings();
268 float videoFpsHint = mFdp.ConsumeFloatingPoint<float>();
269 mMediaPlayer->setSyncSettings(*avSyncSettings, videoFpsHint);
270 mMediaPlayer->getSyncSettings(avSyncSettings, &videoFpsHint);
271 delete avSyncSettings;
272
273 mMediaPlayer->seekTo(mFdp.ConsumeIntegral<int32_t>());
274
275 int32_t msec;
276 mMediaPlayer->getCurrentPosition(&msec);
277 mMediaPlayer->getDuration(&msec);
278 mMediaPlayer->reset();
279
280 mMediaPlayer->notifyAt(mFdp.ConsumeIntegral<int64_t>());
281
282 mMediaPlayer->setAudioStreamType(mFdp.PickValueInArray(kAudioStreamTypes));
283 mMediaPlayer->setLooping(mFdp.ConsumeIntegral<int32_t>());
284 float left = mFdp.ConsumeFloatingPoint<float>();
285 float right = mFdp.ConsumeFloatingPoint<float>();
286 mMediaPlayer->setVolume(left, right);
287
288 Parcel request, reply;
289 request.writeInt32(mFdp.ConsumeIntegral<int32_t>());
290 request.setDataPosition(0);
291 mMediaPlayer->invoke(request, &reply);
292
293 Parcel filter;
294 filter.writeInt32(mFdp.ConsumeIntegral<int32_t>());
295 filter.setDataPosition(0);
296 mMediaPlayer->setMetadataFilter(filter);
297
298 bool updateOnly = mFdp.ConsumeBool();
299 bool applyFilter = mFdp.ConsumeBool();
300 mMediaPlayer->getMetadata(updateOnly, applyFilter, &reply);
301 mMediaPlayer->setAuxEffectSendLevel(mFdp.ConsumeFloatingPoint<float>());
302 mMediaPlayer->attachAuxEffect(mFdp.ConsumeIntegral<int32_t>());
303
304 int32_t key = mFdp.PickValueInArray(kMediaParamKeys);
305 request.writeInt32(mFdp.ConsumeIntegral<int32_t>());
306 request.setDataPosition(0);
307 mMediaPlayer->setParameter(key, request);
308 key = mFdp.PickValueInArray(kMediaParamKeys);
309 mMediaPlayer->getParameter(key, &reply);
310
311 struct sockaddr_in endpoint;
312 mMediaPlayer->getRetransmitEndpoint(&endpoint);
313
314 AttributionSourceState attributionSource;
315 attributionSource.packageName = mFdp.ConsumeRandomLengthString().c_str();
316 attributionSource.token = sp<BBinder>::make();
317 const sp<IMediaPlayerService> mpService(IMediaDeathNotifier::getMediaPlayerService());
318 sp<IMediaPlayer> mNextMediaPlayer = mpService->create(
319 mMediaPlayerClient, mFdp.PickValueInArray(kSupportedAudioSessions), attributionSource);
320 mMediaPlayer->setNextPlayer(mNextMediaPlayer);
321
322 const sp<media::VolumeShaper::Configuration> configuration =
323 sp<media::VolumeShaper::Configuration>::make();
324 const sp<media::VolumeShaper::Operation> operation = sp<media::VolumeShaper::Operation>::make();
325 mMediaPlayer->applyVolumeShaper(configuration, operation);
326
327 mMediaPlayer->getVolumeShaperState(mFdp.ConsumeIntegral<int32_t>());
328 uint8_t uuid[kUuidSize];
329 for (int32_t index = 0; index < kUuidSize; ++index) {
330 uuid[index] = mFdp.ConsumeIntegral<uint8_t>();
331 }
332 Vector<uint8_t> drmSessionId;
333 drmSessionId.push_back(mFdp.ConsumeIntegral<uint8_t>());
334 mMediaPlayer->prepareDrm(uuid, drmSessionId);
335 mMediaPlayer->releaseDrm();
336
337 audio_port_handle_t deviceId = mFdp.ConsumeIntegral<int32_t>();
338 mMediaPlayer->setOutputDevice(deviceId);
339 mMediaPlayer->getRoutedDeviceId(&deviceId);
340
341 mMediaPlayer->enableAudioDeviceCallback(mFdp.ConsumeBool());
342
343 sp<MediaPlayer> mediaPlayer = (MediaPlayer *)mMediaPlayer.get();
344
345 int32_t msg = mFdp.PickValueInArray(kMediaEventTypes);
346 int32_t ext1 = mFdp.PickValueInArray(kMediaInfoTypes);
347 int32_t ext2 = mFdp.ConsumeIntegral<int32_t>();
348 Parcel obj;
349 obj.writeInt32(mFdp.ConsumeIntegral<int32_t>());
350 obj.setDataPosition(0);
351 mediaPlayer->notify(msg, ext1, ext2, &obj);
352
353 int32_t mediaPlayerDumpFd = memfd_create("OutputDumpFile", MFD_ALLOW_SEALING);
354 Vector<String16> args;
355 args.push_back(String16(mFdp.ConsumeRandomLengthString().c_str()));
356 mediaPlayer->dump(mediaPlayerDumpFd, args);
357 close(mediaPlayerDumpFd);
358
359 mMediaPlayer->disconnect();
360 }
361
process(const uint8_t * data,size_t size)362 void MediaPlayerServiceFuzzer::process(const uint8_t *data, size_t size) {
363 MediaPlayerService::instantiate();
364
365 const sp<IMediaPlayerService> mpService(IMediaDeathNotifier::getMediaPlayerService());
366 if (!mpService) {
367 return;
368 }
369
370 sp<IMediaCodecList> mediaCodecList = mpService->getCodecList();
371
372 sp<IRemoteDisplayClient> remoteDisplayClient;
373 sp<IRemoteDisplay> remoteDisplay = mpService->listenForRemoteDisplay(
374 String16(mFdp.ConsumeRandomLengthString().c_str()) /*opPackageName*/, remoteDisplayClient,
375 String8(mFdp.ConsumeRandomLengthString().c_str()) /*iface*/);
376
377 mpService->addBatteryData(mFdp.ConsumeIntegral<uint32_t>());
378 Parcel reply;
379 mpService->pullBatteryData(&reply);
380
381 sp<MediaPlayerService> mediaPlayerService = (MediaPlayerService *)mpService.get();
382 AttributionSourceState attributionSource;
383 attributionSource.packageName = mFdp.ConsumeRandomLengthString().c_str();
384 attributionSource.token = sp<BBinder>::make();
385 mMediaPlayer = mediaPlayerService->create(
386 mMediaPlayerClient, mFdp.PickValueInArray(kSupportedAudioSessions), attributionSource);
387
388 int32_t mediaPlayerServiceDumpFd = memfd_create("OutputDumpFile", MFD_ALLOW_SEALING);
389 Vector<String16> args;
390 args.push_back(String16(mFdp.ConsumeRandomLengthString().c_str()));
391 mediaPlayerService->dump(mediaPlayerServiceDumpFd, args);
392 close(mediaPlayerServiceDumpFd);
393
394 if (!mMediaPlayer) {
395 return;
396 }
397
398 if (setDataSource(data, size)) {
399 invokeMediaPlayer();
400 }
401 }
402
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)403 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
404 MediaPlayerServiceFuzzer mpsFuzzer(data, size);
405 ProcessState::self()->startThreadPool();
406 mpsFuzzer.process(data, size);
407 return 0;
408 };
409