1/* 2 * Copyright (c) 2023 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 "layer_fuzzer.h" 17 18#include <cstddef> 19#include <cstdint> 20#include <securec.h> 21 22#include "display_common_fuzzer.h" 23 24namespace OHOS { 25using namespace OHOS::HDI::Display::Buffer::V1_0; 26using namespace OHOS::HDI::Display::Composer::V1_1; 27 28static sptr<Composer::V1_2::IDisplayComposerInterface> g_composerInterface = nullptr; 29static std::shared_ptr<IDisplayBuffer> g_bufferInterface = nullptr; 30 31static bool g_isInit = false; 32static const uint8_t* g_data = nullptr; 33static size_t g_dataSize = 0; 34static size_t g_pos; 35 36/* 37* describe: get data from outside untrusted data(g_data) which size is according to sizeof(T) 38* tips: only support basic type 39*/ 40template<class T> 41T GetData() 42{ 43 T object {}; 44 size_t objectSize = sizeof(object); 45 if (g_data == nullptr || objectSize > g_dataSize - g_pos) { 46 return object; 47 } 48 errno_t ret = memcpy_s(&object, objectSize, g_data + g_pos, objectSize); 49 if (ret != EOK) { 50 return {}; 51 } 52 g_pos += objectSize; 53 return object; 54} 55 56static int32_t GetLayerInfo(LayerInfo& layerInfo) 57{ 58 uint32_t lenLayerType = GetArrLength(CONVERT_TABLE_LAYER_TYPE); 59 if (lenLayerType == 0) { 60 HDF_LOGE("%{public}s: CONVERT_TABLE_LAYER_TYPE length is equal to 0", __func__); 61 return DISPLAY_FAILURE; 62 } 63 64 uint32_t lenFormat = GetArrLength(CONVERT_TABLE_FORMAT); 65 if (lenFormat == 0) { 66 HDF_LOGE("%{public}s: CONVERT_TABLE_FORMAT length is equal to 0", __func__); 67 return DISPLAY_FAILURE; 68 } 69 layerInfo.width = GetData<uint32_t>() % WIDTH; 70 layerInfo.height = GetData<uint32_t>() % HEIGHT; 71 layerInfo.type = CONVERT_TABLE_LAYER_TYPE[GetData<uint32_t>() % lenLayerType]; 72 layerInfo.bpp = GetData<uint32_t>(); 73 layerInfo.pixFormat = CONVERT_TABLE_FORMAT[GetData<uint32_t>() % lenFormat]; 74 return DISPLAY_SUCCESS; 75} 76 77static int32_t GetLayerAlpha(LayerAlpha& alpha) 78{ 79 alpha.enGlobalAlpha = GetRandBoolValue(GetData<uint32_t>()); 80 alpha.enPixelAlpha = GetRandBoolValue(GetData<uint32_t>()); 81 alpha.alpha0 = GetData<uint32_t>() % ALPHA_VALUE_RANGE; 82 alpha.alpha1 = GetData<uint32_t>() % ALPHA_VALUE_RANGE; 83 alpha.gAlpha = GetData<uint32_t>() % ALPHA_VALUE_RANGE; 84 return DISPLAY_SUCCESS; 85} 86 87static int32_t GetAllocInfo(AllocInfo& info) 88{ 89 uint32_t lenUsage = GetArrLength(CONVERT_TABLE_USAGE); 90 if (lenUsage == 0) { 91 HDF_LOGE("%{public}s: CONVERT_TABLE_USAGE length is equal to 0", __func__); 92 return DISPLAY_FAILURE; 93 } 94 uint32_t lenFormat = GetArrLength(CONVERT_TABLE_FORMAT); 95 if (lenFormat == 0) { 96 HDF_LOGE("%{public}s: CONVERT_TABLE_FORMAT length is equal to 0", __func__); 97 return DISPLAY_FAILURE; 98 } 99 100 info.width = GetData<uint32_t>() % WIDTH; 101 info.height = GetData<uint32_t>() % HEIGHT; 102 info.usage = CONVERT_TABLE_USAGE[GetData<uint32_t>() % lenUsage]; 103 info.format = CONVERT_TABLE_FORMAT[GetData<uint32_t>() % lenFormat]; 104 info.expectedSize = info.width * info.height; 105 return DISPLAY_SUCCESS; 106} 107 108static int32_t GetIRect(IRect& rect) 109{ 110 rect.x = GetData<int32_t>(); 111 rect.y = GetData<int32_t>(); 112 rect.w = GetData<int32_t>(); 113 rect.h = GetData<int32_t>(); 114 return DISPLAY_SUCCESS; 115} 116 117BufferHandle* UsingAllocmem() 118{ 119 AllocInfo info = { 0 }; 120 int32_t ret = GetAllocInfo(info); 121 if (ret != DISPLAY_SUCCESS) { 122 HDF_LOGE("%{public}s: function GetAllocInfo failed", __func__); 123 return nullptr; 124 } 125 126 BufferHandle* handle = nullptr; 127 ret = g_bufferInterface->AllocMem(info, handle); 128 if (ret != DISPLAY_SUCCESS) { 129 HDF_LOGE("%{public}s: function AllocMem failed", __func__); 130 return nullptr; 131 } 132 return handle; 133} 134 135int32_t UsingCreateLayer(uint32_t devId, uint32_t& layerId) 136{ 137 LayerInfo layerInfo; 138 int32_t ret = GetLayerInfo(layerInfo); 139 if (ret != DISPLAY_SUCCESS) { 140 HDF_LOGE("%{public}s: function GetLayerInfo failed", __func__); 141 return DISPLAY_FAILURE; 142 } 143 144 uint32_t bufferCount = 3; 145 ret = g_composerInterface->CreateLayer(devId, layerInfo, bufferCount, layerId); 146 if (ret != DISPLAY_SUCCESS) { 147 HDF_LOGE("%{public}s: function CreateLayer failed", __func__); 148 } 149 return ret; 150} 151 152int32_t UsingCloseLayer(uint32_t devId, uint32_t layerId) 153{ 154 int32_t ret = g_composerInterface->DestroyLayer(devId, layerId); 155 if (ret != DISPLAY_SUCCESS) { 156 HDF_LOGE("%{public}s: function CloseLayer failed", __func__); 157 return DISPLAY_FAILURE; 158 } 159 return ret; 160} 161 162int32_t TestSetLayerAlpha(uint32_t devId, uint32_t layerId) 163{ 164 LayerAlpha alpha = {0}; 165 int32_t ret = GetLayerAlpha(alpha); 166 if (ret != DISPLAY_SUCCESS) { 167 HDF_LOGE("%{public}s: function GetLayerAlpha failed", __func__); 168 return DISPLAY_FAILURE; 169 } 170 ret = g_composerInterface->SetLayerAlpha(0, 0, alpha); 171 if (ret != DISPLAY_SUCCESS) { 172 HDF_LOGE("%{public}s: function SetLyerAlpha failed", __func__); 173 return DISPLAY_FAILURE; 174 } 175 return ret; 176} 177 178int32_t TestSetLayerRegion(uint32_t devId, uint32_t layerId) 179{ 180 IRect rect; 181 int32_t ret = GetIRect(rect); 182 if (ret != DISPLAY_SUCCESS) { 183 HDF_LOGE("%{public}s: function GetIRect failed", __func__); 184 return DISPLAY_FAILURE; 185 } 186 ret = g_composerInterface->SetLayerRegion(devId, layerId, rect); 187 if (ret != DISPLAY_SUCCESS) { 188 HDF_LOGE("%{public}s: function SetLayerRegion failed", __func__); 189 } 190 return ret; 191} 192 193int32_t TestSetLayerCrop(uint32_t devId, uint32_t layerId) 194{ 195 IRect rect; 196 int32_t ret = GetIRect(rect); 197 if (ret != DISPLAY_SUCCESS) { 198 HDF_LOGE("%{public}s: function GetIRect failed", __func__); 199 return DISPLAY_FAILURE; 200 } 201 ret = g_composerInterface->SetLayerCrop(devId, layerId, rect); 202 if (ret != DISPLAY_SUCCESS) { 203 HDF_LOGE("%{public}s: function SetLayerCrop failed", __func__); 204 } 205 return ret; 206} 207 208int32_t TestSetLayerZorder(uint32_t devId, uint32_t layerId) 209{ 210 uint32_t zorder = GetData<uint32_t>(); 211 int32_t ret = g_composerInterface->SetLayerZorder(devId, layerId, zorder); 212 if (ret != DISPLAY_SUCCESS) { 213 HDF_LOGE("%{public}s: function SetLayerZorder failed", __func__); 214 } 215 return ret; 216} 217 218int32_t TestSetLayerPreMulti(uint32_t devId, uint32_t layerId) 219{ 220 bool preMul = GetRandBoolValue(GetData<uint32_t>()); 221 int32_t ret = g_composerInterface->SetLayerPreMulti(devId, layerId, preMul); 222 if (ret != DISPLAY_SUCCESS) { 223 HDF_LOGE("%{public}s: function SetLayerPreMulti failed", __func__); 224 } 225 return ret; 226} 227 228int32_t TestSetLayerTransformMode(uint32_t devId, uint32_t layerId) 229{ 230 uint32_t len = GetArrLength(CONVERT_TABLE_ROTATE); 231 if (len == 0) { 232 HDF_LOGE("%{public}s: CONVERT_TABLE_ROTATE length is equal to 0", __func__); 233 return DISPLAY_FAILURE; 234 } 235 TransformType type = CONVERT_TABLE_ROTATE[GetData<uint32_t>() % len]; 236 int32_t ret = g_composerInterface->SetLayerTransformMode(devId, layerId, type); 237 if (ret != DISPLAY_SUCCESS) { 238 HDF_LOGE("%{public}s: function SetLayerTransformMode failed", __func__); 239 } 240 return ret; 241} 242 243int32_t TestSetLayerDirtyRegion(uint32_t devId, uint32_t layerId) 244{ 245 IRect region; 246 int32_t ret = GetIRect(region); 247 if (ret != DISPLAY_SUCCESS) { 248 HDF_LOGE("%{public}s: function GetIRect failed", __func__); 249 return DISPLAY_FAILURE; 250 } 251 std::vector<IRect> vRects; 252 vRects.push_back(region); 253 ret = g_composerInterface->SetLayerDirtyRegion(devId, layerId, vRects); 254 if (ret != DISPLAY_SUCCESS) { 255 HDF_LOGE("%{public}s: function SetLayerDirtyRegion failed", __func__); 256 } 257 return ret; 258} 259 260int32_t TestSetLayerVisibleRegion(uint32_t devId, uint32_t layerId) 261{ 262 IRect rect; 263 int32_t ret = GetIRect(rect); 264 if (ret != DISPLAY_SUCCESS) { 265 HDF_LOGE("%{public}s: function GetIRect failed", __func__); 266 return DISPLAY_FAILURE; 267 } 268 std::vector<IRect> vRects; 269 vRects.push_back(rect); 270 ret = g_composerInterface->SetLayerVisibleRegion(devId, layerId, vRects); 271 if (ret != DISPLAY_SUCCESS) { 272 HDF_LOGE("%{public}s: function SetLayerVisibleRegion failed", __func__); 273 } 274 return ret; 275} 276 277int32_t TestSetLayerBuffer(uint32_t devId, uint32_t layerId) 278{ 279 int32_t fence = GetData<int32_t>(); 280 BufferHandle* buffer = UsingAllocmem(); 281 if (buffer == nullptr) { 282 HDF_LOGE("%{public}s: Failed to UsingAllocmem", __func__); 283 return DISPLAY_FAILURE; 284 } 285 uint32_t seqNo = GetData<uint32_t>(); 286 std::vector<uint32_t> deletingList; 287 int32_t ret = g_composerInterface->SetLayerBuffer(devId, layerId, buffer, seqNo, fence, deletingList); 288 if (ret != DISPLAY_SUCCESS) { 289 HDF_LOGE("%{public}s: function SetLayerBuffer failed", __func__); 290 } 291 g_bufferInterface->FreeMem(*buffer); 292 return ret; 293} 294 295int32_t TestSetLayerCompositionType(uint32_t devId, uint32_t layerId) 296{ 297 uint32_t len = GetArrLength(CONVERT_TABLE_COMPOSITION); 298 if (len == 0) { 299 HDF_LOGE("%{public}s: CONVERT_TABLE_COMPOSITION length is equal to 0", __func__); 300 return DISPLAY_FAILURE; 301 } 302 Composer::V1_0::CompositionType type = CONVERT_TABLE_COMPOSITION[GetData<uint32_t>() % len]; 303 int32_t ret = g_composerInterface->SetLayerCompositionType(devId, layerId, type); 304 if (ret != DISPLAY_SUCCESS) { 305 HDF_LOGE("%{public}s: function SetLayerCompositionType failed", __func__); 306 } 307 return ret; 308} 309 310int32_t TestSetLayerBlendType(uint32_t devId, uint32_t layerId) 311{ 312 uint32_t len = GetArrLength(CONVERT_TABLE_BLEND); 313 if (len == 0) { 314 HDF_LOGE("%{public}s: CONVERT_TABLE_BLEND length is equal to 0", __func__); 315 return DISPLAY_FAILURE; 316 } 317 BlendType type = CONVERT_TABLE_BLEND[GetData<uint32_t>() % len]; 318 int32_t ret = g_composerInterface->SetLayerBlendType(devId, layerId, type); 319 if (ret != DISPLAY_SUCCESS) { 320 HDF_LOGE("%{public}s: function SetLayerBlendType failed", __func__); 321 } 322 return ret; 323} 324 325int32_t TestSetLayerMaskInfo(uint32_t devId, uint32_t layerId) 326{ 327 uint32_t len = GetArrLength(CONVERT_TABLE_MASK); 328 if (len == 0) { 329 HDF_LOGE("%{public}s: CONVERT_TABLE_MASK length is equal to 0", __func__); 330 return DISPLAY_FAILURE; 331 } 332 MaskInfo maskInfo = CONVERT_TABLE_MASK[GetData<uint32_t>() % len]; 333 int32_t ret = g_composerInterface->SetLayerMaskInfo(devId, layerId, maskInfo); 334 if (ret != DISPLAY_SUCCESS) { 335 HDF_LOGE("%{public}s: function SetLayerMaskInfo failed", __func__); 336 } 337 return ret; 338} 339 340int32_t TestSetLayerColor(uint32_t devId, uint32_t layerId) 341{ 342 LayerColor layerColor = { 343 .r = GetData<uint32_t>() % ALPHA_VALUE_RANGE, 344 .g = GetData<uint32_t>() % ALPHA_VALUE_RANGE, 345 .b = GetData<uint32_t>() % ALPHA_VALUE_RANGE, 346 .a = GetData<uint32_t>() % ALPHA_VALUE_RANGE 347 }; 348 int32_t ret = g_composerInterface->SetLayerColor(devId, layerId, layerColor); 349 if (ret != DISPLAY_SUCCESS) { 350 HDF_LOGE("%{public}s: function SetLayerColor failed", __func__); 351 } 352 return ret; 353} 354 355int32_t TestSetLayerPerFrameParameter(uint32_t devId, uint32_t layerId) 356{ 357 std::vector<std::string> ValidKeys = { "FilmFilter", "ArsrDoEnhance", "SDRBrightnessRatio", "BrightnessNit", 358 "ViewGroupHasValidAlpha", "SourceCropTuning" }; 359 std::string key = ValidKeys[0]; 360 std::vector<int8_t> value; 361 value.push_back(GetData<int8_t>()); 362 int32_t ret = g_composerInterface->SetLayerPerFrameParameter(devId, layerId, key, value); 363 if ((ret != DISPLAY_SUCCESS) && (ret != DISPLAY_NOT_SUPPORT)) { 364 HDF_LOGE("%{public}s: failed with ret=%{public}d", __func__, ret); 365 } 366 return ret; 367} 368 369typedef int32_t (*TestFuncs[])(uint32_t, uint32_t); 370 371TestFuncs g_testFuncs = { 372 TestSetLayerAlpha, 373 TestSetLayerRegion, 374 TestSetLayerCrop, 375 TestSetLayerZorder, 376 TestSetLayerPreMulti, 377 TestSetLayerTransformMode, 378 TestSetLayerDirtyRegion, 379 TestSetLayerVisibleRegion, 380 TestSetLayerBuffer, 381 TestSetLayerCompositionType, 382 TestSetLayerBlendType, 383 TestSetLayerColor, 384 TestSetLayerPerFrameParameter, 385 TestSetLayerMaskInfo 386}; 387 388bool FuzzTest(const uint8_t* rawData, size_t size) 389{ 390 if (rawData == nullptr) { 391 return false; 392 } 393 394 if (!g_isInit) { 395 g_isInit = true; 396 g_composerInterface = Composer::V1_2::IDisplayComposerInterface::Get(); 397 if (g_composerInterface == nullptr) { 398 HDF_LOGE("%{public}s: get IDisplayComposerInterface failed", __func__); 399 return false; 400 } 401 g_bufferInterface.reset(IDisplayBuffer::Get()); 402 if (g_bufferInterface == nullptr) { 403 HDF_LOGE("%{public}s: get IDisplayBuffer failed", __func__); 404 return false; 405 } 406 } 407 408 // initialize data 409 g_data = rawData; 410 g_dataSize = size; 411 g_pos = 0; 412 413 uint32_t code = GetData<uint32_t>(); 414 uint32_t devId = GetData<uint32_t>(); 415 uint32_t layerId = GetData<uint32_t>(); 416 int32_t ret = UsingCreateLayer(devId, layerId); 417 if (ret != DISPLAY_SUCCESS) { 418 HDF_LOGE("%{public}s: function UsingCreateLayer failed", __func__); 419 return false; 420 } 421 422 uint32_t len = GetArrLength(g_testFuncs); 423 if (len == 0) { 424 HDF_LOGE("%{public}s: g_testFuncs length is equal to 0", __func__); 425 return false; 426 } 427 428 ret = g_testFuncs[code % len](devId, layerId); 429 if (ret != DISPLAY_SUCCESS) { 430 HDF_LOGE("function %{public}u failed", code % len); 431 return false; 432 } 433 434 ret = UsingCloseLayer(devId, layerId); 435 if (ret != DISPLAY_SUCCESS) { 436 HDF_LOGE("%{public}s: function UsingCloseLayer failed", __func__); 437 return false; 438 } 439 440 return true; 441} 442} // OHOS 443 444/* Fuzzer entry point */ 445extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) 446{ 447 if (size < OHOS::THRESHOLD) { 448 return 0; 449 } 450 451 OHOS::FuzzTest(data, size); 452 return 0; 453} 454