#include #include #include #include #include "system/camera_metadata.h" #define OK 0 static inline uint32_t AlignUp(uint32_t num, uint32_t alignment) { return (num + (alignment - 1)) & (~(alignment - 1)); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { const size_t sizeof_int = sizeof(uint32_t); if (data == nullptr || size < 2 * sizeof_int) { return 0; } camera_metadata_t *m = NULL; // Use first int as capacity, and the following one as data capacity. uint32_t entry_capacity = *reinterpret_cast(data) % 0xFF; uint32_t data_capacity = *reinterpret_cast(data + sizeof_int) % 0xFFF; m = allocate_camera_metadata(entry_capacity, data_capacity); size_t i = 2 * sizeof_int; std::vector tags; // Do we have at least 2 ints left? while(i + (2 * sizeof_int) < size) { // Use one int as tag Id, and the following one as data size. // Note that i is already aligned at this point. uint32_t tag = *reinterpret_cast(data + i); uint32_t data_count = *reinterpret_cast( data + i + sizeof_int) % 0xFF; i += 2 * sizeof_int; int32_t tag_type = get_camera_metadata_tag_type(tag); // If the tag doesn't exists, just try to add it anyway to try that path, // but skip the rest of the loop. if (tag_type == -1) { add_camera_metadata_entry(m, tag, data, data_count); validate_camera_metadata_structure(m, NULL); continue; } size_t tag_data_size = camera_metadata_type_size[tag_type] * data_count; // Is there enough data left to consider this tag/size pair? if (i + tag_data_size >= size) { continue; } const void* tag_data = data + i; // add then remove add_camera_metadata_entry(m, tag, tag_data, data_count); validate_camera_metadata_structure(m, NULL); camera_metadata_ro_entry_t entry; if (OK == find_camera_metadata_ro_entry(m, tag, &entry)) { delete_camera_metadata_entry(m, entry.index); validate_camera_metadata_structure(m, NULL); } // add back add_camera_metadata_entry(m, tag, tag_data, data_count); tags.push_back(tag); get_camera_metadata_section_name(tag); get_camera_metadata_tag_name(tag); get_camera_metadata_tag_type(tag); i += AlignUp(tag_data_size, sizeof_int); } for (auto tag: tags){ camera_metadata_ro_entry_t entry; if (OK == find_camera_metadata_ro_entry(m, tag, &entry)) { delete_camera_metadata_entry(m, entry.index); validate_camera_metadata_structure(m, NULL); } } free_camera_metadata(m); return 0; }