blob: 9912fbed92d8a3c962de93192359e27073401f6c [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>
Aditya Wazird16f5df2021-07-28 17:57:32 +053019#include <binder/MemoryDealer.h>
20#include <fuzzer/FuzzedDataProvider.h>
Aditya Wazird16f5df2021-07-28 17:57:32 +053021#include <gui/Surface.h>
22#include <gui/SurfaceComposerClient.h>
Aditya Wazird16f5df2021-07-28 17:57:32 +053023#include "camera2common.h"
Aditya Wazird16f5df2021-07-28 17:57:32 +053024
25using namespace std;
26using namespace android;
27using namespace android::hardware;
28
29constexpr int32_t kFrameRateMin = 1;
Kunal Raif57234d2023-11-07 10:19:41 +000030constexpr int32_t kFrameRateMax = 1000;
Aditya Wazird16f5df2021-07-28 17:57:32 +053031constexpr int32_t kNumMin = 0;
32constexpr int32_t kNumMax = 1024;
33constexpr int32_t kMemoryDealerSize = 1000;
Kunal Raif57234d2023-11-07 10:19:41 +000034constexpr int8_t kMinElements = 1;
35constexpr int8_t kMaxElements = 10;
Aditya Wazird16f5df2021-07-28 17:57:32 +053036
37constexpr int32_t kValidCMD[] = {CAMERA_CMD_START_SMOOTH_ZOOM,
38 CAMERA_CMD_STOP_SMOOTH_ZOOM,
39 CAMERA_CMD_SET_DISPLAY_ORIENTATION,
40 CAMERA_CMD_ENABLE_SHUTTER_SOUND,
41 CAMERA_CMD_PLAY_RECORDING_SOUND,
42 CAMERA_CMD_START_FACE_DETECTION,
43 CAMERA_CMD_STOP_FACE_DETECTION,
44 CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG,
45 CAMERA_CMD_PING,
46 CAMERA_CMD_SET_VIDEO_BUFFER_COUNT,
47 CAMERA_CMD_SET_VIDEO_FORMAT};
48
49constexpr int32_t kValidVideoBufferMode[] = {ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV,
50 ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA,
51 ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE};
52
53constexpr int32_t kValidPreviewCallbackFlag[] = {
54 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK, CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK,
55 CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK, CAMERA_FRAME_CALLBACK_FLAG_NOOP,
56 CAMERA_FRAME_CALLBACK_FLAG_CAMCORDER, CAMERA_FRAME_CALLBACK_FLAG_CAMERA,
57 CAMERA_FRAME_CALLBACK_FLAG_BARCODE_SCANNER};
58
Aditya Wazird16f5df2021-07-28 17:57:32 +053059class TestCameraListener : public CameraListener {
60 public:
61 virtual ~TestCameraListener() = default;
62
63 void notify(int32_t /*msgType*/, int32_t /*ext1*/, int32_t /*ext2*/) override { return; };
64 void postData(int32_t /*msgType*/, const sp<IMemory>& /*dataPtr*/,
65 camera_frame_metadata_t* /*metadata*/) override {
66 return;
67 };
68 void postDataTimestamp(nsecs_t /*timestamp*/, int32_t /*msgType*/,
69 const sp<IMemory>& /*dataPtr*/) override {
70 return;
71 };
72 void postRecordingFrameHandleTimestamp(nsecs_t /*timestamp*/,
73 native_handle_t* /*handle*/) override {
74 return;
75 };
76 void postRecordingFrameHandleTimestampBatch(
77 const std::vector<nsecs_t>& /*timestamps*/,
78 const std::vector<native_handle_t*>& /*handles*/) override {
79 return;
80 };
81};
82
83class CameraFuzzer : public ::android::hardware::BnCameraClient {
84 public:
85 void process(const uint8_t* data, size_t size);
Aditya Wazird16f5df2021-07-28 17:57:32 +053086
87 private:
88 bool initCamera();
Aditya Wazird16f5df2021-07-28 17:57:32 +053089 void invokeCamera();
Aditya Wazird16f5df2021-07-28 17:57:32 +053090 void invokeSetParameters();
Aditya Wazir40966bd2024-05-17 15:33:50 +053091 native_handle_t* createNativeHandle();
Aditya Wazird16f5df2021-07-28 17:57:32 +053092 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
Aditya Wazir40966bd2024-05-17 15:33:50 +0530106native_handle_t* CameraFuzzer::createNativeHandle() {
107 int32_t numFds = mFDP->ConsumeIntegralInRange<int32_t>(kMinElements, kMaxElements);
108 int32_t numInts = mFDP->ConsumeIntegralInRange<int32_t>(kNumMin, kNumMax);
109 native_handle_t* handle = native_handle_create(numFds, numInts);
110 for (int32_t i = 0; i < numFds; ++i) {
111 std::string filename = mFDP->ConsumeRandomLengthString(kMaxBytes);
112 int32_t fd = open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC);
113 handle->data[i] = fd;
114 }
115 return handle;
116}
117
Aditya Wazird16f5df2021-07-28 17:57:32 +0530118bool CameraFuzzer::initCamera() {
119 ProcessState::self()->startThreadPool();
120 sp<IServiceManager> sm = defaultServiceManager();
121 sp<IBinder> binder = sm->getService(String16("media.camera"));
Kunal Raif57234d2023-11-07 10:19:41 +0000122 sp<ICameraService> cameraService = nullptr;
123 cameraService = interface_cast<ICameraService>(binder);
124 sp<ICamera> cameraDevice = nullptr;
125 if (mFDP->ConsumeBool()) {
126 cameraService->connect(this, mFDP->ConsumeIntegral<int32_t>() /* cameraId */, "CAMERAFUZZ",
127 hardware::ICameraService::USE_CALLING_UID,
128 hardware::ICameraService::USE_CALLING_PID,
129 /*targetSdkVersion*/ __ANDROID_API_FUTURE__,
130 /*overrideToPortrait*/ false, /*forceSlowJpegMode*/ false,
131 &cameraDevice);
132 } else {
133 cameraService->connect(this, mFDP->ConsumeIntegral<int32_t>() /* cameraId */,
134 mFDP->ConsumeRandomLengthString(kMaxBytes).c_str(),
135 mFDP->ConsumeIntegral<int8_t>() /* clientUid */,
136 mFDP->ConsumeIntegral<int8_t>() /* clientPid */,
137 /*targetSdkVersion*/ mFDP->ConsumeIntegral<int32_t>(),
138 /*overrideToPortrait*/ mFDP->ConsumeBool(),
139 /*forceSlowJpegMode*/ mFDP->ConsumeBool(), &cameraDevice);
140 }
141
Aditya Wazird16f5df2021-07-28 17:57:32 +0530142 mCamera = Camera::create(cameraDevice);
143 if (!mCamera) {
144 return false;
145 }
146 return true;
147}
148
149void CameraFuzzer::invokeSetParameters() {
150 String8 s = mCamera->getParameters();
151 CameraParameters params(s);
152 int32_t width = mFDP->ConsumeIntegral<int32_t>();
153 int32_t height = mFDP->ConsumeIntegral<int32_t>();
154 params.setVideoSize(width, height);
155 int32_t frameRate = mFDP->ConsumeIntegralInRange<int32_t>(kFrameRateMin, kFrameRateMax);
156 params.setPreviewFrameRate(frameRate);
157 mCamera->setParameters(params.flatten());
158}
159
160void CameraFuzzer::invokeCamera() {
161 if (!initCamera()) {
162 return;
163 }
164
Kunal Raif57234d2023-11-07 10:19:41 +0000165 int32_t cameraId = mFDP->ConsumeIntegral<int32_t>();
Aditya Wazird16f5df2021-07-28 17:57:32 +0530166 Camera::getNumberOfCameras();
167 CameraInfo cameraInfo;
168 cameraInfo.facing = mFDP->ConsumeBool() ? mFDP->PickValueInArray(kValidFacing)
Kunal Raif57234d2023-11-07 10:19:41 +0000169 : mFDP->ConsumeIntegral<int32_t>();
Aditya Wazird16f5df2021-07-28 17:57:32 +0530170 cameraInfo.orientation = mFDP->ConsumeBool() ? mFDP->PickValueInArray(kValidOrientation)
Kunal Raif57234d2023-11-07 10:19:41 +0000171 : mFDP->ConsumeIntegral<int32_t>();
Austin Borger18b30a72022-10-27 12:20:29 -0700172 Camera::getCameraInfo(cameraId, /*overrideToPortrait*/false, &cameraInfo);
Aditya Wazird16f5df2021-07-28 17:57:32 +0530173 mCamera->reconnect();
174
Kunal Raif57234d2023-11-07 10:19:41 +0000175 sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
176 sp<SurfaceControl> surfaceControl = nullptr;
Aditya Wazird16f5df2021-07-28 17:57:32 +0530177 if (mFDP->ConsumeBool()) {
Kunal Raif57234d2023-11-07 10:19:41 +0000178 surfaceControl = composerClient->createSurface(String8("FUZZSURFACE"), 1280, 800,
179 HAL_PIXEL_FORMAT_YV12);
Aditya Wazird16f5df2021-07-28 17:57:32 +0530180 } else {
Kunal Raif57234d2023-11-07 10:19:41 +0000181 surfaceControl = composerClient->createSurface(
182 static_cast<String8>(mFDP->ConsumeRandomLengthString(kMaxBytes).c_str()) /* name */,
183 mFDP->ConsumeIntegral<uint32_t>() /* width */,
184 mFDP->ConsumeIntegral<uint32_t>() /* height */,
185 mFDP->ConsumeIntegral<int32_t>() /* format */,
186 mFDP->ConsumeIntegral<int32_t>() /* flags */);
Aditya Wazird16f5df2021-07-28 17:57:32 +0530187 }
Aditya Wazird16f5df2021-07-28 17:57:32 +0530188
189 if (mFDP->ConsumeBool()) {
Kunal Raif57234d2023-11-07 10:19:41 +0000190 invokeSetParameters();
Aditya Wazird16f5df2021-07-28 17:57:32 +0530191 }
Kunal Raif57234d2023-11-07 10:19:41 +0000192 sp<Surface> surface = nullptr;
193 if (surfaceControl) {
194 surface = surfaceControl->getSurface();
Aditya Wazird16f5df2021-07-28 17:57:32 +0530195 }
Kunal Raif57234d2023-11-07 10:19:41 +0000196 sp<MemoryDealer> memoryDealer = nullptr;
197 sp<IMemory> iMem = nullptr;
198 sp<CameraListener> cameraListener = nullptr;
Aditya Wazird16f5df2021-07-28 17:57:32 +0530199
Kunal Raif57234d2023-11-07 10:19:41 +0000200 while (mFDP->remaining_bytes()) {
201 auto callCameraAPIs = mFDP->PickValueInArray<const std::function<void()>>({
202 [&]() {
203 if (surfaceControl) {
204 mCamera->setPreviewTarget(surface->getIGraphicBufferProducer());
205 }
206 },
207 [&]() {
208 if (surfaceControl) {
209 mCamera->startPreview();
210 }
211 },
212 [&]() {
213 if (surfaceControl) {
214 mCamera->stopPreview();
215 }
216 },
217 [&]() {
218 if (surfaceControl) {
219 mCamera->stopPreview();
220 }
221 },
222 [&]() {
223 if (surfaceControl) {
224 mCamera->previewEnabled();
225 }
226 },
227 [&]() {
228 if (surfaceControl) {
229 mCamera->startRecording();
230 }
231 },
232 [&]() {
233 if (surfaceControl) {
234 mCamera->stopRecording();
235 }
236 },
237 [&]() { mCamera->lock(); },
238 [&]() { mCamera->unlock(); },
239 [&]() { mCamera->autoFocus(); },
240 [&]() { mCamera->cancelAutoFocus(); },
241 [&]() {
242 int32_t msgType = mFDP->ConsumeIntegral<int32_t>();
243 mCamera->takePicture(msgType);
244 },
245 [&]() {
246 int32_t cmd;
247 cmd = mFDP->ConsumeBool() ? mFDP->PickValueInArray(kValidCMD)
248 : mFDP->ConsumeIntegral<int32_t>();
249 int32_t arg1 = mFDP->ConsumeIntegral<int32_t>();
250 int32_t arg2 = mFDP->ConsumeIntegral<int32_t>();
251 mCamera->sendCommand(cmd, arg1, arg2);
252 },
253 [&]() {
254 int32_t videoBufferMode =
255 mFDP->ConsumeBool() ? mFDP->PickValueInArray(kValidVideoBufferMode)
256 : mFDP->ConsumeIntegral<int32_t>();
257 mCamera->setVideoBufferMode(videoBufferMode);
258 },
259 [&]() {
260 if (surfaceControl) {
261 mCamera->setVideoTarget(surface->getIGraphicBufferProducer());
262 }
263 },
264 [&]() {
265 cameraListener = sp<TestCameraListener>::make();
266 mCamera->setListener(cameraListener);
267 },
268 [&]() {
269 int32_t previewCallbackFlag;
270 previewCallbackFlag =
271 mFDP->ConsumeBool() ? mFDP->PickValueInArray(kValidPreviewCallbackFlag)
272 : mFDP->ConsumeIntegral<int32_t>();
273 mCamera->setPreviewCallbackFlags(previewCallbackFlag);
274 },
275 [&]() {
276 if (surfaceControl) {
277 mCamera->setPreviewCallbackTarget(surface->getIGraphicBufferProducer());
278 }
279 },
280 [&]() { mCamera->getRecordingProxy(); },
281 [&]() {
282 int32_t mode = mFDP->ConsumeIntegral<int32_t>();
283 mCamera->setAudioRestriction(mode);
284 },
285 [&]() { mCamera->getGlobalAudioRestriction(); },
286 [&]() { mCamera->recordingEnabled(); },
287 [&]() {
288 memoryDealer = new MemoryDealer(kMemoryDealerSize);
289 iMem = memoryDealer->allocate(kMemoryDealerSize);
290 },
291 [&]() {
292 int32_t msgTypeNC = mFDP->ConsumeIntegral<int32_t>();
293 int32_t ext = mFDP->ConsumeIntegral<int32_t>();
294 int32_t ext2 = mFDP->ConsumeIntegral<int32_t>();
295 mCamera->notifyCallback(msgTypeNC, ext, ext2);
296 },
297 [&]() {
298 int32_t msgTypeNC = mFDP->ConsumeIntegral<int32_t>();
299 int64_t timestamp = mFDP->ConsumeIntegral<int64_t>();
300 mCamera->dataCallbackTimestamp(timestamp, msgTypeNC, iMem);
301 },
302 [&]() {
303 int64_t timestamp = mFDP->ConsumeIntegral<int64_t>();
Aditya Wazir40966bd2024-05-17 15:33:50 +0530304 native_handle_t* handle = createNativeHandle();
Kunal Raif57234d2023-11-07 10:19:41 +0000305 mCamera->recordingFrameHandleCallbackTimestamp(timestamp, handle);
306 },
307 [&]() {
Aditya Wazir40966bd2024-05-17 15:33:50 +0530308 native_handle_t* handle = createNativeHandle();
Kunal Raif57234d2023-11-07 10:19:41 +0000309 mCamera->releaseRecordingFrameHandle(handle);
310 },
311 [&]() { mCamera->releaseRecordingFrame(iMem); },
312 [&]() {
313 std::vector<native_handle_t*> handles;
314 for (int8_t i = 0;
315 i < mFDP->ConsumeIntegralInRange<int8_t>(kMinElements, kMaxElements);
316 ++i) {
Aditya Wazir40966bd2024-05-17 15:33:50 +0530317 native_handle_t* handle = createNativeHandle();
Kunal Raif57234d2023-11-07 10:19:41 +0000318 handles.push_back(handle);
319 }
320 mCamera->releaseRecordingFrameHandleBatch(handles);
321 },
322 [&]() {
323 std::vector<native_handle_t*> handles;
324 for (int8_t i = 0;
325 i < mFDP->ConsumeIntegralInRange<int8_t>(kMinElements, kMaxElements);
326 ++i) {
Aditya Wazir40966bd2024-05-17 15:33:50 +0530327 native_handle_t* handle = createNativeHandle();
Kunal Raif57234d2023-11-07 10:19:41 +0000328 handles.push_back(handle);
329 }
330 std::vector<nsecs_t> timestamps;
331 for (int8_t i = 0;
332 i < mFDP->ConsumeIntegralInRange<int8_t>(kMinElements, kMaxElements);
333 ++i) {
334 timestamps.push_back(mFDP->ConsumeIntegral<int64_t>());
335 }
336 mCamera->recordingFrameHandleCallbackTimestampBatch(timestamps, handles);
337 },
338 });
339 callCameraAPIs();
Aditya Wazird16f5df2021-07-28 17:57:32 +0530340 }
Aditya Wazird16f5df2021-07-28 17:57:32 +0530341}
342
343void CameraFuzzer::process(const uint8_t* data, size_t size) {
344 mFDP = new FuzzedDataProvider(data, size);
345 invokeCamera();
Aditya Wazird16f5df2021-07-28 17:57:32 +0530346 delete mFDP;
347}
348
349extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
350 sp<CameraFuzzer> cameraFuzzer = new CameraFuzzer();
351 cameraFuzzer->process(data, size);
352 cameraFuzzer.clear();
353 return 0;
354}