• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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