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 <media/stagefright/foundation/AString.h>
19 #include "fuzzer/FuzzedDataProvider.h"
20
21 #include <AudioFlinger.h>
22 #include <MediaPlayerService.h>
23 #include <ResourceManagerService.h>
24 #include <fakeservicemanager/FakeServiceManager.h>
25 #include <StagefrightRecorder.h>
26 #include <camera/Camera.h>
27 #include <camera/android/hardware/ICamera.h>
28 #include <gui/IGraphicBufferProducer.h>
29 #include <gui/Surface.h>
30 #include <gui/SurfaceComposerClient.h>
31 #include <media/stagefright/PersistentSurface.h>
32 #include <mediametricsservice/MediaMetricsService.h>
33 #include <thread>
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
51 constexpr audio_microphone_direction_t kSupportedMicrophoneDirections[] = {
52 MIC_DIRECTION_UNSPECIFIED, MIC_DIRECTION_FRONT, MIC_DIRECTION_BACK, MIC_DIRECTION_EXTERNAL};
53
54 struct RecordingConfig {
55 output_format outputFormat;
56 audio_encoder audioEncoder;
57 video_encoder videoEncoder;
58 };
59
60 const struct RecordingConfig kRecordingConfigList[] = {
61 {OUTPUT_FORMAT_AMR_NB, AUDIO_ENCODER_AMR_NB, VIDEO_ENCODER_DEFAULT},
62 {OUTPUT_FORMAT_AMR_WB, AUDIO_ENCODER_AMR_WB, VIDEO_ENCODER_DEFAULT},
63 {OUTPUT_FORMAT_AAC_ADTS, AUDIO_ENCODER_AAC, VIDEO_ENCODER_DEFAULT},
64 {OUTPUT_FORMAT_AAC_ADTS, AUDIO_ENCODER_HE_AAC, VIDEO_ENCODER_DEFAULT},
65 {OUTPUT_FORMAT_AAC_ADTS, AUDIO_ENCODER_AAC_ELD, VIDEO_ENCODER_DEFAULT},
66 {OUTPUT_FORMAT_OGG, AUDIO_ENCODER_OPUS, VIDEO_ENCODER_DEFAULT},
67 {OUTPUT_FORMAT_RTP_AVP, AUDIO_ENCODER_DEFAULT, VIDEO_ENCODER_DEFAULT},
68 {OUTPUT_FORMAT_MPEG2TS, AUDIO_ENCODER_AAC, VIDEO_ENCODER_H264},
69 {OUTPUT_FORMAT_WEBM, AUDIO_ENCODER_VORBIS, VIDEO_ENCODER_VP8},
70 {OUTPUT_FORMAT_THREE_GPP, AUDIO_ENCODER_DEFAULT, VIDEO_ENCODER_MPEG_4_SP},
71 {OUTPUT_FORMAT_MPEG_4, AUDIO_ENCODER_AAC, VIDEO_ENCODER_H264},
72 {OUTPUT_FORMAT_MPEG_4, AUDIO_ENCODER_DEFAULT, VIDEO_ENCODER_MPEG_4_SP},
73 {OUTPUT_FORMAT_MPEG_4, AUDIO_ENCODER_DEFAULT, VIDEO_ENCODER_HEVC}};
74
75 const string kParametersList[] = {"max-duration",
76 "max-filesize",
77 "interleave-duration-us",
78 "param-movie-time-scale",
79 "param-geotag-longitude",
80 "param-geotag-latitude",
81 "param-track-time-status",
82 "audio-param-sampling-rate",
83 "audio-param-encoding-bitrate",
84 "audio-param-number-of-channels",
85 "audio-param-time-scale",
86 "video-param-rotation-angle-degrees",
87 "video-param-encoding-bitrate",
88 "video-param-bitrate-mode",
89 "video-param-i-frames-interval",
90 "video-param-encoder-profile",
91 "video-param-encoder-level",
92 "video-param-camera-id",
93 "video-param-time-scale",
94 "param-use-64bit-offset",
95 "time-lapse-enable",
96 "time-lapse-fps",
97 "rtp-param-local-ip",
98 "rtp-param-local-port",
99 "rtp-param-remote-port",
100 "rtp-param-self-id",
101 "rtp-param-opponent-id",
102 "rtp-param-payload-type",
103 "rtp-param-ext-cvo-extmap",
104 "rtp-param-ext-cvo-degrees",
105 "video-param-request-i-frame",
106 "rtp-param-set-socket-dscp",
107 "rtp-param-set-socket-network"};
108
109 constexpr int32_t kMaxSleepTimeInMs = 100;
110 constexpr int32_t kMinSleepTimeInMs = 0;
111 constexpr int32_t kMinVideoSize = 2;
112 constexpr int32_t kMaxVideoSize = 8192;
113 constexpr int32_t kNumRecordMin = 1;
114 constexpr int32_t kNumRecordMax = 10;
115
116 class TestAudioDeviceCallback : public AudioSystem::AudioDeviceCallback {
117 public:
118 virtual ~TestAudioDeviceCallback() = default;
119
onAudioDeviceUpdate(audio_io_handle_t,audio_port_handle_t)120 void onAudioDeviceUpdate(audio_io_handle_t /*audioIo*/,
121 audio_port_handle_t /*deviceId*/) override{};
122 };
123
124 class TestCamera : public ICamera {
125 public:
126 virtual ~TestCamera() = default;
127
disconnect()128 binder::Status disconnect() override { return binder::Status::ok(); };
connect(const sp<ICameraClient> &)129 status_t connect(const sp<ICameraClient> & /*client*/) override { return 0; };
lock()130 status_t lock() override { return 0; };
unlock()131 status_t unlock() override { return 0; };
setPreviewTarget(const sp<IGraphicBufferProducer> &)132 status_t setPreviewTarget(const sp<IGraphicBufferProducer> & /*bufferProducer*/) override {
133 return 0;
134 };
setPreviewCallbackFlag(int)135 void setPreviewCallbackFlag(int /*flag*/) override{};
setPreviewCallbackTarget(const sp<IGraphicBufferProducer> &)136 status_t setPreviewCallbackTarget(
137 const sp<IGraphicBufferProducer> & /*callbackProducer*/) override {
138 return 0;
139 };
startPreview()140 status_t startPreview() override { return 0; };
stopPreview()141 void stopPreview() override{};
previewEnabled()142 bool previewEnabled() override { return true; };
startRecording()143 status_t startRecording() override { return 0; };
stopRecording()144 void stopRecording() override{};
recordingEnabled()145 bool recordingEnabled() override { return true; };
releaseRecordingFrame(const sp<IMemory> &)146 void releaseRecordingFrame(const sp<IMemory> & /*mem*/) override{};
releaseRecordingFrameHandle(native_handle_t *)147 void releaseRecordingFrameHandle(native_handle_t * /*handle*/) override{};
releaseRecordingFrameHandleBatch(const vector<native_handle_t * > &)148 void releaseRecordingFrameHandleBatch(const vector<native_handle_t *> & /*handles*/) override{};
autoFocus()149 status_t autoFocus() override { return 0; };
cancelAutoFocus()150 status_t cancelAutoFocus() override { return 0; };
takePicture(int)151 status_t takePicture(int /*msgType*/) override { return 0; };
setParameters(const String8 &)152 status_t setParameters(const String8 & /*params*/) override { return 0; };
getParameters() const153 String8 getParameters() const override { return String8(); };
sendCommand(int32_t,int32_t,int32_t)154 status_t sendCommand(int32_t /*cmd*/, int32_t /*arg1*/, int32_t /*arg2*/) override {
155 return 0;
156 };
setVideoBufferMode(int32_t)157 status_t setVideoBufferMode(int32_t /*videoBufferMode*/) override { return 0; };
setVideoTarget(const sp<IGraphicBufferProducer> &)158 status_t setVideoTarget(const sp<IGraphicBufferProducer> & /*bufferProducer*/) override {
159 return 0;
160 };
setAudioRestriction(int32_t)161 status_t setAudioRestriction(int32_t /*mode*/) override { return 0; };
getGlobalAudioRestriction()162 int32_t getGlobalAudioRestriction() override { return 0; };
onAsBinder()163 IBinder *onAsBinder() override { return reinterpret_cast<IBinder *>(this); };
164 };
165
166 class TestMediaRecorderClient : public IMediaRecorderClient {
167 public:
168 virtual ~TestMediaRecorderClient() = default;
169
notify(int,int,int)170 void notify(int /*msg*/, int /*ext1*/, int /*ext2*/) override{};
onAsBinder()171 IBinder *onAsBinder() override { return reinterpret_cast<IBinder *>(this); };
172 };
173
174 class MediaRecorderClientFuzzer {
175 public:
176 MediaRecorderClientFuzzer(const uint8_t *data, size_t size);
~MediaRecorderClientFuzzer()177 ~MediaRecorderClientFuzzer() { close(mMediaRecorderOutputFd); }
178 void process();
179
180 private:
181 void setConfig();
182 void getConfig();
183 void dumpInfo();
184
185 FuzzedDataProvider mFdp;
186 unique_ptr<MediaRecorderBase> mStfRecorder = nullptr;
187 SurfaceComposerClient mComposerClient;
188 sp<SurfaceControl> mSurfaceControl = nullptr;
189 sp<Surface> mSurface = nullptr;
190 const int32_t mMediaRecorderOutputFd;
191 };
192
getConfig()193 void MediaRecorderClientFuzzer::getConfig() {
194 int32_t max;
195 mStfRecorder->getMaxAmplitude(&max);
196
197 int32_t deviceId = mFdp.ConsumeIntegral<int32_t>();
198 mStfRecorder->setInputDevice(deviceId);
199 mStfRecorder->getRoutedDeviceId(&deviceId);
200
201 vector<android::media::MicrophoneInfoFw> activeMicrophones{};
202 mStfRecorder->getActiveMicrophones(&activeMicrophones);
203
204 int32_t portId;
205 mStfRecorder->getPortId(&portId);
206
207 uint64_t bytes;
208 mStfRecorder->getRtpDataUsage(&bytes);
209
210 Parcel parcel;
211 mStfRecorder->getMetrics(&parcel);
212
213 sp<IGraphicBufferProducer> buffer = mStfRecorder->querySurfaceMediaSource();
214 }
215
dumpInfo()216 void MediaRecorderClientFuzzer::dumpInfo() {
217 int32_t dumpFd = memfd_create("DumpFile", MFD_ALLOW_SEALING);
218 Vector<String16> args;
219 args.push_back(String16(mFdp.ConsumeRandomLengthString().c_str()));
220 mStfRecorder->dump(dumpFd, args);
221 close(dumpFd);
222 }
223
setConfig()224 void MediaRecorderClientFuzzer::setConfig() {
225 mStfRecorder->setOutputFile(mMediaRecorderOutputFd);
226 mStfRecorder->setAudioSource(mFdp.PickValueInArray(kSupportedAudioSources));
227 mStfRecorder->setVideoSource(mFdp.PickValueInArray(kSupportedVideoSources));
228 mStfRecorder->setPreferredMicrophoneDirection(
229 mFdp.PickValueInArray(kSupportedMicrophoneDirections));
230 mStfRecorder->setPrivacySensitive(mFdp.ConsumeBool());
231 bool isPrivacySensitive;
232 mStfRecorder->isPrivacySensitive(&isPrivacySensitive);
233 mStfRecorder->setVideoSize(mFdp.ConsumeIntegralInRange<int32_t>(kMinVideoSize, kMaxVideoSize),
234 mFdp.ConsumeIntegralInRange<int32_t>(kMinVideoSize, kMaxVideoSize));
235 mStfRecorder->setVideoFrameRate(mFdp.ConsumeIntegral<int32_t>());
236 mStfRecorder->enableAudioDeviceCallback(mFdp.ConsumeBool());
237 mStfRecorder->setPreferredMicrophoneFieldDimension(mFdp.ConsumeFloatingPoint<float>());
238 mStfRecorder->setClientName(String16(mFdp.ConsumeRandomLengthString().c_str()));
239
240 int32_t Idx = mFdp.ConsumeIntegralInRange<int32_t>(0, size(kRecordingConfigList) - 1);
241 mStfRecorder->setOutputFormat(kRecordingConfigList[Idx].outputFormat);
242 mStfRecorder->setAudioEncoder(kRecordingConfigList[Idx].audioEncoder);
243 mStfRecorder->setVideoEncoder(kRecordingConfigList[Idx].videoEncoder);
244
245 int32_t nextOutputFd = memfd_create("NextOutputFile", MFD_ALLOW_SEALING);
246 mStfRecorder->setNextOutputFile(nextOutputFd);
247 close(nextOutputFd);
248
249 for (Idx = 0; Idx < size(kParametersList); ++Idx) {
250 if (mFdp.ConsumeBool()) {
251 int32_t value = mFdp.ConsumeIntegral<int32_t>();
252 mStfRecorder->setParameters(
253 String8((kParametersList[Idx] + "=" + to_string(value)).c_str()));
254 }
255 }
256 }
257
MediaRecorderClientFuzzer(const uint8_t * data,size_t size)258 MediaRecorderClientFuzzer::MediaRecorderClientFuzzer(const uint8_t *data, size_t size)
259 : mFdp(data, size), mMediaRecorderOutputFd(memfd_create("OutputFile", MFD_ALLOW_SEALING)) {
260 AttributionSourceState attributionSource;
261 attributionSource.packageName = mFdp.ConsumeRandomLengthString().c_str();
262 attributionSource.token = sp<BBinder>::make();
263 mStfRecorder = make_unique<StagefrightRecorder>(attributionSource);
264
265 mSurfaceControl = mComposerClient.createSurface(
266 String8(mFdp.ConsumeRandomLengthString().c_str()), mFdp.ConsumeIntegral<uint32_t>(),
267 mFdp.ConsumeIntegral<uint32_t>(), mFdp.ConsumeIntegral<int32_t>(),
268 mFdp.ConsumeIntegral<int32_t>());
269 if (mSurfaceControl) {
270 mSurface = mSurfaceControl->getSurface();
271 mStfRecorder->setPreviewSurface(mSurface->getIGraphicBufferProducer());
272 }
273
274 sp<TestMediaRecorderClient> listener = sp<TestMediaRecorderClient>::make();
275 mStfRecorder->setListener(listener);
276
277 sp<TestCamera> testCamera = sp<TestCamera>::make();
278 sp<Camera> camera = Camera::create(testCamera);
279 mStfRecorder->setCamera(camera->remote(), camera->getRecordingProxy());
280
281 sp<PersistentSurface> persistentSurface = sp<PersistentSurface>::make();
282 mStfRecorder->setInputSurface(persistentSurface);
283
284 sp<TestAudioDeviceCallback> callback = sp<TestAudioDeviceCallback>::make();
285 mStfRecorder->setAudioDeviceCallback(callback);
286 }
287
process()288 void MediaRecorderClientFuzzer::process() {
289 setConfig();
290
291 mStfRecorder->init();
292 mStfRecorder->prepare();
293 size_t numRecord = mFdp.ConsumeIntegralInRange<size_t>(kNumRecordMin, kNumRecordMax);
294 for (size_t Idx = 0; Idx < numRecord; ++Idx) {
295 mStfRecorder->start();
296 this_thread::sleep_for(chrono::milliseconds(
297 mFdp.ConsumeIntegralInRange<int32_t>(kMinSleepTimeInMs, kMaxSleepTimeInMs)));
298 mStfRecorder->pause();
299 this_thread::sleep_for(chrono::milliseconds(
300 mFdp.ConsumeIntegralInRange<int32_t>(kMinSleepTimeInMs, kMaxSleepTimeInMs)));
301 mStfRecorder->resume();
302 this_thread::sleep_for(chrono::milliseconds(
303 mFdp.ConsumeIntegralInRange<int32_t>(kMinSleepTimeInMs, kMaxSleepTimeInMs)));
304 mStfRecorder->stop();
305 }
306 dumpInfo();
307 getConfig();
308
309 mStfRecorder->close();
310 mStfRecorder->reset();
311 }
312
LLVMFuzzerInitialize(int,char)313 extern "C" int LLVMFuzzerInitialize(int /* *argc */, char /* ***argv */) {
314 /**
315 * Initializing a FakeServiceManager and adding the instances
316 * of all the required services
317 */
318 sp<IServiceManager> fakeServiceManager = new FakeServiceManager();
319 setDefaultServiceManager(fakeServiceManager);
320 MediaPlayerService::instantiate();
321 AudioFlinger::instantiate();
322 ResourceManagerService::instantiate();
323 fakeServiceManager->addService(String16(MediaMetricsService::kServiceName),
324 new MediaMetricsService());
325 return 0;
326 }
327
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)328 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
329 MediaRecorderClientFuzzer mrcFuzzer(data, size);
330 mrcFuzzer.process();
331 return 0;
332 }
333