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 "camera2common.h"
19
20 using namespace std;
21 using namespace android;
22 using namespace android::hardware;
23
24 constexpr int32_t kSizeMin = 0;
25 constexpr int32_t kSizeMax = 1000;
26 constexpr int32_t kMinMetadataCapacity = 0;
27 constexpr int32_t kMaxMetadataCapacity = 1000;
28 constexpr int32_t kRangeMin = 0;
29 constexpr int32_t kRangeMax = 1000;
30
31 class CameraMetadataFuzzer {
32 public:
33 void process(const uint8_t* data, size_t size);
34
35 private:
36 void initCameraMetadata();
37 void invokeCameraMetadata();
38 CameraMetadata* mCameraMetadata = nullptr;
39 FuzzedDataProvider* mFDP = nullptr;
40 camera_metadata* mMetaBuffer = nullptr;
41 bool mMetadataLocked = false;
42 template <typename T>
callCameraMetadataUpdate(size_t dataCount,T data)43 void callCameraMetadataUpdate(size_t dataCount, T data) {
44 uint32_t tag = mFDP->ConsumeIntegral<uint32_t>();
45 mCameraMetadata->update(tag, &data, dataCount);
46 }
47 };
48
initCameraMetadata()49 void CameraMetadataFuzzer::initCameraMetadata() {
50 auto selectMetadataConstructor = mFDP->PickValueInArray<const std::function<void()>>({
51 [&]() {
52 mMetaBuffer = allocate_camera_metadata(
53 mFDP->ConsumeIntegralInRange<size_t>(
54 kMinMetadataCapacity, kMaxMetadataCapacity) /* entry_capacity */,
55 mFDP->ConsumeIntegralInRange<size_t>(
56 kMinMetadataCapacity, kMaxMetadataCapacity) /* data_capacity */);
57 mCameraMetadata = new CameraMetadata(mMetaBuffer);
58 },
59 [&]() {
60 mCameraMetadata = new CameraMetadata();
61 },
62 [&]() {
63 size_t entryCapacity = mFDP->ConsumeIntegralInRange<size_t>(kSizeMin, kSizeMax);
64 size_t dataCapacity = mFDP->ConsumeIntegralInRange<size_t>(kSizeMin, kSizeMax);
65 mCameraMetadata = new CameraMetadata(entryCapacity, dataCapacity);
66 },
67 });
68 selectMetadataConstructor();
69 }
invokeCameraMetadata()70 void CameraMetadataFuzzer::invokeCameraMetadata() {
71 initCameraMetadata();
72
73 const camera_metadata_t* metadataBuffer = nullptr;
74 mMetadataLocked = mFDP->ConsumeBool();
75 if (mMetadataLocked) {
76 metadataBuffer = mCameraMetadata->getAndLock();
77 }
78
79 size_t dataCount = 1;
80 while (mFDP->remaining_bytes()) {
81 auto callMetadataAPIs = mFDP->PickValueInArray<const std::function<void()>>({
82
83 [&]() { mCameraMetadata->entryCount(); },
84 [&]() { mCameraMetadata->isEmpty(); },
85 [&]() { mCameraMetadata->bufferSize(); },
86 [&]() { mCameraMetadata->sort(); },
87 [&]() {
88 uint8_t dataUint8 = mFDP->ConsumeIntegral<uint8_t>();
89 callCameraMetadataUpdate(dataCount, dataUint8);
90 },
91 [&]() {
92 int32_t dataInt32 = mFDP->ConsumeIntegral<int32_t>();
93 callCameraMetadataUpdate(dataCount, dataInt32);
94 },
95 [&]() {
96 int64_t dataInt64 = mFDP->ConsumeIntegral<int64_t>();
97 callCameraMetadataUpdate(dataCount, dataInt64);
98 },
99 [&]() {
100 float dataFloat = mFDP->ConsumeFloatingPoint<float>();
101 callCameraMetadataUpdate(dataCount, dataFloat);
102 },
103 [&]() {
104 double dataDouble = mFDP->ConsumeFloatingPoint<double>();
105 callCameraMetadataUpdate(dataCount, dataDouble);
106 },
107 [&]() {
108 camera_metadata_rational dataRational;
109 dataRational.numerator = mFDP->ConsumeIntegral<int32_t>();
110 dataRational.denominator = mFDP->ConsumeIntegral<int32_t>();
111 callCameraMetadataUpdate(dataCount, dataRational);
112 },
113 [&]() {
114 uint32_t tag = mFDP->ConsumeIntegral<uint32_t>();
115 string dataStr = mFDP->ConsumeRandomLengthString(kMaxBytes);
116 String8 dataString(dataStr.c_str());
117 mCameraMetadata->update(tag, dataString);
118 },
119 [&]() {
120 uint32_t tag = mFDP->ConsumeIntegral<uint32_t>();
121 uint32_t tagExists =
122 mFDP->ConsumeBool() ? tag : mFDP->ConsumeIntegral<uint32_t>();
123 mCameraMetadata->exists(tagExists);
124 },
125 [&]() {
126 uint32_t tag = mFDP->ConsumeIntegral<uint32_t>();
127 uint32_t tagFind =
128 mFDP->ConsumeBool() ? tag : mFDP->ConsumeIntegral<uint32_t>();
129 mCameraMetadata->find(tagFind);
130 },
131 [&]() {
132 uint32_t tag = mFDP->ConsumeIntegral<uint32_t>();
133 uint32_t tagErase =
134 mFDP->ConsumeBool() ? tag : mFDP->ConsumeIntegral<uint32_t>();
135 mCameraMetadata->erase(tagErase);
136 },
137 [&]() { mCameraMetadata->unlock(metadataBuffer); },
138 [&]() {
139 std::vector<int32_t> tagsRemoved;
140 uint64_t vendorId = mFDP->ConsumeIntegral<uint64_t>();
141 mCameraMetadata->removePermissionEntries(vendorId, &tagsRemoved);
142 },
143 [&]() {
144 string name = mFDP->ConsumeRandomLengthString(kMaxBytes);
145 VendorTagDescriptor vTags;
146 uint32_t tagName = mFDP->ConsumeIntegral<uint32_t>();
147 mCameraMetadata->getTagFromName(name.c_str(), &vTags, &tagName);
148 },
149 [&]() {
150 int32_t fd = open("/dev/null", O_CLOEXEC | O_RDWR | O_CREAT);
151 int32_t verbosity = mFDP->ConsumeIntegralInRange<int32_t>(kRangeMin, kRangeMax);
152 int32_t indentation =
153 mFDP->ConsumeIntegralInRange<int32_t>(kRangeMin, kRangeMax);
154 mCameraMetadata->dump(fd, verbosity, indentation);
155 close(fd);
156 },
157 [&]() { CameraMetadata metadataCopy(mCameraMetadata->release()); },
158 [&]() {
159 if (mFDP->ConsumeBool()) {
160 CameraMetadata otherCameraMetadata;
161 mCameraMetadata->swap(otherCameraMetadata);
162 } else {
163 std::vector<int8_t> entryCapacityVector =
164 mFDP->ConsumeBytes<int8_t>(kMaxBytes);
165 /**
166 * Resizing vector to a size between 1 to 1000 so that vector is not empty.
167 */
168 entryCapacityVector.resize(0, mFDP->ConsumeIntegralInRange<int32_t>(
169 kMinCapacity, kMaxCapacity));
170 CameraMetadata otherCameraMetadata(entryCapacityVector.size());
171 mCameraMetadata->swap(otherCameraMetadata);
172 }
173 },
174 [&]() {
175 if (!mMetadataLocked) {
176 camera_metadata* metaBuffer = allocate_camera_metadata(
177 mFDP->ConsumeIntegralInRange<size_t>(
178 kMinMetadataCapacity,
179 kMaxMetadataCapacity) /* entry_capacity */,
180 mFDP->ConsumeIntegralInRange<size_t>(
181 kMinMetadataCapacity,
182 kMaxMetadataCapacity) /* data_capacity */);
183 mCameraMetadata->acquire(metaBuffer);
184 }
185 },
186 [&]() {
187 if (!mMetadataLocked) {
188 camera_metadata* metaBuffer = allocate_camera_metadata(
189 mFDP->ConsumeIntegralInRange<size_t>(
190 kMinMetadataCapacity,
191 kMaxMetadataCapacity) /* entry_capacity */,
192 mFDP->ConsumeIntegralInRange<size_t>(
193 kMinMetadataCapacity,
194 kMaxMetadataCapacity) /* data_capacity */);
195 mCameraMetadata->append(metaBuffer);
196 free_camera_metadata(metaBuffer);
197 }
198 },
199 });
200 callMetadataAPIs();
201
202 // Not keeping invokeReadWrite() APIs in while loop to avoid possible OOM.
203 invokeReadWriteNullParcel<CameraMetadata>(mCameraMetadata);
204 if (mFDP->ConsumeBool()) {
205 invokeReadWriteParcel<CameraMetadata>(mCameraMetadata);
206 } else {
207 invokeNewReadWriteParcel<CameraMetadata>(mCameraMetadata, *mFDP);
208 }
209 }
210 delete mCameraMetadata;
211 }
212
process(const uint8_t * data,size_t size)213 void CameraMetadataFuzzer::process(const uint8_t* data, size_t size) {
214 mFDP = new FuzzedDataProvider(data, size);
215 invokeCameraMetadata();
216 delete mFDP;
217 }
218
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)219 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
220 CameraMetadataFuzzer cameraMetadataFuzzer;
221 cameraMetadataFuzzer.process(data, size);
222 return 0;
223 }
224