1 /*
2 * Copyright (C) 2022 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 #include <Camera.h>
18 #include <CameraParameters.h>
19 #include <CameraUtils.h>
20 #include <android/content/AttributionSourceState.h>
21 #include <binder/MemoryDealer.h>
22 #include <fuzzer/FuzzedDataProvider.h>
23 #include <gui/Flags.h>
24 #include <gui/Surface.h>
25 #include <gui/SurfaceComposerClient.h>
26 #include "camera2common.h"
27
28 using namespace std;
29 using namespace android;
30 using namespace android::hardware;
31
32 constexpr int32_t kFrameRateMin = 1;
33 constexpr int32_t kFrameRateMax = 1000;
34 constexpr int32_t kNumMin = 0;
35 constexpr int32_t kNumMax = 1024;
36 constexpr int32_t kMemoryDealerSize = 1000;
37 constexpr int8_t kMinElements = 1;
38 constexpr int8_t kMaxElements = 10;
39
40 constexpr int32_t kValidCMD[] = {CAMERA_CMD_START_SMOOTH_ZOOM,
41 CAMERA_CMD_STOP_SMOOTH_ZOOM,
42 CAMERA_CMD_SET_DISPLAY_ORIENTATION,
43 CAMERA_CMD_ENABLE_SHUTTER_SOUND,
44 CAMERA_CMD_PLAY_RECORDING_SOUND,
45 CAMERA_CMD_START_FACE_DETECTION,
46 CAMERA_CMD_STOP_FACE_DETECTION,
47 CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG,
48 CAMERA_CMD_PING,
49 CAMERA_CMD_SET_VIDEO_BUFFER_COUNT,
50 CAMERA_CMD_SET_VIDEO_FORMAT};
51
52 constexpr int32_t kValidVideoBufferMode[] = {ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV,
53 ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA,
54 ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE};
55
56 constexpr int32_t kValidPreviewCallbackFlag[] = {
57 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK, CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK,
58 CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK, CAMERA_FRAME_CALLBACK_FLAG_NOOP,
59 CAMERA_FRAME_CALLBACK_FLAG_CAMCORDER, CAMERA_FRAME_CALLBACK_FLAG_CAMERA,
60 CAMERA_FRAME_CALLBACK_FLAG_BARCODE_SCANNER};
61
62 class TestCameraListener : public CameraListener {
63 public:
64 virtual ~TestCameraListener() = default;
65
notify(int32_t,int32_t,int32_t)66 void notify(int32_t /*msgType*/, int32_t /*ext1*/, int32_t /*ext2*/) override { return; };
postData(int32_t,const sp<IMemory> &,camera_frame_metadata_t *)67 void postData(int32_t /*msgType*/, const sp<IMemory>& /*dataPtr*/,
68 camera_frame_metadata_t* /*metadata*/) override {
69 return;
70 };
postDataTimestamp(nsecs_t,int32_t,const sp<IMemory> &)71 void postDataTimestamp(nsecs_t /*timestamp*/, int32_t /*msgType*/,
72 const sp<IMemory>& /*dataPtr*/) override {
73 return;
74 };
postRecordingFrameHandleTimestamp(nsecs_t,native_handle_t *)75 void postRecordingFrameHandleTimestamp(nsecs_t /*timestamp*/,
76 native_handle_t* /*handle*/) override {
77 return;
78 };
postRecordingFrameHandleTimestampBatch(const std::vector<nsecs_t> &,const std::vector<native_handle_t * > &)79 void postRecordingFrameHandleTimestampBatch(
80 const std::vector<nsecs_t>& /*timestamps*/,
81 const std::vector<native_handle_t*>& /*handles*/) override {
82 return;
83 };
84 };
85
86 class CameraFuzzer : public ::android::hardware::BnCameraClient {
87 public:
88 void process(const uint8_t* data, size_t size);
89
90 private:
91 bool initCamera();
92 void invokeCamera();
93 void invokeSetParameters();
94 native_handle_t* createNativeHandle();
95 sp<Camera> mCamera = nullptr;
96 FuzzedDataProvider* mFDP = nullptr;
97
98 // CameraClient interface
notifyCallback(int32_t,int32_t,int32_t)99 void notifyCallback(int32_t, int32_t, int32_t) override { return; };
dataCallback(int32_t,const sp<IMemory> &,camera_frame_metadata_t *)100 void dataCallback(int32_t, const sp<IMemory>&, camera_frame_metadata_t*) override { return; };
dataCallbackTimestamp(nsecs_t,int32_t,const sp<IMemory> &)101 void dataCallbackTimestamp(nsecs_t, int32_t, const sp<IMemory>&) override { return; };
recordingFrameHandleCallbackTimestamp(nsecs_t,native_handle_t *)102 void recordingFrameHandleCallbackTimestamp(nsecs_t, native_handle_t*) override { return; };
recordingFrameHandleCallbackTimestampBatch(const std::vector<nsecs_t> &,const std::vector<native_handle_t * > &)103 void recordingFrameHandleCallbackTimestampBatch(const std::vector<nsecs_t>&,
104 const std::vector<native_handle_t*>&) override {
105 return;
106 };
107 };
108
createNativeHandle()109 native_handle_t* CameraFuzzer::createNativeHandle() {
110 int32_t numFds = mFDP->ConsumeIntegralInRange<int32_t>(kMinElements, kMaxElements);
111 int32_t numInts = mFDP->ConsumeIntegralInRange<int32_t>(kNumMin, kNumMax);
112 native_handle_t* handle = native_handle_create(numFds, numInts);
113 for (int32_t i = 0; i < numFds; ++i) {
114 std::string filename = mFDP->ConsumeRandomLengthString(kMaxBytes);
115 int32_t fd = open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC);
116 handle->data[i] = fd;
117 }
118 return handle;
119 }
120
initCamera()121 bool CameraFuzzer::initCamera() {
122 ProcessState::self()->startThreadPool();
123 sp<IServiceManager> sm = defaultServiceManager();
124 sp<IBinder> binder = sm->getService(String16("media.camera"));
125 sp<ICameraService> cameraService = nullptr;
126 cameraService = interface_cast<ICameraService>(binder);
127 sp<ICamera> cameraDevice = nullptr;
128 AttributionSourceState clientAttribution;
129 clientAttribution.deviceId = kDefaultDeviceId;
130 if (mFDP->ConsumeBool()) {
131 clientAttribution.uid = hardware::ICameraService::USE_CALLING_UID;
132 clientAttribution.pid = hardware::ICameraService::USE_CALLING_PID;
133 clientAttribution.packageName = "CAMERAFUZZ";
134 cameraService->connect(this, mFDP->ConsumeIntegral<int32_t>() /* cameraId */,
135 /*targetSdkVersion*/ __ANDROID_API_FUTURE__,
136 /*overrideToPortrait*/ false, /*forceSlowJpegMode*/ false,
137 clientAttribution, /*devicePolicy*/0, &cameraDevice);
138 } else {
139 clientAttribution.uid = mFDP->ConsumeIntegral<int8_t>();
140 clientAttribution.pid = mFDP->ConsumeIntegral<int8_t>();
141 clientAttribution.packageName = mFDP->ConsumeRandomLengthString(kMaxBytes).c_str();
142 cameraService->connect(this, mFDP->ConsumeIntegral<int32_t>() /* cameraId */,
143 /*targetSdkVersion*/ mFDP->ConsumeIntegral<int32_t>(),
144 /*overrideToPortrait*/ mFDP->ConsumeBool(),
145 /*forceSlowJpegMode*/ mFDP->ConsumeBool(), clientAttribution,
146 /*devicePolicy*/0, &cameraDevice);
147 }
148
149 mCamera = Camera::create(cameraDevice);
150 if (!mCamera) {
151 return false;
152 }
153 return true;
154 }
155
invokeSetParameters()156 void CameraFuzzer::invokeSetParameters() {
157 String8 s = mCamera->getParameters();
158 CameraParameters params(s);
159 int32_t width = mFDP->ConsumeIntegral<int32_t>();
160 int32_t height = mFDP->ConsumeIntegral<int32_t>();
161 params.setVideoSize(width, height);
162 int32_t frameRate = mFDP->ConsumeIntegralInRange<int32_t>(kFrameRateMin, kFrameRateMax);
163 params.setPreviewFrameRate(frameRate);
164 mCamera->setParameters(params.flatten());
165 }
166
invokeCamera()167 void CameraFuzzer::invokeCamera() {
168 if (!initCamera()) {
169 return;
170 }
171
172 int32_t cameraId = mFDP->ConsumeIntegral<int32_t>();
173 AttributionSourceState clientAttribution;
174 clientAttribution.deviceId = kDefaultDeviceId;
175 Camera::getNumberOfCameras(clientAttribution, /*devicePolicy*/0);
176 CameraInfo cameraInfo;
177 cameraInfo.facing = mFDP->ConsumeBool() ? mFDP->PickValueInArray(kValidFacing)
178 : mFDP->ConsumeIntegral<int32_t>();
179 cameraInfo.orientation = mFDP->ConsumeBool() ? mFDP->PickValueInArray(kValidOrientation)
180 : mFDP->ConsumeIntegral<int32_t>();
181 Camera::getCameraInfo(cameraId, /*overrideToPortrait*/false, clientAttribution,
182 /*devicePolicy*/0, &cameraInfo);
183 mCamera->reconnect();
184
185 sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
186 sp<SurfaceControl> surfaceControl = nullptr;
187 if (mFDP->ConsumeBool()) {
188 surfaceControl = composerClient->createSurface(String8("FUZZSURFACE"), 1280, 800,
189 HAL_PIXEL_FORMAT_YV12);
190 } else {
191 surfaceControl = composerClient->createSurface(
192 static_cast<String8>(mFDP->ConsumeRandomLengthString(kMaxBytes).c_str()) /* name */,
193 mFDP->ConsumeIntegral<uint32_t>() /* width */,
194 mFDP->ConsumeIntegral<uint32_t>() /* height */,
195 mFDP->ConsumeIntegral<int32_t>() /* format */,
196 mFDP->ConsumeIntegral<int32_t>() /* flags */);
197 }
198
199 if (mFDP->ConsumeBool()) {
200 invokeSetParameters();
201 }
202 sp<Surface> surface = nullptr;
203 if (surfaceControl) {
204 surface = surfaceControl->getSurface();
205 }
206 sp<MemoryDealer> memoryDealer = nullptr;
207 sp<IMemory> iMem = nullptr;
208 sp<CameraListener> cameraListener = nullptr;
209
210 while (mFDP->remaining_bytes()) {
211 auto callCameraAPIs = mFDP->PickValueInArray<const std::function<void()>>({
212 [&]() {
213 if (surfaceControl) {
214 mCamera->setPreviewTarget(surface
215 #if !WB_LIBCAMERASERVICE_WITH_DEPENDENCIES
216 ->getIGraphicBufferProducer()
217 #endif
218 );
219 }
220 },
221 [&]() {
222 if (surfaceControl) {
223 mCamera->startPreview();
224 }
225 },
226 [&]() {
227 if (surfaceControl) {
228 mCamera->stopPreview();
229 }
230 },
231 [&]() {
232 if (surfaceControl) {
233 mCamera->stopPreview();
234 }
235 },
236 [&]() {
237 if (surfaceControl) {
238 mCamera->previewEnabled();
239 }
240 },
241 [&]() {
242 if (surfaceControl) {
243 mCamera->startRecording();
244 }
245 },
246 [&]() {
247 if (surfaceControl) {
248 mCamera->stopRecording();
249 }
250 },
251 [&]() { mCamera->lock(); },
252 [&]() { mCamera->unlock(); },
253 [&]() { mCamera->autoFocus(); },
254 [&]() { mCamera->cancelAutoFocus(); },
255 [&]() {
256 int32_t msgType = mFDP->ConsumeIntegral<int32_t>();
257 mCamera->takePicture(msgType);
258 },
259 [&]() {
260 int32_t cmd;
261 cmd = mFDP->ConsumeBool() ? mFDP->PickValueInArray(kValidCMD)
262 : mFDP->ConsumeIntegral<int32_t>();
263 int32_t arg1 = mFDP->ConsumeIntegral<int32_t>();
264 int32_t arg2 = mFDP->ConsumeIntegral<int32_t>();
265 mCamera->sendCommand(cmd, arg1, arg2);
266 },
267 [&]() {
268 int32_t videoBufferMode =
269 mFDP->ConsumeBool() ? mFDP->PickValueInArray(kValidVideoBufferMode)
270 : mFDP->ConsumeIntegral<int32_t>();
271 mCamera->setVideoBufferMode(videoBufferMode);
272 },
273 [&]() {
274 if (surfaceControl) {
275 mCamera->setVideoTarget(surface
276 #if !WB_LIBCAMERASERVICE_WITH_DEPENDENCIES
277 ->getIGraphicBufferProducer()
278 #endif
279 );
280 }
281 },
282 [&]() {
283 cameraListener = sp<TestCameraListener>::make();
284 mCamera->setListener(cameraListener);
285 },
286 [&]() {
287 int32_t previewCallbackFlag;
288 previewCallbackFlag =
289 mFDP->ConsumeBool() ? mFDP->PickValueInArray(kValidPreviewCallbackFlag)
290 : mFDP->ConsumeIntegral<int32_t>();
291 mCamera->setPreviewCallbackFlags(previewCallbackFlag);
292 },
293 [&]() {
294 if (surfaceControl) {
295 mCamera->setPreviewCallbackTarget(surface
296 #if !WB_LIBCAMERASERVICE_WITH_DEPENDENCIES
297 ->getIGraphicBufferProducer()
298 #endif
299 );
300 }
301 },
302 [&]() { mCamera->getRecordingProxy(); },
303 [&]() {
304 int32_t mode = mFDP->ConsumeIntegral<int32_t>();
305 mCamera->setAudioRestriction(mode);
306 },
307 [&]() { mCamera->getGlobalAudioRestriction(); },
308 [&]() { mCamera->recordingEnabled(); },
309 [&]() {
310 memoryDealer = new MemoryDealer(kMemoryDealerSize);
311 iMem = memoryDealer->allocate(kMemoryDealerSize);
312 },
313 [&]() {
314 int32_t msgTypeNC = mFDP->ConsumeIntegral<int32_t>();
315 int32_t ext = mFDP->ConsumeIntegral<int32_t>();
316 int32_t ext2 = mFDP->ConsumeIntegral<int32_t>();
317 mCamera->notifyCallback(msgTypeNC, ext, ext2);
318 },
319 [&]() {
320 int32_t msgTypeNC = mFDP->ConsumeIntegral<int32_t>();
321 int64_t timestamp = mFDP->ConsumeIntegral<int64_t>();
322 mCamera->dataCallbackTimestamp(timestamp, msgTypeNC, iMem);
323 },
324 [&]() {
325 int64_t timestamp = mFDP->ConsumeIntegral<int64_t>();
326 native_handle_t* handle = createNativeHandle();
327 mCamera->recordingFrameHandleCallbackTimestamp(timestamp, handle);
328 },
329 [&]() {
330 native_handle_t* handle = createNativeHandle();
331 mCamera->releaseRecordingFrameHandle(handle);
332 },
333 [&]() { mCamera->releaseRecordingFrame(iMem); },
334 [&]() {
335 std::vector<native_handle_t*> handles;
336 for (int8_t i = 0;
337 i < mFDP->ConsumeIntegralInRange<int8_t>(kMinElements, kMaxElements);
338 ++i) {
339 native_handle_t* handle = createNativeHandle();
340 handles.push_back(handle);
341 }
342 mCamera->releaseRecordingFrameHandleBatch(handles);
343 },
344 [&]() {
345 std::vector<native_handle_t*> handles;
346 for (int8_t i = 0;
347 i < mFDP->ConsumeIntegralInRange<int8_t>(kMinElements, kMaxElements);
348 ++i) {
349 native_handle_t* handle = createNativeHandle();
350 handles.push_back(handle);
351 }
352 std::vector<nsecs_t> timestamps;
353 for (int8_t i = 0;
354 i < mFDP->ConsumeIntegralInRange<int8_t>(kMinElements, kMaxElements);
355 ++i) {
356 timestamps.push_back(mFDP->ConsumeIntegral<int64_t>());
357 }
358 mCamera->recordingFrameHandleCallbackTimestampBatch(timestamps, handles);
359 },
360 });
361 callCameraAPIs();
362 }
363 }
364
process(const uint8_t * data,size_t size)365 void CameraFuzzer::process(const uint8_t* data, size_t size) {
366 mFDP = new FuzzedDataProvider(data, size);
367 invokeCamera();
368 delete mFDP;
369 }
370
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)371 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
372 sp<CameraFuzzer> cameraFuzzer = new CameraFuzzer();
373 cameraFuzzer->process(data, size);
374 cameraFuzzer.clear();
375 return 0;
376 }
377