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