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 "device_fuzzer.h"
17
18 #include <cstddef>
19 #include <cstdint>
20 #include <securec.h>
21 #include <string>
22
23 #include "display_common_fuzzer.h"
24
25 namespace OHOS {
26 using namespace OHOS::HDI::Display::Buffer::V1_0;
27 using namespace OHOS::HDI::Display::Composer::V1_1;
28
29 static sptr<Composer::V1_1::IDisplayComposerInterface> g_composerInterface = nullptr;
30 static std::shared_ptr<IDisplayBuffer> g_bufferInterface = nullptr;
31
32 static bool g_isInit = false;
33 static const uint8_t* g_data = nullptr;
34 static size_t g_dataSize = 0;
35 static size_t g_pos;
36
37 /*
38 * describe: get data from outside untrusted data(g_data) which size is according to sizeof(T)
39 * tips: only support basic type
40 */
41 template<class T>
GetData()42 T GetData()
43 {
44 T object {};
45 size_t objectSize = sizeof(object);
46 if (g_data == nullptr || objectSize > g_dataSize - g_pos) {
47 return object;
48 }
49 errno_t ret = memcpy_s(&object, objectSize, g_data + g_pos, objectSize);
50 if (ret != EOK) {
51 return {};
52 }
53 g_pos += objectSize;
54 return object;
55 }
56
GetAllocInfo(AllocInfo & info)57 static int32_t GetAllocInfo(AllocInfo& info)
58 {
59 uint32_t lenUsage = GetArrLength(CONVERT_TABLE_USAGE);
60 if (lenUsage == 0) {
61 HDF_LOGE("%{public}s: CONVERT_TABLE_USAGE length is equal to 0", __func__);
62 return DISPLAY_FAILURE;
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
70 info.width = GetData<uint32_t>() % WIDTH;
71 info.height = GetData<uint32_t>() % HEIGHT;
72 info.usage = CONVERT_TABLE_USAGE[GetData<uint32_t>() % lenUsage];
73 info.format = CONVERT_TABLE_FORMAT[GetData<uint32_t>() % lenFormat];
74 info.expectedSize = info.width * info.height;
75
76 return DISPLAY_SUCCESS;
77 }
78
GetIRect(IRect & rect)79 static int32_t GetIRect(IRect& rect)
80 {
81 rect.x = GetData<int32_t>();
82 rect.y = GetData<int32_t>();
83 rect.w = GetData<int32_t>();
84 rect.h = GetData<int32_t>();
85 return DISPLAY_SUCCESS;
86 }
87
UsingAllocmem()88 BufferHandle* UsingAllocmem()
89 {
90 AllocInfo info = { 0 };
91 int32_t ret = GetAllocInfo(info);
92 if (ret != DISPLAY_SUCCESS) {
93 HDF_LOGE("%{public}s: function GetAllocInfo failed", __func__);
94 return nullptr;
95 }
96
97 BufferHandle* handle = nullptr;
98 ret = g_bufferInterface->AllocMem(info, handle);
99 if (ret != DISPLAY_SUCCESS) {
100 HDF_LOGE("%{public}s: function AllocMem failed", __func__);
101 return nullptr;
102 }
103 return handle;
104 }
105
TestSetClientBufferCacheCount(uint32_t devId)106 int32_t TestSetClientBufferCacheCount(uint32_t devId)
107 {
108 uint32_t cacheCount = GetData<uint32_t>();
109 int32_t ret = g_composerInterface->SetClientBufferCacheCount(devId, cacheCount);
110 if (ret != DISPLAY_SUCCESS) {
111 HDF_LOGE("%{public}s: function SetClientBufferCacheCount failed", __func__);
112 return DISPLAY_FAILURE;
113 }
114 return ret;
115 }
116
TestGetDisplaySupportedModes(uint32_t devId)117 int32_t TestGetDisplaySupportedModes(uint32_t devId)
118 {
119 DisplayModeInfo info = { 0 };
120 info.width = GetData<int32_t>() % WIDTH;
121 info.height = GetData<int32_t>() % HEIGHT;
122 info.freshRate = GetData<uint32_t>();
123 info.id = GetData<int32_t>();
124
125 std::vector<DisplayModeInfo> infos;
126 infos.push_back(info);
127 int32_t ret = g_composerInterface->GetDisplaySupportedModes(devId, infos);
128 if (ret != DISPLAY_SUCCESS) {
129 HDF_LOGE("%{public}s: function GetDisplaySupportedModes failed", __func__);
130 return DISPLAY_FAILURE;
131 }
132 return ret;
133 }
134
TestSetGetDisplayMode(uint32_t devId)135 int32_t TestSetGetDisplayMode(uint32_t devId)
136 {
137 uint32_t modeId = GetData<uint32_t>();
138 int32_t ret = g_composerInterface->SetDisplayMode(devId, modeId);
139 if (ret != DISPLAY_SUCCESS) {
140 HDF_LOGE("%{public}s: function SetDisplayMode failed", __func__);
141 return DISPLAY_FAILURE;
142 }
143 ret = g_composerInterface->GetDisplayMode(devId, modeId);
144 if (ret != DISPLAY_SUCCESS) {
145 HDF_LOGE("%{public}s: function GetDisplayMode failed", __func__);
146 return DISPLAY_FAILURE;
147 }
148 return ret;
149 }
150
TestSetGetDisplayPowerStatus(uint32_t devId)151 int32_t TestSetGetDisplayPowerStatus(uint32_t devId)
152 {
153 uint32_t len = GetArrLength(CONVERT_TABLE_POWER_STATUS);
154 if (len == 0) {
155 HDF_LOGE("%{public}s: CONVERT_TABLE_POWER_STATUS length is equal to 0", __func__);
156 return DISPLAY_FAILURE;
157 }
158 Composer::V1_0::DispPowerStatus status = CONVERT_TABLE_POWER_STATUS[GetData<uint32_t>() % len];
159 int32_t ret = g_composerInterface->SetDisplayPowerStatus(devId, status);
160 if (ret != DISPLAY_SUCCESS) {
161 HDF_LOGE("%{public}s: function SetDisplayPowerStatus failed", __func__);
162 return DISPLAY_FAILURE;
163 }
164 ret = g_composerInterface->GetDisplayPowerStatus(devId, status);
165 if (ret != DISPLAY_SUCCESS) {
166 HDF_LOGE("%{public}s: function GetDisplayPowerStatus failed", __func__);
167 return DISPLAY_FAILURE;
168 }
169 return ret;
170 }
171
TestPrepareDisplayLayers(uint32_t devId)172 int32_t TestPrepareDisplayLayers(uint32_t devId)
173 {
174 bool needFlushFb = GetRandBoolValue(GetData<uint32_t>());
175 int32_t ret = g_composerInterface->PrepareDisplayLayers(devId, needFlushFb);
176 if (ret != DISPLAY_SUCCESS) {
177 HDF_LOGE("%{public}s: function PrepareDisplayLayers failed", __func__);
178 return DISPLAY_FAILURE;
179 }
180 return ret;
181 }
182
TestSetGetDisplayBacklight(uint32_t devId)183 int32_t TestSetGetDisplayBacklight(uint32_t devId)
184 {
185 uint32_t level = GetData<uint32_t>();
186 int32_t ret = g_composerInterface->SetDisplayBacklight(devId, level);
187 if (ret != DISPLAY_SUCCESS) {
188 HDF_LOGE("%{public}s: function SetDisplayBacklight failed", __func__);
189 return DISPLAY_FAILURE;
190 }
191 ret = g_composerInterface->GetDisplayBacklight(devId, level);
192 if (ret != DISPLAY_SUCCESS) {
193 HDF_LOGE("%{public}s: function GetDisplayBacklight failed", __func__);
194 return DISPLAY_FAILURE;
195 }
196 return ret;
197 }
198
TestGetDisplayProperty(uint32_t devId)199 int32_t TestGetDisplayProperty(uint32_t devId)
200 {
201 uint32_t id = GetData<uint32_t>();
202 uint64_t value = GetData<uint32_t>();
203 int32_t ret = g_composerInterface->GetDisplayProperty(devId, id, value);
204 if (ret != DISPLAY_SUCCESS) {
205 HDF_LOGE("%{public}s: function GetDisplayProperty failed", __func__);
206 return DISPLAY_FAILURE;
207 }
208 return ret;
209 }
210
TestGetDisplayCompChange(uint32_t devId)211 int32_t TestGetDisplayCompChange(uint32_t devId)
212 {
213 std::vector<uint32_t> layers;
214 layers.push_back(GetData<uint32_t>());
215 std::vector<int32_t> types;
216 types.push_back(GetData<int32_t>());
217
218 int32_t ret = g_composerInterface->GetDisplayCompChange(devId, layers, types);
219 if (ret != DISPLAY_SUCCESS) {
220 HDF_LOGE("%{public}s: function GetDisplayCompChange failed", __func__);
221 return DISPLAY_FAILURE;
222 }
223 return ret;
224 }
225
TestSetDisplayClientCrop(uint32_t devId)226 int32_t TestSetDisplayClientCrop(uint32_t devId)
227 {
228 IRect rect;
229 int32_t ret = GetIRect(rect);
230 if (ret != DISPLAY_SUCCESS) {
231 HDF_LOGE("%{public}s: function GetIRect failed", __func__);
232 return DISPLAY_FAILURE;
233 }
234 ret = g_composerInterface->SetDisplayClientCrop(devId, rect);
235 if (ret != DISPLAY_SUCCESS) {
236 HDF_LOGE("%{public}s: function SetDisplayClientCrop failed", __func__);
237 return DISPLAY_FAILURE;
238 }
239 return ret;
240 }
241
TestSetDisplayClientDamage(uint32_t devId)242 int32_t TestSetDisplayClientDamage(uint32_t devId)
243 {
244 IRect rect;
245 int32_t ret = GetIRect(rect);
246 if (ret != DISPLAY_SUCCESS) {
247 HDF_LOGE("%{public}s: function GetIRect failed", __func__);
248 return DISPLAY_FAILURE;
249 }
250 std::vector<IRect> rects;
251 rects.push_back(rect);
252 ret = g_composerInterface->SetDisplayClientDamage(devId, rects);
253 if (ret != DISPLAY_SUCCESS) {
254 HDF_LOGE("%{public}s: function SetDisplayClientDamage failed", __func__);
255 }
256 return ret;
257 }
258
TestSetDisplayVsyncEnabled(uint32_t devId)259 int32_t TestSetDisplayVsyncEnabled(uint32_t devId)
260 {
261 bool enabled = GetRandBoolValue(GetData<uint32_t>());
262 int32_t ret = g_composerInterface->SetDisplayVsyncEnabled(devId, enabled);
263 if (ret != DISPLAY_SUCCESS) {
264 HDF_LOGE("%{public}s: function SetDisplayVsyncEnabled failed", __func__);
265 }
266 return ret;
267 }
268
TestRegDisplayVBlankCallback(uint32_t devId)269 int32_t TestRegDisplayVBlankCallback(uint32_t devId)
270 {
271 uint32_t param1 = GetData<uint32_t>();
272 VBlankCallback param2 = GetData<VBlankCallback>();
273 void* param3 = malloc(PARAM_VOIDPTR_LEN);
274 if (param3 == nullptr) {
275 HDF_LOGE("%{public}s: void* param3 malloc failed", __func__);
276 return DISPLAY_FAILURE;
277 }
278 int32_t ret = g_composerInterface->RegDisplayVBlankCallback(param1, param2, param3);
279 if (ret != DISPLAY_SUCCESS) {
280 HDF_LOGE("%{public}s: function RegDisplayVBlankCallback failed", __func__);
281 }
282 free(param3);
283 param3 = nullptr;
284 return ret;
285 }
286
TestGetDisplayReleaseFence(uint32_t devId)287 int32_t TestGetDisplayReleaseFence(uint32_t devId)
288 {
289 std::vector<uint32_t> layers;
290 layers.push_back(GetData<uint32_t>());
291 std::vector<int32_t> fences;
292 fences.push_back(GetData<int32_t>());
293
294 int32_t ret = g_composerInterface->GetDisplayReleaseFence(devId, layers, fences);
295 if (ret != DISPLAY_SUCCESS) {
296 HDF_LOGE("%{public}s: function GetDisplayReleaseFence failed", __func__);
297 }
298 return ret;
299 }
300
TestDestroyVirtualDisplay(uint32_t devId)301 int32_t TestDestroyVirtualDisplay(uint32_t devId)
302 {
303 int32_t ret = g_composerInterface->DestroyVirtualDisplay(devId);
304 if (ret != DISPLAY_SUCCESS) {
305 HDF_LOGE("%{public}s: function DestroyVirtualDisplay failed", __func__);
306 }
307 return ret;
308 }
309
TestSetVirtualDisplayBuffer(uint32_t devId)310 int32_t TestSetVirtualDisplayBuffer(uint32_t devId)
311 {
312 int32_t fence = GetData<int32_t>();
313 BufferHandle* buffer = UsingAllocmem();
314 if (buffer == nullptr) {
315 HDF_LOGE("%{public}s: Failed to UsingAllocmem", __func__);
316 return DISPLAY_FAILURE;
317 }
318 int32_t ret = g_composerInterface->SetVirtualDisplayBuffer(devId, *buffer, fence);
319 if (ret != DISPLAY_SUCCESS) {
320 HDF_LOGE("%{public}s: function SetVirtualDisplayBuffer failed", __func__);
321 }
322 g_bufferInterface->FreeMem(*buffer);
323 return ret;
324 }
325
TestSetDisplayProperty(uint32_t devId)326 int32_t TestSetDisplayProperty(uint32_t devId)
327 {
328 uint32_t id = GetData<uint32_t>();
329 uint64_t value = GetData<uint64_t>();
330 int32_t ret = g_composerInterface->SetDisplayProperty(devId, id, value);
331 if (ret != DISPLAY_SUCCESS) {
332 HDF_LOGE("%{public}s: SetDisplayProperty failed", __func__);
333 }
334 return ret;
335 }
336
TestCommit(uint32_t devId)337 int32_t TestCommit(uint32_t devId)
338 {
339 int32_t fence = GetData<int32_t>();
340 int32_t ret = g_composerInterface->Commit(devId, fence);
341 if (ret != DISPLAY_SUCCESS) {
342 HDF_LOGE("%{public}s: function Commit failed", __func__);
343 }
344 return ret;
345 }
346
TestGetDisplaySupportedModesExt(uint32_t devId)347 int TestGetDisplaySupportedModesExt(uint32_t devId)
348 {
349 std::vector<DisplayModeInfoExt> modes;
350 modes.push_back(GetData<DisplayModeInfoExt>());
351 int32_t ret = g_composerInterface->GetDisplaySupportedModesExt(devId, modes);
352 if ((ret != DISPLAY_SUCCESS) && (ret != DISPLAY_NOT_SUPPORT)) {
353 HDF_LOGE("%{public}s: GetDisplaySupportedModesExt failed", __func__);
354 }
355 return ret;
356 }
357
TestModeCallback(uint32_t modeId,uint64_t vBlankPeriod,void * data)358 void TestModeCallback(uint32_t modeId, uint64_t vBlankPeriod, void* data)
359 {
360 }
361
TestSetDisplayModeAsync(uint32_t devId)362 int TestSetDisplayModeAsync(uint32_t devId)
363 {
364 uint32_t modeid = GetData<uint32_t>();
365 int32_t ret = g_composerInterface->SetDisplayModeAsync(devId, modeid, TestModeCallback);
366 if ((ret != DISPLAY_SUCCESS) && (ret != DISPLAY_NOT_SUPPORT)) {
367 HDF_LOGE("%{public}s: SetDisplayModeAsync failed", __func__);
368 }
369 return ret;
370 }
371
TestGetDisplayVBlankPeriod(uint32_t devId)372 int TestGetDisplayVBlankPeriod(uint32_t devId)
373 {
374 uint64_t period = GetData<uint64_t>();
375 int32_t ret = g_composerInterface->GetDisplayVBlankPeriod(devId, period);
376 if ((ret != DISPLAY_SUCCESS) && (ret != DISPLAY_NOT_SUPPORT)) {
377 HDF_LOGE("%{public}s: GetDisplayVBlankPeriod failed", __func__);
378 }
379 return ret;
380 }
381
TestSeamlessChangeCallback(uint32_t devId,void * data)382 void TestSeamlessChangeCallback(uint32_t devId, void* data)
383 {
384 }
385
TestRegSeamlessChangeCallback(uint32_t devId)386 int TestRegSeamlessChangeCallback(uint32_t devId)
387 {
388 int32_t ret = g_composerInterface->RegSeamlessChangeCallback(TestSeamlessChangeCallback, nullptr);
389 if ((ret != DISPLAY_SUCCESS) && (ret != DISPLAY_NOT_SUPPORT)) {
390 HDF_LOGE("%{public}s: SetDisplayModeAsync failed", __func__);
391 }
392 return ret;
393 }
394
TestGetSupportedLayerPerFrameParameterKey(uint32_t devId)395 int TestGetSupportedLayerPerFrameParameterKey(uint32_t devId)
396 {
397 std::vector<std::string> keys;
398 int32_t ret = g_composerInterface->GetSupportedLayerPerFrameParameterKey(keys);
399 if ((ret != DISPLAY_SUCCESS) && (ret != DISPLAY_NOT_SUPPORT)) {
400 HDF_LOGE("%{public}s: failed with ret=%{public}d", __func__, ret);
401 }
402 return ret;
403 }
404
TestSetDisplayOverlayResolution(uint32_t devId)405 int TestSetDisplayOverlayResolution(uint32_t devId)
406 {
407 uint32_t width = GetData<uint32_t>() % WIDTH;
408 uint32_t height = GetData<uint32_t>() % HEIGHT;
409 int32_t ret = g_composerInterface->SetDisplayOverlayResolution(devId, width, height);
410 if ((ret != DISPLAY_SUCCESS) && (ret != DISPLAY_NOT_SUPPORT)) {
411 HDF_LOGE("%{public}s: failed with ret=%{public}d", __func__, ret);
412 }
413 return ret;
414 }
415
TestRefreshCallback(uint32_t devId,void * data)416 static void TestRefreshCallback(uint32_t devId, void* data)
417 {
418 }
419
TestRegRefreshCallback(uint32_t devId)420 int TestRegRefreshCallback(uint32_t devId)
421 {
422 int32_t ret = g_composerInterface->RegRefreshCallback(TestRefreshCallback, nullptr);
423 if ((ret != DISPLAY_SUCCESS) && (ret != DISPLAY_NOT_SUPPORT)) {
424 HDF_LOGE("%{public}s: failed with ret=%{public}d", __func__, ret);
425 }
426 return ret;
427 }
428
TestGetDisplaySupportedColorGamuts(uint32_t devId)429 int TestGetDisplaySupportedColorGamuts(uint32_t devId)
430 {
431 std::vector<ColorGamut> gamuts;
432 int32_t ret = g_composerInterface->GetDisplaySupportedColorGamuts(devId, gamuts);
433 if ((ret != DISPLAY_SUCCESS) && (ret != DISPLAY_NOT_SUPPORT)) {
434 HDF_LOGE("%{public}s: failed with ret=%{public}d", __func__, ret);
435 }
436 return ret;
437 }
438
TestGetHDRCapabilityInfos(uint32_t devId)439 int TestGetHDRCapabilityInfos(uint32_t devId)
440 {
441 HDRCapability info = { 0 };
442 int32_t ret = g_composerInterface->GetHDRCapabilityInfos(devId, info);
443 if ((ret != DISPLAY_SUCCESS) && (ret != DISPLAY_NOT_SUPPORT)) {
444 HDF_LOGE("%{public}s: failed with ret=%{public}d", __func__, ret);
445 }
446 return ret;
447 }
448
449 typedef int32_t (*TestFuncs[])(uint32_t);
450
451 TestFuncs g_testFuncs = {
452 TestSetClientBufferCacheCount,
453 TestGetDisplaySupportedModes,
454 TestSetGetDisplayMode,
455 TestSetGetDisplayPowerStatus,
456 TestPrepareDisplayLayers,
457 TestSetGetDisplayBacklight,
458 TestGetDisplayProperty,
459 TestGetDisplayCompChange,
460 TestSetDisplayClientCrop,
461 TestSetDisplayClientDamage,
462 TestSetDisplayVsyncEnabled,
463 TestGetDisplayReleaseFence,
464 TestDestroyVirtualDisplay,
465 TestSetVirtualDisplayBuffer,
466 TestSetDisplayProperty,
467 TestGetDisplaySupportedModesExt,
468 TestSetDisplayModeAsync,
469 TestGetDisplayVBlankPeriod,
470 TestRegSeamlessChangeCallback,
471 TestGetSupportedLayerPerFrameParameterKey,
472 TestSetDisplayOverlayResolution,
473 TestRegRefreshCallback,
474 TestGetDisplaySupportedColorGamuts,
475 TestGetHDRCapabilityInfos,
476 TestCommit,
477 };
478
FuzzTest(const uint8_t * rawData,size_t size)479 bool FuzzTest(const uint8_t* rawData, size_t size)
480 {
481 if (rawData == nullptr) {
482 return false;
483 }
484
485 // initialize service
486 if (!g_isInit) {
487 g_isInit = true;
488 g_composerInterface = Composer::V1_1::IDisplayComposerInterface::Get();
489 if (g_composerInterface == nullptr) {
490 HDF_LOGE("%{public}s: get IDisplayComposerInterface failed", __func__);
491 return false;
492 }
493 g_bufferInterface.reset(IDisplayBuffer::Get());
494 if (g_bufferInterface == nullptr) {
495 HDF_LOGE("%{public}s: get IDisplayBuffer failed", __func__);
496 return false;
497 }
498 }
499
500 // initialize data
501 g_data = rawData;
502 g_dataSize = size;
503 g_pos = 0;
504
505 uint32_t code = GetData<uint32_t>();
506 uint32_t devId = GetData<uint32_t>();
507 uint32_t len = GetArrLength(g_testFuncs);
508 if (len == 0) {
509 HDF_LOGE("%{public}s: g_testFuncs length is equal to 0", __func__);
510 return false;
511 }
512
513 int32_t ret = g_testFuncs[code % len](devId);
514 if (ret != DISPLAY_SUCCESS) {
515 HDF_LOGE("function %{public}u failed", code % len);
516 return false;
517 }
518
519 return true;
520 }
521 } // OHOS
522
523 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)524 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
525 {
526 if (size < OHOS::THRESHOLD) {
527 return 0;
528 }
529
530 OHOS::FuzzTest(data, size);
531 return 0;
532 }
533