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