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