xref: /aosp_15_r20/frameworks/av/camera/tests/fuzzer/camera_fuzzer.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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