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