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