1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include "metadata_fuzzer.h" 17094332d3Sopenharmony_ci 18094332d3Sopenharmony_ci#include <cstddef> 19094332d3Sopenharmony_ci#include <cstdint> 20094332d3Sopenharmony_ci#include <securec.h> 21094332d3Sopenharmony_ci#include "hdf_base.h" 22094332d3Sopenharmony_ci#include "display_common_fuzzer.h" 23094332d3Sopenharmony_cinamespace OHOS { 24094332d3Sopenharmony_ciusing namespace OHOS::HDI::Display::Buffer::V1_1; 25094332d3Sopenharmony_ciusing namespace OHOS::HDI::Display::Composer::V1_0; 26094332d3Sopenharmony_cistatic std::shared_ptr<OHOS::HDI::Display::Buffer::V1_1::IDisplayBuffer> g_bufferInterface = nullptr; 27094332d3Sopenharmony_ci 28094332d3Sopenharmony_cistatic bool g_isInit = false; 29094332d3Sopenharmony_cistatic const uint8_t* g_data = nullptr; 30094332d3Sopenharmony_cistatic size_t g_dataSize = 0; 31094332d3Sopenharmony_cistatic size_t g_pos; 32094332d3Sopenharmony_cistatic int32_t g_maxVectorLen = 2880; // max size of value vector 33094332d3Sopenharmony_ci/* 34094332d3Sopenharmony_ci* describe: get data from outside untrusted data(g_data) which size is according to sizeof(T) 35094332d3Sopenharmony_ci* tips: only support basic type 36094332d3Sopenharmony_ci*/ 37094332d3Sopenharmony_citemplate<class T> 38094332d3Sopenharmony_ciT GetData() 39094332d3Sopenharmony_ci{ 40094332d3Sopenharmony_ci T object {}; 41094332d3Sopenharmony_ci size_t objectSize = sizeof(object); 42094332d3Sopenharmony_ci if (g_data == nullptr || objectSize > g_dataSize - g_pos) { 43094332d3Sopenharmony_ci return object; 44094332d3Sopenharmony_ci } 45094332d3Sopenharmony_ci errno_t ret = memcpy_s(&object, objectSize, g_data + g_pos, objectSize); 46094332d3Sopenharmony_ci if (ret != EOK) { 47094332d3Sopenharmony_ci return {}; 48094332d3Sopenharmony_ci } 49094332d3Sopenharmony_ci g_pos += objectSize; 50094332d3Sopenharmony_ci return object; 51094332d3Sopenharmony_ci} 52094332d3Sopenharmony_ci 53094332d3Sopenharmony_cistatic int32_t GetAllocInfo(OHOS::HDI::Display::Buffer::V1_0::AllocInfo& info) 54094332d3Sopenharmony_ci{ 55094332d3Sopenharmony_ci uint32_t lenUsage = GetArrLength(CONVERT_TABLE_USAGE); 56094332d3Sopenharmony_ci if (lenUsage == 0) { 57094332d3Sopenharmony_ci HDF_LOGE("%{public}s: CONVERT_TABLE_USAGE length is equal to 0", __func__); 58094332d3Sopenharmony_ci return DISPLAY_FAILURE; 59094332d3Sopenharmony_ci } 60094332d3Sopenharmony_ci uint32_t lenFormat = GetArrLength(CONVERT_TABLE_FORMAT); 61094332d3Sopenharmony_ci if (lenFormat == 0) { 62094332d3Sopenharmony_ci HDF_LOGE("%{public}s: CONVERT_TABLE_FORMAT length is equal to 0", __func__); 63094332d3Sopenharmony_ci return DISPLAY_FAILURE; 64094332d3Sopenharmony_ci } 65094332d3Sopenharmony_ci 66094332d3Sopenharmony_ci info.width = GetData<uint32_t>() % WIDTH; 67094332d3Sopenharmony_ci info.height = GetData<uint32_t>() % HEIGHT; 68094332d3Sopenharmony_ci info.usage = CONVERT_TABLE_USAGE[GetData<uint32_t>() % lenUsage]; 69094332d3Sopenharmony_ci info.format = CONVERT_TABLE_FORMAT[GetData<uint32_t>() % lenFormat]; 70094332d3Sopenharmony_ci info.expectedSize = info.width * info.height; 71094332d3Sopenharmony_ci return DISPLAY_SUCCESS; 72094332d3Sopenharmony_ci} 73094332d3Sopenharmony_ci 74094332d3Sopenharmony_ciBufferHandle* UsingAllocmem() 75094332d3Sopenharmony_ci{ 76094332d3Sopenharmony_ci AllocInfo info = { 0 }; 77094332d3Sopenharmony_ci int32_t ret = GetAllocInfo(info); 78094332d3Sopenharmony_ci if (ret != DISPLAY_SUCCESS) { 79094332d3Sopenharmony_ci HDF_LOGE("%{public}s: function GetAllocInfo failed", __func__); 80094332d3Sopenharmony_ci return nullptr; 81094332d3Sopenharmony_ci } 82094332d3Sopenharmony_ci 83094332d3Sopenharmony_ci BufferHandle* handle = nullptr; 84094332d3Sopenharmony_ci ret = g_bufferInterface->AllocMem(info, handle); 85094332d3Sopenharmony_ci if (ret != DISPLAY_SUCCESS && handle != nullptr) { 86094332d3Sopenharmony_ci HDF_LOGE("%{public}s: function AllocMem failed", __func__); 87094332d3Sopenharmony_ci g_bufferInterface->FreeMem(*handle); 88094332d3Sopenharmony_ci return nullptr; 89094332d3Sopenharmony_ci } 90094332d3Sopenharmony_ci return handle; 91094332d3Sopenharmony_ci} 92094332d3Sopenharmony_ci 93094332d3Sopenharmony_civoid TestRegisterBuffer(const BufferHandle& handle) 94094332d3Sopenharmony_ci{ 95094332d3Sopenharmony_ci (void)g_bufferInterface->RegisterBuffer(handle); 96094332d3Sopenharmony_ci} 97094332d3Sopenharmony_ci 98094332d3Sopenharmony_civoid TestSetMetadata(const BufferHandle& handle) 99094332d3Sopenharmony_ci{ 100094332d3Sopenharmony_ci uint16_t key = GetData<uint16_t>(); 101094332d3Sopenharmony_ci uint32_t len = GetData<uint32_t>() % g_maxVectorLen; 102094332d3Sopenharmony_ci std::vector<uint8_t> values; 103094332d3Sopenharmony_ci for (uint32_t i = 0; i < len; i++) { 104094332d3Sopenharmony_ci values.push_back(GetData<uint8_t>() % ALPHA_VALUE_RANGE); 105094332d3Sopenharmony_ci } 106094332d3Sopenharmony_ci 107094332d3Sopenharmony_ci (void)g_bufferInterface->SetMetadata(handle, key, values); 108094332d3Sopenharmony_ci} 109094332d3Sopenharmony_ci 110094332d3Sopenharmony_civoid TestGetMetadata(const BufferHandle& handle) 111094332d3Sopenharmony_ci{ 112094332d3Sopenharmony_ci uint16_t key = GetData<uint16_t>(); 113094332d3Sopenharmony_ci std::vector<uint8_t> values = {}; 114094332d3Sopenharmony_ci (void)g_bufferInterface->GetMetadata(handle, key, values); 115094332d3Sopenharmony_ci} 116094332d3Sopenharmony_ci 117094332d3Sopenharmony_civoid TestListMetadataKeys(const BufferHandle& handle) 118094332d3Sopenharmony_ci{ 119094332d3Sopenharmony_ci std::vector<uint32_t> keys = {}; 120094332d3Sopenharmony_ci (void)g_bufferInterface->ListMetadataKeys(handle, keys); 121094332d3Sopenharmony_ci} 122094332d3Sopenharmony_ci 123094332d3Sopenharmony_civoid TestEraseMetadataKey(const BufferHandle& handle) 124094332d3Sopenharmony_ci{ 125094332d3Sopenharmony_ci uint16_t key = GetData<uint16_t>(); 126094332d3Sopenharmony_ci (void)g_bufferInterface->EraseMetadataKey(handle, key); 127094332d3Sopenharmony_ci} 128094332d3Sopenharmony_ci 129094332d3Sopenharmony_citypedef void (*TestFuncs[])(const BufferHandle&); 130094332d3Sopenharmony_ci 131094332d3Sopenharmony_ciTestFuncs g_testFuncs = { 132094332d3Sopenharmony_ci TestRegisterBuffer, 133094332d3Sopenharmony_ci TestSetMetadata, 134094332d3Sopenharmony_ci TestGetMetadata, 135094332d3Sopenharmony_ci TestEraseMetadataKey, 136094332d3Sopenharmony_ci TestListMetadataKeys 137094332d3Sopenharmony_ci}; 138094332d3Sopenharmony_ci 139094332d3Sopenharmony_cibool FuzzTest(const uint8_t* rawData, size_t size) 140094332d3Sopenharmony_ci{ 141094332d3Sopenharmony_ci if (rawData == nullptr) { 142094332d3Sopenharmony_ci return false; 143094332d3Sopenharmony_ci } 144094332d3Sopenharmony_ci 145094332d3Sopenharmony_ci if (!g_isInit) { 146094332d3Sopenharmony_ci g_isInit = true; 147094332d3Sopenharmony_ci g_bufferInterface.reset(OHOS::HDI::Display::Buffer::V1_1::IDisplayBuffer::Get()); 148094332d3Sopenharmony_ci if (g_bufferInterface == nullptr) { 149094332d3Sopenharmony_ci HDF_LOGE("%{public}s: get IDisplayBuffer failed", __func__); 150094332d3Sopenharmony_ci return false; 151094332d3Sopenharmony_ci } 152094332d3Sopenharmony_ci } 153094332d3Sopenharmony_ci 154094332d3Sopenharmony_ci // initialize data 155094332d3Sopenharmony_ci g_data = rawData; 156094332d3Sopenharmony_ci g_dataSize = size; 157094332d3Sopenharmony_ci g_pos = 0; 158094332d3Sopenharmony_ci BufferHandle* buffer = UsingAllocmem(); 159094332d3Sopenharmony_ci if (buffer == nullptr) { 160094332d3Sopenharmony_ci HDF_LOGE("%{public}s: function UsingAllocmem failed", __func__); 161094332d3Sopenharmony_ci return false; 162094332d3Sopenharmony_ci } 163094332d3Sopenharmony_ci 164094332d3Sopenharmony_ci uint32_t code = GetData<uint32_t>(); 165094332d3Sopenharmony_ci uint32_t len = GetArrLength(g_testFuncs); 166094332d3Sopenharmony_ci if (len == 0) { 167094332d3Sopenharmony_ci HDF_LOGE("%{public}s: g_testFuncs length is equal to 0", __func__); 168094332d3Sopenharmony_ci g_bufferInterface->FreeMem(*buffer); 169094332d3Sopenharmony_ci return false; 170094332d3Sopenharmony_ci } 171094332d3Sopenharmony_ci 172094332d3Sopenharmony_ci g_testFuncs[code % len](*buffer); 173094332d3Sopenharmony_ci g_bufferInterface->FreeMem(*buffer); 174094332d3Sopenharmony_ci return true; 175094332d3Sopenharmony_ci} 176094332d3Sopenharmony_ci} // OHOS 177094332d3Sopenharmony_ci 178094332d3Sopenharmony_ci/* Fuzzer entry point */ 179094332d3Sopenharmony_ciextern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) 180094332d3Sopenharmony_ci{ 181094332d3Sopenharmony_ci if (size < OHOS::THRESHOLD) { 182094332d3Sopenharmony_ci return 0; 183094332d3Sopenharmony_ci } 184094332d3Sopenharmony_ci 185094332d3Sopenharmony_ci OHOS::FuzzTest(data, size); 186094332d3Sopenharmony_ci return 0; 187094332d3Sopenharmony_ci} 188