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 <AudioFlinger.h>
19 #include <MediaPlayerService.h>
20 #include <ResourceManagerService.h>
21 #include <StagefrightRecorder.h>
22 #include <camera/Camera.h>
23 #include <camera/android/hardware/ICamera.h>
24 #include <fakeservicemanager/FakeServiceManager.h>
25 #include <gui/IGraphicBufferProducer.h>
26 #include <gui/Surface.h>
27 #include <gui/SurfaceComposerClient.h>
28 #include <media/stagefright/PersistentSurface.h>
29 #include <media/stagefright/foundation/AString.h>
30 #include <mediametricsservice/MediaMetricsService.h>
31 #include <thread>
32 #include "CameraService.h"
33 #include "fuzzer/FuzzedDataProvider.h"
34 
35 using namespace std;
36 using namespace android;
37 using namespace android::hardware;
38 
39 constexpr video_source kSupportedVideoSources[] = {VIDEO_SOURCE_DEFAULT, VIDEO_SOURCE_CAMERA,
40                                                    VIDEO_SOURCE_SURFACE};
41 
42 constexpr audio_source_t kSupportedAudioSources[] = {
43     AUDIO_SOURCE_DEFAULT,           AUDIO_SOURCE_MIC,
44     AUDIO_SOURCE_VOICE_UPLINK,      AUDIO_SOURCE_VOICE_DOWNLINK,
45     AUDIO_SOURCE_VOICE_CALL,        AUDIO_SOURCE_CAMCORDER,
46     AUDIO_SOURCE_VOICE_RECOGNITION, AUDIO_SOURCE_VOICE_COMMUNICATION,
47     AUDIO_SOURCE_REMOTE_SUBMIX,     AUDIO_SOURCE_UNPROCESSED,
48     AUDIO_SOURCE_VOICE_PERFORMANCE, AUDIO_SOURCE_ECHO_REFERENCE,
49     AUDIO_SOURCE_FM_TUNER,          AUDIO_SOURCE_HOTWORD,
50     AUDIO_SOURCE_ULTRASOUND};
51 
52 constexpr output_format kOutputFormat[] = {
53         OUTPUT_FORMAT_DEFAULT,        OUTPUT_FORMAT_THREE_GPP,
54         OUTPUT_FORMAT_MPEG_4,         OUTPUT_FORMAT_AUDIO_ONLY_START,
55         OUTPUT_FORMAT_RAW_AMR,        OUTPUT_FORMAT_AMR_NB,
56         OUTPUT_FORMAT_AMR_WB,         OUTPUT_FORMAT_AAC_ADTS,
57         OUTPUT_FORMAT_AUDIO_ONLY_END, OUTPUT_FORMAT_RTP_AVP,
58         OUTPUT_FORMAT_MPEG2TS,        OUTPUT_FORMAT_WEBM,
59         OUTPUT_FORMAT_HEIF,           OUTPUT_FORMAT_OGG,
60         OUTPUT_FORMAT_LIST_END};
61 
62 constexpr video_encoder kVideoEncoder[] = {
63         VIDEO_ENCODER_DEFAULT,      VIDEO_ENCODER_H263, VIDEO_ENCODER_H264,
64         VIDEO_ENCODER_MPEG_4_SP,    VIDEO_ENCODER_VP8,  VIDEO_ENCODER_HEVC,
65         VIDEO_ENCODER_DOLBY_VISION, VIDEO_ENCODER_AV1,  VIDEO_ENCODER_LIST_END};
66 
67 constexpr audio_microphone_direction_t kSupportedMicrophoneDirections[] = {
68     MIC_DIRECTION_UNSPECIFIED, MIC_DIRECTION_FRONT, MIC_DIRECTION_BACK, MIC_DIRECTION_EXTERNAL};
69 
70 const string kParametersList[] = {"max-duration",
71                                   "max-filesize",
72                                   "interleave-duration-us",
73                                   "param-movie-time-scale",
74                                   "param-geotag-longitude",
75                                   "param-geotag-latitude",
76                                   "param-track-time-status",
77                                   "audio-param-sampling-rate",
78                                   "audio-param-encoding-bitrate",
79                                   "audio-param-number-of-channels",
80                                   "audio-param-time-scale",
81                                   "video-param-rotation-angle-degrees",
82                                   "video-param-encoding-bitrate",
83                                   "video-param-bitrate-mode",
84                                   "video-param-i-frames-interval",
85                                   "video-param-encoder-profile",
86                                   "video-param-encoder-level",
87                                   "video-param-camera-id",
88                                   "video-param-time-scale",
89                                   "param-use-64bit-offset",
90                                   "time-lapse-enable",
91                                   "time-lapse-fps",
92                                   "rtp-param-local-ip",
93                                   "rtp-param-local-port",
94                                   "rtp-param-remote-port",
95                                   "rtp-param-self-id",
96                                   "rtp-param-opponent-id",
97                                   "rtp-param-payload-type",
98                                   "rtp-param-ext-cvo-extmap",
99                                   "rtp-param-ext-cvo-degrees",
100                                   "video-param-request-i-frame",
101                                   "rtp-param-set-socket-dscp",
102                                   "rtp-param-set-socket-network",
103                                   "rtp-param-set-socket-ecn",
104                                   "rtp-param-remote-ip",
105                                   "rtp-param-set-socket-network",
106                                   "log-session-id"};
107 
108 constexpr int32_t kMinVideoSize = 2;
109 constexpr int32_t kMaxVideoSize = 8192;
110 const char kOutputFile[] = "OutputFile";
111 const char kNextOutputFile[] = "NextOutputFile";
112 
113 class TestAudioDeviceCallback : public AudioSystem::AudioDeviceCallback {
114    public:
115     virtual ~TestAudioDeviceCallback() = default;
116 
onAudioDeviceUpdate(audio_io_handle_t,audio_port_handle_t)117     void onAudioDeviceUpdate(audio_io_handle_t /*audioIo*/,
118                              audio_port_handle_t /*deviceId*/) override{};
119 };
120 
121 class TestCamera : public ICamera {
122    public:
123     virtual ~TestCamera() = default;
124 
disconnect()125     binder::Status disconnect() override { return binder::Status::ok(); };
connect(const sp<ICameraClient> &)126     status_t connect(const sp<ICameraClient> & /*client*/) override { return 0; };
lock()127     status_t lock() override { return 0; };
unlock()128     status_t unlock() override { return 0; };
setPreviewTarget(const sp<IGraphicBufferProducer> &)129     status_t setPreviewTarget(const sp<IGraphicBufferProducer> & /*bufferProducer*/) override {
130         return 0;
131     };
setPreviewCallbackFlag(int)132     void setPreviewCallbackFlag(int /*flag*/) override{};
setPreviewCallbackTarget(const sp<IGraphicBufferProducer> &)133     status_t setPreviewCallbackTarget(
134         const sp<IGraphicBufferProducer> & /*callbackProducer*/) override {
135         return 0;
136     };
startPreview()137     status_t startPreview() override { return 0; };
stopPreview()138     void stopPreview() override{};
previewEnabled()139     bool previewEnabled() override { return true; };
startRecording()140     status_t startRecording() override { return 0; };
stopRecording()141     void stopRecording() override{};
recordingEnabled()142     bool recordingEnabled() override { return true; };
releaseRecordingFrame(const sp<IMemory> &)143     void releaseRecordingFrame(const sp<IMemory> & /*mem*/) override{};
releaseRecordingFrameHandle(native_handle_t *)144     void releaseRecordingFrameHandle(native_handle_t * /*handle*/) override{};
releaseRecordingFrameHandleBatch(const vector<native_handle_t * > &)145     void releaseRecordingFrameHandleBatch(const vector<native_handle_t *> & /*handles*/) override{};
autoFocus()146     status_t autoFocus() override { return 0; };
cancelAutoFocus()147     status_t cancelAutoFocus() override { return 0; };
takePicture(int)148     status_t takePicture(int /*msgType*/) override { return 0; };
setParameters(const String8 &)149     status_t setParameters(const String8 & /*params*/) override { return 0; };
getParameters() const150     String8 getParameters() const override { return String8(); };
sendCommand(int32_t,int32_t,int32_t)151     status_t sendCommand(int32_t /*cmd*/, int32_t /*arg1*/, int32_t /*arg2*/) override {
152         return 0;
153     };
setVideoBufferMode(int32_t)154     status_t setVideoBufferMode(int32_t /*videoBufferMode*/) override { return 0; };
setVideoTarget(const sp<IGraphicBufferProducer> &)155     status_t setVideoTarget(const sp<IGraphicBufferProducer> & /*bufferProducer*/) override {
156         return 0;
157     };
setAudioRestriction(int32_t)158     status_t setAudioRestriction(int32_t /*mode*/) override { return 0; };
getGlobalAudioRestriction()159     int32_t getGlobalAudioRestriction() override { return 0; };
onAsBinder()160     IBinder *onAsBinder() override { return reinterpret_cast<IBinder *>(this); };
161 };
162 
163 class TestMediaRecorderClient : public IMediaRecorderClient {
164    public:
165     virtual ~TestMediaRecorderClient() = default;
166 
notify(int,int,int)167     void notify(int /*msg*/, int /*ext1*/, int /*ext2*/) override{};
onAsBinder()168     IBinder *onAsBinder() override { return reinterpret_cast<IBinder *>(this); };
169 };
170 
171 class MediaRecorderClientFuzzer {
172    public:
173     MediaRecorderClientFuzzer(const uint8_t *data, size_t size);
~MediaRecorderClientFuzzer()174     ~MediaRecorderClientFuzzer() { close(mMediaRecorderOutputFd); }
175     void process();
176 
177    private:
178     void setConfig();
179     void getConfig();
180     void dumpInfo();
181 
182     FuzzedDataProvider mFdp;
183     unique_ptr<MediaRecorderBase> mStfRecorder = nullptr;
184     SurfaceComposerClient mComposerClient;
185     sp<SurfaceControl> mSurfaceControl = nullptr;
186     sp<Surface> mSurface = nullptr;
187     const int32_t mMediaRecorderOutputFd;
188 };
189 
getConfig()190 void MediaRecorderClientFuzzer::getConfig() {
191     int32_t max;
192     mStfRecorder->getMaxAmplitude(&max);
193 
194     int32_t deviceId;
195     mStfRecorder->getRoutedDeviceId(&deviceId);
196 
197     vector<android::media::MicrophoneInfoFw> activeMicrophones{};
198     mStfRecorder->getActiveMicrophones(&activeMicrophones);
199 
200     int32_t portId;
201     mStfRecorder->getPortId(&portId);
202 
203     uint64_t bytes;
204     mStfRecorder->getRtpDataUsage(&bytes);
205 
206     Parcel parcel;
207     mStfRecorder->getMetrics(&parcel);
208 
209     sp<IGraphicBufferProducer> buffer = mStfRecorder->querySurfaceMediaSource();
210 }
211 
212 template <typename FuncWrapper>
callMediaAPI(FuncWrapper funcWrapper,FuzzedDataProvider * fdp)213 void callMediaAPI(FuncWrapper funcWrapper, FuzzedDataProvider* fdp) {
214     if (fdp->ConsumeBool()) {
215         funcWrapper();
216     }
217 }
218 
setConfig()219 void MediaRecorderClientFuzzer::setConfig() {
220     callMediaAPI(
221             [this]() {
222                 mSurfaceControl = mComposerClient.createSurface(
223                         String8(mFdp.ConsumeRandomLengthString().c_str()) /* name */,
224                         mFdp.ConsumeIntegral<uint32_t>() /* width */,
225                         mFdp.ConsumeIntegral<uint32_t>() /* height */,
226                         mFdp.ConsumeIntegral<int32_t>() /* pixel-format */,
227                         mFdp.ConsumeIntegral<int32_t>() /* flags */);
228                 if (mSurfaceControl) {
229                     mSurface = mSurfaceControl->getSurface();
230                     mStfRecorder->setPreviewSurface(mSurface->getIGraphicBufferProducer());
231                 }
232             },
233             &mFdp);
234 
235     callMediaAPI([this]() { mStfRecorder->setInputDevice(mFdp.ConsumeIntegral<int32_t>()); },
236                  &mFdp);
237 
238     callMediaAPI(
239             [this]() {
240                 sp<TestMediaRecorderClient> listener = sp<TestMediaRecorderClient>::make();
241                 mStfRecorder->setListener(listener);
242             },
243             &mFdp);
244 
245     callMediaAPI(
246             [this]() {
247                 sp<TestCamera> testCamera = sp<TestCamera>::make();
248                 sp<Camera> camera = Camera::create(testCamera);
249                 mStfRecorder->setCamera(camera->remote(), camera->getRecordingProxy());
250             },
251             &mFdp);
252 
253     callMediaAPI(
254             [this]() {
255                 sp<PersistentSurface> persistentSurface = sp<PersistentSurface>::make();
256                 mStfRecorder->setInputSurface(persistentSurface);
257             },
258             &mFdp);
259 
260     callMediaAPI(
261             [this]() {
262                 sp<TestAudioDeviceCallback> callback = sp<TestAudioDeviceCallback>::make();
263                 mStfRecorder->setAudioDeviceCallback(callback);
264                 mStfRecorder->setOutputFile(mMediaRecorderOutputFd);
265             },
266             &mFdp);
267 
268     callMediaAPI(
269             [this]() {
270                 mStfRecorder->setAudioSource(mFdp.PickValueInArray(kSupportedAudioSources));
271             },
272             &mFdp);
273 
274     callMediaAPI(
275             [this]() {
276                 mStfRecorder->setVideoSource(mFdp.PickValueInArray(kSupportedVideoSources));
277             },
278             &mFdp);
279 
280     callMediaAPI(
281             [this]() {
282                 mStfRecorder->setPreferredMicrophoneDirection(
283                         mFdp.PickValueInArray(kSupportedMicrophoneDirections));
284             },
285             &mFdp);
286 
287     callMediaAPI([this]() { mStfRecorder->setPrivacySensitive(mFdp.ConsumeBool()); }, &mFdp);
288 
289     callMediaAPI(
290             [this]() {
291                 bool isPrivacySensitive;
292                 mStfRecorder->isPrivacySensitive(&isPrivacySensitive);
293             },
294             &mFdp);
295 
296     callMediaAPI(
297             [this]() {
298                 mStfRecorder->setVideoSize(mFdp.ConsumeIntegralInRange<int32_t>(
299                                                    kMinVideoSize, kMaxVideoSize) /* width */,
300                                            mFdp.ConsumeIntegralInRange<int32_t>(
301                                                    kMinVideoSize, kMaxVideoSize) /* height */);
302             },
303             &mFdp);
304 
305     callMediaAPI([this]() { mStfRecorder->setVideoFrameRate(mFdp.ConsumeIntegral<int32_t>()); },
306                  &mFdp);
307 
308     callMediaAPI([this]() { mStfRecorder->enableAudioDeviceCallback(mFdp.ConsumeBool()); }, &mFdp);
309 
310     callMediaAPI(
311             [this]() {
312                 mStfRecorder->setPreferredMicrophoneFieldDimension(
313                         mFdp.ConsumeFloatingPoint<float>());
314             },
315             &mFdp);
316 
317     callMediaAPI(
318             [this]() {
319                 mStfRecorder->setClientName(String16(mFdp.ConsumeRandomLengthString().c_str()));
320             },
321             &mFdp);
322 
323     callMediaAPI(
324             [this]() {
325                 output_format OutputFormat = mFdp.PickValueInArray(kOutputFormat);
326                 audio_encoder AudioEncoderFormat =
327                         (audio_encoder)mFdp.ConsumeIntegralInRange<int32_t>(AUDIO_ENCODER_DEFAULT,
328                                                                             AUDIO_ENCODER_LIST_END);
329                 video_encoder VideoEncoderFormat = mFdp.PickValueInArray(kVideoEncoder);
330                 if (OutputFormat == OUTPUT_FORMAT_AMR_NB) {
331                     AudioEncoderFormat =
332                             mFdp.ConsumeBool() ? AUDIO_ENCODER_DEFAULT : AUDIO_ENCODER_AMR_NB;
333                 } else if (OutputFormat == OUTPUT_FORMAT_AMR_WB) {
334                     AudioEncoderFormat = AUDIO_ENCODER_AMR_WB;
335                 } else if (OutputFormat == OUTPUT_FORMAT_AAC_ADIF ||
336                            OutputFormat == OUTPUT_FORMAT_AAC_ADTS ||
337                            OutputFormat == OUTPUT_FORMAT_MPEG2TS) {
338                     AudioEncoderFormat = (audio_encoder)mFdp.ConsumeIntegralInRange<int32_t>(
339                             AUDIO_ENCODER_AAC, AUDIO_ENCODER_AAC_ELD);
340                     if (OutputFormat == OUTPUT_FORMAT_MPEG2TS) {
341                         VideoEncoderFormat = VIDEO_ENCODER_H264;
342                     }
343                 }
344                 mStfRecorder->setOutputFormat(OutputFormat);
345                 mStfRecorder->setAudioEncoder(AudioEncoderFormat);
346                 mStfRecorder->setVideoEncoder(VideoEncoderFormat);
347             },
348             &mFdp);
349 
350     callMediaAPI(
351             [this]() {
352                 int32_t nextOutputFd = memfd_create(kNextOutputFile, MFD_ALLOW_SEALING);
353                 mStfRecorder->setNextOutputFile(nextOutputFd);
354                 close(nextOutputFd);
355             },
356             &mFdp);
357 
358     callMediaAPI(
359             [this]() {
360                 for (int32_t idx = 0; idx < size(kParametersList); ++idx) {
361                     if (mFdp.ConsumeBool()) {
362                         int32_t value = mFdp.ConsumeIntegral<int32_t>();
363                         mStfRecorder->setParameters(
364                                 String8((kParametersList[idx] + "=" + to_string(value)).c_str()));
365                     }
366                 }
367             },
368             &mFdp);
369 }
370 
MediaRecorderClientFuzzer(const uint8_t * data,size_t size)371 MediaRecorderClientFuzzer::MediaRecorderClientFuzzer(const uint8_t* data, size_t size)
372     : mFdp(data, size), mMediaRecorderOutputFd(memfd_create(kOutputFile, MFD_ALLOW_SEALING)) {
373     AttributionSourceState attributionSource;
374     attributionSource.packageName = mFdp.ConsumeRandomLengthString().c_str();
375     attributionSource.token = sp<BBinder>::make();
376     mStfRecorder = make_unique<StagefrightRecorder>(attributionSource);
377 }
378 
process()379 void MediaRecorderClientFuzzer::process() {
380     mStfRecorder->init();
381     mStfRecorder->prepare();
382     while (mFdp.remaining_bytes()) {
383         auto invokeMediaPLayerApi = mFdp.PickValueInArray<const std::function<void()>>({
384                 [&]() { setConfig(); },
385                 [&]() { mStfRecorder->start(); },
386                 [&]() { mStfRecorder->pause(); },
387                 [&]() { mStfRecorder->resume(); },
388                 [&]() { mStfRecorder->stop(); },
389                 [&]() { getConfig(); },
390                 [&]() { mStfRecorder->close(); },
391                 [&]() { mStfRecorder->reset(); },
392         });
393         invokeMediaPLayerApi();
394     }
395 }
396 
LLVMFuzzerInitialize(int,char)397 extern "C" int LLVMFuzzerInitialize(int /* *argc */, char /* ***argv */) {
398     /**
399      * Initializing a FakeServiceManager and adding the instances
400      * of all the required services
401      */
402     sp<IServiceManager> fakeServiceManager = new FakeServiceManager();
403     setDefaultServiceManager(fakeServiceManager);
404     MediaPlayerService::instantiate();
405     AudioFlinger::instantiate();
406     ResourceManagerService::instantiate();
407     CameraService::instantiate();
408     fakeServiceManager->addService(String16(MediaMetricsService::kServiceName),
409                                     new MediaMetricsService());
410     return 0;
411 }
412 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)413 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
414     MediaRecorderClientFuzzer mrcFuzzer(data, size);
415     mrcFuzzer.process();
416     return 0;
417 }
418