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