1 /*
2  * Copyright (C) 2023 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 <CameraBase.h>
18 #include <CameraUtils.h>
19 #include "camera2common.h"
20 
21 using namespace std;
22 using namespace android;
23 using namespace android::hardware;
24 
25 constexpr int8_t kMaxLoopIterations = 20;
26 constexpr int32_t kSizeMin = 0;
27 constexpr int32_t kSizeMax = 1000;
28 
29 class CameraUtilsFuzzer {
30   public:
31     void process(const uint8_t* data, size_t size);
32 
33   private:
34     void invokeCameraUtils();
35     void invokeCameraBase();
36     FuzzedDataProvider* mFDP = nullptr;
37 };
38 
invokeCameraUtils()39 void CameraUtilsFuzzer::invokeCameraUtils() {
40     int8_t count = kMaxLoopIterations;
41     while (--count > 0) {
42         int32_t transform = 0;
43         auto callCameraUtilsAPIs = mFDP->PickValueInArray<const std::function<void()>>({
44                 [&]() {
45                     CameraMetadata staticMetadata;
46                     if (mFDP->ConsumeBool()) {
47                         int32_t orientVal = mFDP->ConsumeBool()
48                                                     ? mFDP->PickValueInArray(kValidOrientation)
49                                                     : mFDP->ConsumeIntegral<int32_t>();
50                         uint8_t facingVal = mFDP->ConsumeBool()
51                                                     ? mFDP->PickValueInArray(kValidFacing)
52                                                     : mFDP->ConsumeIntegral<uint8_t>();
53                         staticMetadata.update(ANDROID_SENSOR_ORIENTATION, &orientVal, 1);
54                         staticMetadata.update(ANDROID_LENS_FACING, &facingVal, 1);
55                     } else {
56                         std::vector<int32_t> orientVal;
57                         for (int8_t i = 0;
58                              i <= mFDP->ConsumeIntegralInRange<int32_t>(kMinCapacity, kMaxCapacity);
59                              ++i) {
60                             orientVal.push_back(mFDP->ConsumeIntegral<int32_t>());
61                         }
62                         std::vector<uint8_t> facingVal = mFDP->ConsumeBytes<uint8_t>(kMaxBytes);
63                         /**
64                          * Resizing vector to a size between 1 to 1000 so that vector is not empty.
65                          */
66                         orientVal.resize(0, mFDP->ConsumeIntegralInRange<int32_t>(kMinCapacity,
67                                                                                   kMaxCapacity));
68                         facingVal.resize(0, mFDP->ConsumeIntegralInRange<int32_t>(kMinCapacity,
69                                                                                   kMaxCapacity));
70                         staticMetadata.update(ANDROID_SENSOR_ORIENTATION, orientVal.data(),
71                                               orientVal.size());
72                         staticMetadata.update(ANDROID_LENS_FACING, facingVal.data(),
73                                               facingVal.size());
74                     }
75 
76                     CameraUtils::getRotationTransform(
77                             staticMetadata, mFDP->ConsumeIntegral<int32_t>() /* mirrorMode */,
78                             &transform /*out*/);
79                 },
80                 [&]() { CameraUtils::isCameraServiceDisabled(); },
81         });
82         callCameraUtilsAPIs();
83     }
84 }
85 
invokeCameraBase()86 void CameraUtilsFuzzer::invokeCameraBase() {
87     int8_t count = kMaxLoopIterations;
88     while (--count > 0) {
89         CameraInfo cameraInfo;
90         cameraInfo.facing = mFDP->ConsumeBool() ? mFDP->PickValueInArray(kValidFacing)
91                                                 : mFDP->ConsumeIntegral<int>();
92         cameraInfo.orientation = mFDP->ConsumeBool() ? mFDP->PickValueInArray(kValidOrientation)
93                                                      : mFDP->ConsumeIntegral<int>();
94         if (mFDP->ConsumeBool()) {
95             invokeReadWriteParcel<CameraInfo>(&cameraInfo);
96         } else {
97             invokeNewReadWriteParcel<CameraInfo>(&cameraInfo, *mFDP);
98         }
99 
100         CameraStatus* cameraStatus = nullptr;
101 
102         if (mFDP->ConsumeBool()) {
103             cameraStatus = new CameraStatus();
104         } else {
105             string id = mFDP->ConsumeRandomLengthString(kMaxBytes);
106             int32_t status = mFDP->ConsumeIntegral<int32_t>();
107             size_t unavailSubIdsSize = mFDP->ConsumeIntegralInRange<size_t>(kSizeMin, kSizeMax);
108             vector<string> unavailSubIds;
109             for (size_t idx = 0; idx < unavailSubIdsSize; ++idx) {
110                 string unavailSubId = mFDP->ConsumeRandomLengthString(kMaxBytes);
111                 unavailSubIds.push_back(unavailSubId);
112             }
113             string clientPackage = mFDP->ConsumeRandomLengthString(kMaxBytes);
114 
115             cameraStatus = new CameraStatus(id, status, unavailSubIds, clientPackage,
116                                             kDefaultDeviceId);
117         }
118 
119         if (mFDP->ConsumeBool()) {
120             invokeReadWriteParcel<CameraStatus>(cameraStatus);
121         } else {
122             invokeNewReadWriteParcel<CameraStatus>(cameraStatus, *mFDP);
123         }
124         delete cameraStatus;
125     }
126 }
127 
process(const uint8_t * data,size_t size)128 void CameraUtilsFuzzer::process(const uint8_t* data, size_t size) {
129     mFDP = new FuzzedDataProvider(data, size);
130     if (mFDP->ConsumeBool()) {
131         invokeCameraUtils();
132     } else {
133         invokeCameraBase();
134     }
135     delete mFDP;
136 }
137 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)138 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
139     CameraUtilsFuzzer cameraUtilsFuzzer;
140     cameraUtilsFuzzer.process(data, size);
141     return 0;
142 }
143