xref: /aosp_15_r20/system/media/camera/fuzz/libcamera_metadata_fuzzer.cpp (revision b9df5ad1c9ac98a7fefaac271a55f7ae3db05414)
1*b9df5ad1SAndroid Build Coastguard Worker #include <stddef.h>
2*b9df5ad1SAndroid Build Coastguard Worker #include <stdint.h>
3*b9df5ad1SAndroid Build Coastguard Worker 
4*b9df5ad1SAndroid Build Coastguard Worker #include <errno.h>
5*b9df5ad1SAndroid Build Coastguard Worker #include <vector>
6*b9df5ad1SAndroid Build Coastguard Worker 
7*b9df5ad1SAndroid Build Coastguard Worker #include "system/camera_metadata.h"
8*b9df5ad1SAndroid Build Coastguard Worker 
9*b9df5ad1SAndroid Build Coastguard Worker #define OK    0
10*b9df5ad1SAndroid Build Coastguard Worker 
AlignUp(uint32_t num,uint32_t alignment)11*b9df5ad1SAndroid Build Coastguard Worker static inline uint32_t AlignUp(uint32_t num, uint32_t alignment) {
12*b9df5ad1SAndroid Build Coastguard Worker     return (num + (alignment - 1)) & (~(alignment - 1));
13*b9df5ad1SAndroid Build Coastguard Worker }
14*b9df5ad1SAndroid Build Coastguard Worker 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)15*b9df5ad1SAndroid Build Coastguard Worker extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
16*b9df5ad1SAndroid Build Coastguard Worker     const size_t sizeof_int = sizeof(uint32_t);
17*b9df5ad1SAndroid Build Coastguard Worker     if (data == nullptr || size < 2 * sizeof_int) {
18*b9df5ad1SAndroid Build Coastguard Worker         return 0;
19*b9df5ad1SAndroid Build Coastguard Worker     }
20*b9df5ad1SAndroid Build Coastguard Worker     camera_metadata_t *m = NULL;
21*b9df5ad1SAndroid Build Coastguard Worker 
22*b9df5ad1SAndroid Build Coastguard Worker     // Use first int as capacity, and the following one as data capacity.
23*b9df5ad1SAndroid Build Coastguard Worker     uint32_t entry_capacity = *reinterpret_cast<const uint32_t*>(data) % 0xFF;
24*b9df5ad1SAndroid Build Coastguard Worker     uint32_t data_capacity  = *reinterpret_cast<const uint32_t*>(data + sizeof_int) % 0xFFF;
25*b9df5ad1SAndroid Build Coastguard Worker 
26*b9df5ad1SAndroid Build Coastguard Worker     m = allocate_camera_metadata(entry_capacity, data_capacity);
27*b9df5ad1SAndroid Build Coastguard Worker 
28*b9df5ad1SAndroid Build Coastguard Worker     size_t i = 2 * sizeof_int;
29*b9df5ad1SAndroid Build Coastguard Worker     std::vector<uint32_t> tags;
30*b9df5ad1SAndroid Build Coastguard Worker     // Do we have at least 2 ints left?
31*b9df5ad1SAndroid Build Coastguard Worker     while(i + (2 * sizeof_int) < size) {
32*b9df5ad1SAndroid Build Coastguard Worker         // Use one int as tag Id, and the following one as data size.
33*b9df5ad1SAndroid Build Coastguard Worker         // Note that i is already aligned at this point.
34*b9df5ad1SAndroid Build Coastguard Worker         uint32_t tag = *reinterpret_cast<const uint32_t*>(data + i);
35*b9df5ad1SAndroid Build Coastguard Worker         uint32_t data_count = *reinterpret_cast<const uint32_t*>(
36*b9df5ad1SAndroid Build Coastguard Worker             data + i + sizeof_int) % 0xFF;
37*b9df5ad1SAndroid Build Coastguard Worker 
38*b9df5ad1SAndroid Build Coastguard Worker         i += 2 * sizeof_int;
39*b9df5ad1SAndroid Build Coastguard Worker 
40*b9df5ad1SAndroid Build Coastguard Worker         int32_t tag_type = get_camera_metadata_tag_type(tag);
41*b9df5ad1SAndroid Build Coastguard Worker 
42*b9df5ad1SAndroid Build Coastguard Worker         // If the tag doesn't exists, just try to add it anyway to try that path,
43*b9df5ad1SAndroid Build Coastguard Worker         // but skip the rest of the loop.
44*b9df5ad1SAndroid Build Coastguard Worker         if (tag_type == -1) {
45*b9df5ad1SAndroid Build Coastguard Worker             add_camera_metadata_entry(m, tag, data, data_count);
46*b9df5ad1SAndroid Build Coastguard Worker             validate_camera_metadata_structure(m, NULL);
47*b9df5ad1SAndroid Build Coastguard Worker             continue;
48*b9df5ad1SAndroid Build Coastguard Worker         }
49*b9df5ad1SAndroid Build Coastguard Worker 
50*b9df5ad1SAndroid Build Coastguard Worker         size_t tag_data_size = camera_metadata_type_size[tag_type] * data_count;
51*b9df5ad1SAndroid Build Coastguard Worker 
52*b9df5ad1SAndroid Build Coastguard Worker         // Is there enough data left to consider this tag/size pair?
53*b9df5ad1SAndroid Build Coastguard Worker         if (i + tag_data_size >= size) {
54*b9df5ad1SAndroid Build Coastguard Worker             continue;
55*b9df5ad1SAndroid Build Coastguard Worker         }
56*b9df5ad1SAndroid Build Coastguard Worker 
57*b9df5ad1SAndroid Build Coastguard Worker         const void* tag_data = data + i;
58*b9df5ad1SAndroid Build Coastguard Worker         // add then remove
59*b9df5ad1SAndroid Build Coastguard Worker         add_camera_metadata_entry(m, tag, tag_data, data_count);
60*b9df5ad1SAndroid Build Coastguard Worker         validate_camera_metadata_structure(m, NULL);
61*b9df5ad1SAndroid Build Coastguard Worker         camera_metadata_ro_entry_t entry;
62*b9df5ad1SAndroid Build Coastguard Worker         if (OK == find_camera_metadata_ro_entry(m, tag, &entry)) {
63*b9df5ad1SAndroid Build Coastguard Worker             delete_camera_metadata_entry(m, entry.index);
64*b9df5ad1SAndroid Build Coastguard Worker             validate_camera_metadata_structure(m, NULL);
65*b9df5ad1SAndroid Build Coastguard Worker         }
66*b9df5ad1SAndroid Build Coastguard Worker 
67*b9df5ad1SAndroid Build Coastguard Worker         // add back
68*b9df5ad1SAndroid Build Coastguard Worker         add_camera_metadata_entry(m, tag, tag_data, data_count);
69*b9df5ad1SAndroid Build Coastguard Worker         tags.push_back(tag);
70*b9df5ad1SAndroid Build Coastguard Worker 
71*b9df5ad1SAndroid Build Coastguard Worker         get_camera_metadata_section_name(tag);
72*b9df5ad1SAndroid Build Coastguard Worker         get_camera_metadata_tag_name(tag);
73*b9df5ad1SAndroid Build Coastguard Worker         get_camera_metadata_tag_type(tag);
74*b9df5ad1SAndroid Build Coastguard Worker 
75*b9df5ad1SAndroid Build Coastguard Worker         i += AlignUp(tag_data_size, sizeof_int);
76*b9df5ad1SAndroid Build Coastguard Worker     }
77*b9df5ad1SAndroid Build Coastguard Worker 
78*b9df5ad1SAndroid Build Coastguard Worker     for (auto tag: tags){
79*b9df5ad1SAndroid Build Coastguard Worker         camera_metadata_ro_entry_t entry;
80*b9df5ad1SAndroid Build Coastguard Worker         if (OK == find_camera_metadata_ro_entry(m, tag, &entry)) {
81*b9df5ad1SAndroid Build Coastguard Worker             delete_camera_metadata_entry(m, entry.index);
82*b9df5ad1SAndroid Build Coastguard Worker             validate_camera_metadata_structure(m, NULL);
83*b9df5ad1SAndroid Build Coastguard Worker         }
84*b9df5ad1SAndroid Build Coastguard Worker     }
85*b9df5ad1SAndroid Build Coastguard Worker 
86*b9df5ad1SAndroid Build Coastguard Worker     free_camera_metadata(m);
87*b9df5ad1SAndroid Build Coastguard Worker     return 0;
88*b9df5ad1SAndroid Build Coastguard Worker }