blob: 08120968eba4c1c657dd274ef2ddc205728d8df2 [file] [log] [blame]
Aditya Wazird16f5df2021-07-28 17:57:32 +05301/*
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>
Aditya Wazird16f5df2021-07-28 17:57:32 +053018#include <CameraParameters.h>
Biswarup Pal37a75182024-01-16 15:53:35 +000019#include <CameraUtils.h>
Aditya Wazird16f5df2021-07-28 17:57:32 +053020#include <binder/MemoryDealer.h>
21#include <fuzzer/FuzzedDataProvider.h>
Aditya Wazird16f5df2021-07-28 17:57:32 +053022#include <gui/Surface.h>
23#include <gui/SurfaceComposerClient.h>
Aditya Wazird16f5df2021-07-28 17:57:32 +053024#include "camera2common.h"
Aditya Wazird16f5df2021-07-28 17:57:32 +053025
26using namespace std;
27using namespace android;
28using namespace android::hardware;
29
30constexpr int32_t kFrameRateMin = 1;
Kunal Raif57234d2023-11-07 10:19:41 +000031constexpr int32_t kFrameRateMax = 1000;
Aditya Wazird16f5df2021-07-28 17:57:32 +053032constexpr int32_t kNumMin = 0;
33constexpr int32_t kNumMax = 1024;
34constexpr int32_t kMemoryDealerSize = 1000;
Kunal Raif57234d2023-11-07 10:19:41 +000035constexpr int8_t kMinElements = 1;
36constexpr int8_t kMaxElements = 10;
Aditya Wazird16f5df2021-07-28 17:57:32 +053037
38constexpr 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
50constexpr 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
54constexpr 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
Aditya Wazird16f5df2021-07-28 17:57:32 +053060class TestCameraListener : public CameraListener {
61 public:
62 virtual ~TestCameraListener() = default;
63
64 void notify(int32_t /*msgType*/, int32_t /*ext1*/, int32_t /*ext2*/) override { return; };
65 void postData(int32_t /*msgType*/, const sp<IMemory>& /*dataPtr*/,
66 camera_frame_metadata_t* /*metadata*/) override {
67 return;
68 };
69 void postDataTimestamp(nsecs_t /*timestamp*/, int32_t /*msgType*/,
70 const sp<IMemory>& /*dataPtr*/) override {
71 return;
72 };
73 void postRecordingFrameHandleTimestamp(nsecs_t /*timestamp*/,
74 native_handle_t* /*handle*/) override {
75 return;
76 };
77 void postRecordingFrameHandleTimestampBatch(
78 const std::vector<nsecs_t>& /*timestamps*/,
79 const std::vector<native_handle_t*>& /*handles*/) override {
80 return;
81 };
82};
83
84class CameraFuzzer : public ::android::hardware::BnCameraClient {
85 public:
86 void process(const uint8_t* data, size_t size);
Aditya Wazird16f5df2021-07-28 17:57:32 +053087
88 private:
89 bool initCamera();
Aditya Wazird16f5df2021-07-28 17:57:32 +053090 void invokeCamera();
Aditya Wazird16f5df2021-07-28 17:57:32 +053091 void invokeSetParameters();
92 sp<Camera> mCamera = nullptr;
Aditya Wazird16f5df2021-07-28 17:57:32 +053093 FuzzedDataProvider* mFDP = nullptr;
94
95 // CameraClient interface
96 void notifyCallback(int32_t, int32_t, int32_t) override { return; };
97 void dataCallback(int32_t, const sp<IMemory>&, camera_frame_metadata_t*) override { return; };
98 void dataCallbackTimestamp(nsecs_t, int32_t, const sp<IMemory>&) override { return; };
99 void recordingFrameHandleCallbackTimestamp(nsecs_t, native_handle_t*) override { return; };
100 void recordingFrameHandleCallbackTimestampBatch(const std::vector<nsecs_t>&,
101 const std::vector<native_handle_t*>&) override {
102 return;
103 };
104};
105
106bool CameraFuzzer::initCamera() {
107 ProcessState::self()->startThreadPool();
108 sp<IServiceManager> sm = defaultServiceManager();
109 sp<IBinder> binder = sm->getService(String16("media.camera"));
Kunal Raif57234d2023-11-07 10:19:41 +0000110 sp<ICameraService> cameraService = nullptr;
111 cameraService = interface_cast<ICameraService>(binder);
112 sp<ICamera> cameraDevice = nullptr;
113 if (mFDP->ConsumeBool()) {
114 cameraService->connect(this, mFDP->ConsumeIntegral<int32_t>() /* cameraId */, "CAMERAFUZZ",
115 hardware::ICameraService::USE_CALLING_UID,
116 hardware::ICameraService::USE_CALLING_PID,
117 /*targetSdkVersion*/ __ANDROID_API_FUTURE__,
118 /*overrideToPortrait*/ false, /*forceSlowJpegMode*/ false,
Biswarup Pal37a75182024-01-16 15:53:35 +0000119 kDefaultDeviceId, /*devicePolicy*/0, &cameraDevice);
Kunal Raif57234d2023-11-07 10:19:41 +0000120 } else {
121 cameraService->connect(this, mFDP->ConsumeIntegral<int32_t>() /* cameraId */,
122 mFDP->ConsumeRandomLengthString(kMaxBytes).c_str(),
123 mFDP->ConsumeIntegral<int8_t>() /* clientUid */,
124 mFDP->ConsumeIntegral<int8_t>() /* clientPid */,
125 /*targetSdkVersion*/ mFDP->ConsumeIntegral<int32_t>(),
126 /*overrideToPortrait*/ mFDP->ConsumeBool(),
Biswarup Pal37a75182024-01-16 15:53:35 +0000127 /*forceSlowJpegMode*/ mFDP->ConsumeBool(), kDefaultDeviceId,
128 /*devicePolicy*/0, &cameraDevice);
Kunal Raif57234d2023-11-07 10:19:41 +0000129 }
130
Aditya Wazird16f5df2021-07-28 17:57:32 +0530131 mCamera = Camera::create(cameraDevice);
132 if (!mCamera) {
133 return false;
134 }
135 return true;
136}
137
138void CameraFuzzer::invokeSetParameters() {
139 String8 s = mCamera->getParameters();
140 CameraParameters params(s);
141 int32_t width = mFDP->ConsumeIntegral<int32_t>();
142 int32_t height = mFDP->ConsumeIntegral<int32_t>();
143 params.setVideoSize(width, height);
144 int32_t frameRate = mFDP->ConsumeIntegralInRange<int32_t>(kFrameRateMin, kFrameRateMax);
145 params.setPreviewFrameRate(frameRate);
146 mCamera->setParameters(params.flatten());
147}
148
149void CameraFuzzer::invokeCamera() {
150 if (!initCamera()) {
151 return;
152 }
153
Kunal Raif57234d2023-11-07 10:19:41 +0000154 int32_t cameraId = mFDP->ConsumeIntegral<int32_t>();
Biswarup Pal37a75182024-01-16 15:53:35 +0000155 Camera::getNumberOfCameras(kDefaultDeviceId, /*devicePolicy*/0);
Aditya Wazird16f5df2021-07-28 17:57:32 +0530156 CameraInfo cameraInfo;
157 cameraInfo.facing = mFDP->ConsumeBool() ? mFDP->PickValueInArray(kValidFacing)
Kunal Raif57234d2023-11-07 10:19:41 +0000158 : mFDP->ConsumeIntegral<int32_t>();
Aditya Wazird16f5df2021-07-28 17:57:32 +0530159 cameraInfo.orientation = mFDP->ConsumeBool() ? mFDP->PickValueInArray(kValidOrientation)
Kunal Raif57234d2023-11-07 10:19:41 +0000160 : mFDP->ConsumeIntegral<int32_t>();
Biswarup Pal37a75182024-01-16 15:53:35 +0000161 Camera::getCameraInfo(cameraId, /*overrideToPortrait*/false, kDefaultDeviceId,
162 /*devicePolicy*/0, &cameraInfo);
Aditya Wazird16f5df2021-07-28 17:57:32 +0530163 mCamera->reconnect();
164
Kunal Raif57234d2023-11-07 10:19:41 +0000165 sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
166 sp<SurfaceControl> surfaceControl = nullptr;
Aditya Wazird16f5df2021-07-28 17:57:32 +0530167 if (mFDP->ConsumeBool()) {
Kunal Raif57234d2023-11-07 10:19:41 +0000168 surfaceControl = composerClient->createSurface(String8("FUZZSURFACE"), 1280, 800,
169 HAL_PIXEL_FORMAT_YV12);
Aditya Wazird16f5df2021-07-28 17:57:32 +0530170 } else {
Kunal Raif57234d2023-11-07 10:19:41 +0000171 surfaceControl = composerClient->createSurface(
172 static_cast<String8>(mFDP->ConsumeRandomLengthString(kMaxBytes).c_str()) /* name */,
173 mFDP->ConsumeIntegral<uint32_t>() /* width */,
174 mFDP->ConsumeIntegral<uint32_t>() /* height */,
175 mFDP->ConsumeIntegral<int32_t>() /* format */,
176 mFDP->ConsumeIntegral<int32_t>() /* flags */);
Aditya Wazird16f5df2021-07-28 17:57:32 +0530177 }
Aditya Wazird16f5df2021-07-28 17:57:32 +0530178
179 if (mFDP->ConsumeBool()) {
Kunal Raif57234d2023-11-07 10:19:41 +0000180 invokeSetParameters();
Aditya Wazird16f5df2021-07-28 17:57:32 +0530181 }
Kunal Raif57234d2023-11-07 10:19:41 +0000182 sp<Surface> surface = nullptr;
183 if (surfaceControl) {
184 surface = surfaceControl->getSurface();
Aditya Wazird16f5df2021-07-28 17:57:32 +0530185 }
Kunal Raif57234d2023-11-07 10:19:41 +0000186 sp<MemoryDealer> memoryDealer = nullptr;
187 sp<IMemory> iMem = nullptr;
188 sp<CameraListener> cameraListener = nullptr;
Aditya Wazird16f5df2021-07-28 17:57:32 +0530189
Kunal Raif57234d2023-11-07 10:19:41 +0000190 while (mFDP->remaining_bytes()) {
191 auto callCameraAPIs = mFDP->PickValueInArray<const std::function<void()>>({
192 [&]() {
193 if (surfaceControl) {
194 mCamera->setPreviewTarget(surface->getIGraphicBufferProducer());
195 }
196 },
197 [&]() {
198 if (surfaceControl) {
199 mCamera->startPreview();
200 }
201 },
202 [&]() {
203 if (surfaceControl) {
204 mCamera->stopPreview();
205 }
206 },
207 [&]() {
208 if (surfaceControl) {
209 mCamera->stopPreview();
210 }
211 },
212 [&]() {
213 if (surfaceControl) {
214 mCamera->previewEnabled();
215 }
216 },
217 [&]() {
218 if (surfaceControl) {
219 mCamera->startRecording();
220 }
221 },
222 [&]() {
223 if (surfaceControl) {
224 mCamera->stopRecording();
225 }
226 },
227 [&]() { mCamera->lock(); },
228 [&]() { mCamera->unlock(); },
229 [&]() { mCamera->autoFocus(); },
230 [&]() { mCamera->cancelAutoFocus(); },
231 [&]() {
232 int32_t msgType = mFDP->ConsumeIntegral<int32_t>();
233 mCamera->takePicture(msgType);
234 },
235 [&]() {
236 int32_t cmd;
237 cmd = mFDP->ConsumeBool() ? mFDP->PickValueInArray(kValidCMD)
238 : mFDP->ConsumeIntegral<int32_t>();
239 int32_t arg1 = mFDP->ConsumeIntegral<int32_t>();
240 int32_t arg2 = mFDP->ConsumeIntegral<int32_t>();
241 mCamera->sendCommand(cmd, arg1, arg2);
242 },
243 [&]() {
244 int32_t videoBufferMode =
245 mFDP->ConsumeBool() ? mFDP->PickValueInArray(kValidVideoBufferMode)
246 : mFDP->ConsumeIntegral<int32_t>();
247 mCamera->setVideoBufferMode(videoBufferMode);
248 },
249 [&]() {
250 if (surfaceControl) {
251 mCamera->setVideoTarget(surface->getIGraphicBufferProducer());
252 }
253 },
254 [&]() {
255 cameraListener = sp<TestCameraListener>::make();
256 mCamera->setListener(cameraListener);
257 },
258 [&]() {
259 int32_t previewCallbackFlag;
260 previewCallbackFlag =
261 mFDP->ConsumeBool() ? mFDP->PickValueInArray(kValidPreviewCallbackFlag)
262 : mFDP->ConsumeIntegral<int32_t>();
263 mCamera->setPreviewCallbackFlags(previewCallbackFlag);
264 },
265 [&]() {
266 if (surfaceControl) {
267 mCamera->setPreviewCallbackTarget(surface->getIGraphicBufferProducer());
268 }
269 },
270 [&]() { mCamera->getRecordingProxy(); },
271 [&]() {
272 int32_t mode = mFDP->ConsumeIntegral<int32_t>();
273 mCamera->setAudioRestriction(mode);
274 },
275 [&]() { mCamera->getGlobalAudioRestriction(); },
276 [&]() { mCamera->recordingEnabled(); },
277 [&]() {
278 memoryDealer = new MemoryDealer(kMemoryDealerSize);
279 iMem = memoryDealer->allocate(kMemoryDealerSize);
280 },
281 [&]() {
282 int32_t msgTypeNC = mFDP->ConsumeIntegral<int32_t>();
283 int32_t ext = mFDP->ConsumeIntegral<int32_t>();
284 int32_t ext2 = mFDP->ConsumeIntegral<int32_t>();
285 mCamera->notifyCallback(msgTypeNC, ext, ext2);
286 },
287 [&]() {
288 int32_t msgTypeNC = mFDP->ConsumeIntegral<int32_t>();
289 int64_t timestamp = mFDP->ConsumeIntegral<int64_t>();
290 mCamera->dataCallbackTimestamp(timestamp, msgTypeNC, iMem);
291 },
292 [&]() {
293 int64_t timestamp = mFDP->ConsumeIntegral<int64_t>();
294 int32_t numFds = mFDP->ConsumeIntegralInRange<int32_t>(kNumMin, kNumMax);
295 int32_t numInts = mFDP->ConsumeIntegralInRange<int32_t>(kNumMin, kNumMax);
296 native_handle_t* handle = native_handle_create(numFds, numInts);
297 mCamera->recordingFrameHandleCallbackTimestamp(timestamp, handle);
298 },
299 [&]() {
300 int32_t numFds = mFDP->ConsumeIntegralInRange<int32_t>(kNumMin, kNumMax);
301 int32_t numInts = mFDP->ConsumeIntegralInRange<int32_t>(kNumMin, kNumMax);
302 native_handle_t* handle = native_handle_create(numFds, numInts);
303 mCamera->releaseRecordingFrameHandle(handle);
304 },
305 [&]() { mCamera->releaseRecordingFrame(iMem); },
306 [&]() {
307 std::vector<native_handle_t*> handles;
308 for (int8_t i = 0;
309 i < mFDP->ConsumeIntegralInRange<int8_t>(kMinElements, kMaxElements);
310 ++i) {
311 int32_t numFds = mFDP->ConsumeIntegralInRange<int32_t>(kNumMin, kNumMax);
312 int32_t numInts = mFDP->ConsumeIntegralInRange<int32_t>(kNumMin, kNumMax);
313 native_handle_t* handle = native_handle_create(numFds, numInts);
314 handles.push_back(handle);
315 }
316 mCamera->releaseRecordingFrameHandleBatch(handles);
317 },
318 [&]() {
319 std::vector<native_handle_t*> handles;
320 for (int8_t i = 0;
321 i < mFDP->ConsumeIntegralInRange<int8_t>(kMinElements, kMaxElements);
322 ++i) {
323 int32_t numFds = mFDP->ConsumeIntegralInRange<int32_t>(kNumMin, kNumMax);
324 int32_t numInts = mFDP->ConsumeIntegralInRange<int32_t>(kNumMin, kNumMax);
325 native_handle_t* handle = native_handle_create(numFds, numInts);
326 handles.push_back(handle);
327 }
328 std::vector<nsecs_t> timestamps;
329 for (int8_t i = 0;
330 i < mFDP->ConsumeIntegralInRange<int8_t>(kMinElements, kMaxElements);
331 ++i) {
332 timestamps.push_back(mFDP->ConsumeIntegral<int64_t>());
333 }
334 mCamera->recordingFrameHandleCallbackTimestampBatch(timestamps, handles);
335 },
336 });
337 callCameraAPIs();
Aditya Wazird16f5df2021-07-28 17:57:32 +0530338 }
Aditya Wazird16f5df2021-07-28 17:57:32 +0530339}
340
341void CameraFuzzer::process(const uint8_t* data, size_t size) {
342 mFDP = new FuzzedDataProvider(data, size);
343 invokeCamera();
Aditya Wazird16f5df2021-07-28 17:57:32 +0530344 delete mFDP;
345}
346
347extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
348 sp<CameraFuzzer> cameraFuzzer = new CameraFuzzer();
349 cameraFuzzer->process(data, size);
350 cameraFuzzer.clear();
351 return 0;
352}