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