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