1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "camera.h"
17 #include "camera_metadata_operator.h"
18 #include "metadata_utils.h"
19
20 using namespace OHOS::Camera;
21 namespace OHOS {
22 const size_t THRESHOLD = 12;
23
24 enum BitOperat {
25 INDEX_0 = 0,
26 INDEX_1,
27 INDEX_2,
28 INDEX_3,
29 OFFSET,
30 MOVE_EIGHT_BITS = 8,
31 MOVE_SIXTEEN_BITS = 16,
32 DATA_TYPE_OFFSET = 20,
33 MOVE_TWENTY_FOUR_BITS = 24,
34 META_HEADER_SIZE = 28,
35 };
ConvertUint32(const uint8_t * bitOperat)36 static uint32_t ConvertUint32(const uint8_t *bitOperat)
37 {
38 if (bitOperat == nullptr) {
39 return 0;
40 }
41
42 return (bitOperat[INDEX_0] << MOVE_TWENTY_FOUR_BITS) | (bitOperat[INDEX_1] << MOVE_SIXTEEN_BITS) |
43 (bitOperat[INDEX_2] << MOVE_EIGHT_BITS) | (bitOperat[INDEX_3]);
44 }
45
GetMinInputSize(const uint8_t * rawData)46 uint32_t GetMinInputSize(const uint8_t *rawData)
47 {
48 uint32_t dataType = ConvertUint32(rawData + DATA_TYPE_OFFSET);
49 uint32_t dataSize;
50 switch (dataType) {
51 case META_TYPE_BYTE:
52 dataSize = sizeof(uint8_t);
53 break;
54 case META_TYPE_INT32:
55 dataSize = sizeof(int32_t);
56 break;
57 case META_TYPE_UINT32:
58 dataSize = sizeof(uint32_t);
59 break;
60 case META_TYPE_FLOAT:
61 dataSize = sizeof(float);
62 break;
63 case META_TYPE_INT64:
64 dataSize = sizeof(int64_t);
65 break;
66 case META_TYPE_DOUBLE:
67 dataSize = sizeof(double);
68 break;
69 case META_TYPE_RATIONAL:
70 dataSize = sizeof(camera_rational_t);
71 break;
72 default:
73 dataSize = 0;
74 break;
75 }
76 uint32_t dataCount = ConvertUint32(rawData + MOVE_TWENTY_FOUR_BITS);
77 uint32_t maxValue = std::numeric_limits<uint32_t>::max();
78 if (dataSize == 0 || dataCount == 0 || dataCount > (maxValue - META_HEADER_SIZE)/dataSize) {
79 return 0;
80 }
81 return (META_HEADER_SIZE + dataSize * dataCount);
82 }
83
GetMetadataHeader(const uint8_t * rawData,size_t size,common_metadata_header_t * meta)84 void GetMetadataHeader(const uint8_t *rawData, size_t size, common_metadata_header_t* meta)
85 {
86 uint32_t minInputSize = GetMinInputSize(rawData);
87 if (size < minInputSize || minInputSize == 0) {
88 return;
89 }
90 std::shared_ptr<CameraMetadata> metadata
91 = std::make_shared<CameraMetadata>(MAX_ITEM_CAPACITY, MAX_ITEM_CAPACITY);
92 std::vector<uint8_t> cameraAbility(rawData, rawData + size);
93 MetadataUtils::ConvertVecToMetadata(cameraAbility, metadata);
94 meta = metadata->get();
95 }
96
FuncAllocateCameraMetadataBuffer(const uint8_t * rawData,size_t size)97 void FuncAllocateCameraMetadataBuffer(const uint8_t *rawData, size_t size)
98 {
99 common_metadata_header_t *meta = AllocateCameraMetadataBuffer(ConvertUint32(rawData),
100 ConvertUint32(rawData + OFFSET));
101
102 if (meta != nullptr) {
103 FreeCameraMetadataBuffer(meta);
104 }
105 }
106
FuncIsCameraMetadataItemExist(const uint8_t * rawData,size_t size)107 void FuncIsCameraMetadataItemExist(const uint8_t *rawData, size_t size)
108 {
109 common_metadata_header_t *meta = nullptr;
110 GetMetadataHeader(rawData, size, meta);
111 if (meta == nullptr) {
112 return;
113 }
114
115 IsCameraMetadataItemExist(meta, ConvertUint32(rawData + MOVE_EIGHT_BITS));
116 }
117
FuncFindCameraMetadataItem(const uint8_t * rawData,size_t size)118 void FuncFindCameraMetadataItem(const uint8_t *rawData, size_t size)
119 {
120 common_metadata_header_t *meta = nullptr;
121 GetMetadataHeader(rawData, size, meta);
122 if (meta == nullptr) {
123 return;
124 }
125
126 camera_metadata_item_t entry;
127 FindCameraMetadataItem(meta, ConvertUint32(rawData + MOVE_EIGHT_BITS), &entry);
128 }
129
FuncFindCameraMetadataItemIndex(const uint8_t * rawData,size_t size)130 void FuncFindCameraMetadataItemIndex(const uint8_t *rawData, size_t size)
131 {
132 common_metadata_header_t *meta = nullptr;
133 GetMetadataHeader(rawData, size, meta);
134 if (meta == nullptr) {
135 return;
136 }
137
138 uint32_t index = 0;
139 FindCameraMetadataItemIndex(meta, ConvertUint32(rawData + MOVE_EIGHT_BITS), &index);
140 }
141
FuncGetCameraMetadataItemName(const uint8_t * rawData,size_t size)142 void FuncGetCameraMetadataItemName(const uint8_t *rawData, size_t size)
143 {
144 GetCameraMetadataItemName(ConvertUint32(rawData));
145 }
146
FuncAddCameraMetadataItem(const uint8_t * rawData,size_t size)147 void FuncAddCameraMetadataItem(const uint8_t *rawData, size_t size)
148 {
149 common_metadata_header_t *meta = nullptr;
150 GetMetadataHeader(rawData, size, meta);
151 if (meta == nullptr) {
152 return;
153 }
154 camera_metadata_item_t entry;
155 FindCameraMetadataItem(meta, ConvertUint32(rawData), &entry);
156
157 std::shared_ptr<CameraMetadata> metadata1
158 = std::make_shared<CameraMetadata>(MAX_ITEM_CAPACITY, MAX_ITEM_CAPACITY);
159 common_metadata_header_t *meta1 = metadata1->get();
160 AddCameraMetadataItem(meta1, entry.item, rawData, entry.count);
161 }
162
FuncDeleteCameraMetadataItem(const uint8_t * rawData,size_t size)163 void FuncDeleteCameraMetadataItem(const uint8_t *rawData, size_t size)
164 {
165 common_metadata_header_t *meta = nullptr;
166 GetMetadataHeader(rawData, size, meta);
167 if (meta == nullptr) {
168 return;
169 }
170
171 DeleteCameraMetadataItem(meta, ConvertUint32(rawData + MOVE_EIGHT_BITS));
172 }
173
FuncFreeCameraMetadataBuffer(const uint8_t * rawData,size_t size)174 void FuncFreeCameraMetadataBuffer(const uint8_t *rawData, size_t size)
175 {
176 common_metadata_header_t *meta = AllocateCameraMetadataBuffer(ConvertUint32(rawData),
177 ConvertUint32(rawData + OFFSET));
178 if (meta == nullptr) {
179 return;
180 }
181
182 FreeCameraMetadataBuffer(meta);
183 }
184
FuncFormatCameraMetadataToString(const uint8_t * rawData,size_t size)185 void FuncFormatCameraMetadataToString(const uint8_t *rawData, size_t size)
186 {
187 common_metadata_header_t *meta = nullptr;
188 GetMetadataHeader(rawData, size, meta);
189 if (meta == nullptr) {
190 return;
191 }
192
193 FormatCameraMetadataToString(meta);
194 }
195
FuncGetMetadataItems(const uint8_t * rawData,size_t size)196 void FuncGetMetadataItems(const uint8_t *rawData, size_t size)
197 {
198 common_metadata_header_t *meta = nullptr;
199 GetMetadataHeader(rawData, size, meta);
200 if (meta == nullptr) {
201 return;
202 }
203
204 GetMetadataItems(meta);
205 }
206
FuncGetMetadataData(const uint8_t * rawData,size_t size)207 void FuncGetMetadataData(const uint8_t *rawData, size_t size)
208 {
209 common_metadata_header_t *meta = nullptr;
210 GetMetadataHeader(rawData, size, meta);
211 if (meta == nullptr) {
212 return;
213 }
214
215 GetMetadataData(meta);
216 }
217
FuncGetCameraMetadataItem(const uint8_t * rawData,size_t size)218 void FuncGetCameraMetadataItem(const uint8_t *rawData, size_t size)
219 {
220 common_metadata_header_t *meta = nullptr;
221 GetMetadataHeader(rawData, size, meta);
222 if (meta == nullptr) {
223 return;
224 }
225
226 camera_metadata_item_t item;
227 GetCameraMetadataItem(meta, ConvertUint32(rawData), &item);
228 }
229
FuncGetCameraMetadataItemCount(const uint8_t * rawData,size_t size)230 void FuncGetCameraMetadataItemCount(const uint8_t *rawData, size_t size)
231 {
232 common_metadata_header_t *meta = nullptr;
233 GetMetadataHeader(rawData, size, meta);
234 if (meta == nullptr) {
235 return;
236 }
237
238 GetCameraMetadataItemCount(meta);
239 }
240
FuncGetCameraMetadataItemCapacity(const uint8_t * rawData,size_t size)241 void FuncGetCameraMetadataItemCapacity(const uint8_t *rawData, size_t size)
242 {
243 common_metadata_header_t *meta = nullptr;
244 GetMetadataHeader(rawData, size, meta);
245 if (meta == nullptr) {
246 return;
247 }
248
249 GetCameraMetadataItemCapacity(meta);
250 }
251
FuncGetCameraMetadataDataSize(const uint8_t * rawData,size_t size)252 void FuncGetCameraMetadataDataSize(const uint8_t *rawData, size_t size)
253 {
254 common_metadata_header_t *meta = nullptr;
255 GetMetadataHeader(rawData, size, meta);
256 if (meta == nullptr) {
257 return;
258 }
259
260 GetCameraMetadataDataSize(meta);
261 }
262
FuncCopyCameraMetadataItems(const uint8_t * rawData,size_t size)263 void FuncCopyCameraMetadataItems(const uint8_t *rawData, size_t size)
264 {
265 common_metadata_header_t *oldmeta = nullptr;
266 GetMetadataHeader(rawData, size, oldmeta);
267 if (oldmeta == nullptr) {
268 return;
269 }
270
271 common_metadata_header_t *newmeta = AllocateCameraMetadataBuffer(MAX_ITEM_CAPACITY, MAX_ITEM_CAPACITY);
272 if (newmeta == nullptr) {
273 return;
274 }
275 CopyCameraMetadataItems(newmeta, oldmeta);
276 }
277
FuncCalculateCameraMetadataItemDataSize(const uint8_t * rawData,size_t size)278 void FuncCalculateCameraMetadataItemDataSize(const uint8_t *rawData, size_t size)
279 {
280 CalculateCameraMetadataItemDataSize(ConvertUint32(rawData), static_cast<size_t>(ConvertUint32(rawData + OFFSET)));
281 }
282
283 typedef void (*TestFuncDef)(const uint8_t *rawData, size_t size);
284 static TestFuncDef g_allTestFunc[] = {
285 FuncAllocateCameraMetadataBuffer,
286 FuncIsCameraMetadataItemExist,
287 FuncFindCameraMetadataItem,
288 FuncFindCameraMetadataItemIndex,
289 FuncGetCameraMetadataItemName,
290 FuncAddCameraMetadataItem,
291 FuncDeleteCameraMetadataItem,
292 FuncFreeCameraMetadataBuffer,
293 FuncFormatCameraMetadataToString,
294 FuncGetMetadataItems,
295 FuncGetMetadataData,
296 FuncGetCameraMetadataItem,
297 FuncGetCameraMetadataItemCount,
298 FuncGetCameraMetadataItemCapacity,
299 FuncGetCameraMetadataDataSize,
300 FuncCopyCameraMetadataItems,
301 FuncCalculateCameraMetadataItemDataSize,
302 };
303
304
TestFuncSwitch(uint32_t cmd,const uint8_t * rawData,size_t size)305 static void TestFuncSwitch(uint32_t cmd, const uint8_t *rawData, size_t size)
306 {
307 int testCount = sizeof(g_allTestFunc) / sizeof(g_allTestFunc[0]);
308 TestFuncDef curFunc = g_allTestFunc[cmd % testCount];
309 curFunc(rawData, size);
310 }
311
DoSomethingInterestingWithMyApi(const uint8_t * rawData,size_t size)312 bool DoSomethingInterestingWithMyApi(const uint8_t *rawData, size_t size)
313 {
314 if (rawData == nullptr) {
315 return false;
316 }
317
318 uint32_t cmd = ConvertUint32(rawData);
319 rawData += sizeof(cmd);
320
321 TestFuncSwitch(cmd, rawData, size);
322 return true;
323 }
324
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)325 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
326 {
327 if (size < OHOS::THRESHOLD) {
328 CAMERA_LOGW("Fuzz test input is invalid. The size is smaller than %{public}zu", OHOS::THRESHOLD);
329 return 0;
330 }
331
332 OHOS::DoSomethingInterestingWithMyApi(data, size);
333 return 0;
334 }
335 } // namespace OHOS