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