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_0;
28
29 static sptr<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
57 /*
58 * get a string from g_data
59 */
GetStringFromData(int strlen)60 std::string GetStringFromData(int strlen)
61 {
62 char cstr[strlen];
63 cstr[strlen - 1] = '\0';
64 for (int i = 0; i < strlen - 1; i++) {
65 cstr[i] = GetData<char>();
66 }
67 std::string str(cstr);
68 return str;
69 }
70
GetDisplayCapability(DisplayCapability & info)71 static int32_t GetDisplayCapability(DisplayCapability& info)
72 {
73 uint32_t lenType = GetArrLength(CONVERT_TABLE_INTERFACE_TYPE);
74 if (lenType == 0) {
75 HDF_LOGE("%{public}s: CONVERT_TABLE_INTERFACE_TYPE length is equal to 0", __func__);
76 return DISPLAY_FAILURE;
77 }
78
79 info.name = GetStringFromData(STR_LEN);
80 info.type = CONVERT_TABLE_INTERFACE_TYPE[GetData<uint32_t>() % lenType];
81 info.phyWidth = GetData<uint32_t>();
82 info.phyHeight = GetData<uint32_t>();
83 info.supportLayers = GetData<uint32_t>();
84 info.virtualDispCount = GetData<uint32_t>();
85 info.supportWriteBack = GetData<uint32_t>();
86 info.propertyCount = GetData<uint32_t>();
87 return DISPLAY_SUCCESS;
88 }
89
GetAllocInfo(AllocInfo & info)90 static int32_t GetAllocInfo(AllocInfo& info)
91 {
92 uint32_t lenUsage = GetArrLength(CONVERT_TABLE_USAGE);
93 if (lenUsage == 0) {
94 HDF_LOGE("%{public}s: CONVERT_TABLE_USAGE length is equal to 0", __func__);
95 return DISPLAY_FAILURE;
96 }
97 uint32_t lenFormat = GetArrLength(CONVERT_TABLE_FORMAT);
98 if (lenFormat == 0) {
99 HDF_LOGE("%{public}s: CONVERT_TABLE_FORMAT length is equal to 0", __func__);
100 return DISPLAY_FAILURE;
101 }
102
103 info.width = GetData<uint32_t>() % WIDTH;
104 info.height = GetData<uint32_t>() % HEIGHT;
105 info.usage = CONVERT_TABLE_USAGE[GetData<uint32_t>() % lenUsage];
106 info.format = CONVERT_TABLE_FORMAT[GetData<uint32_t>() % lenFormat];
107 info.expectedSize = info.width * info.height;
108 return DISPLAY_SUCCESS;
109 }
110
GetIRect(IRect & rect)111 static int32_t GetIRect(IRect& rect)
112 {
113 rect.x = GetData<int32_t>();
114 rect.y = GetData<int32_t>();
115 rect.w = GetData<int32_t>();
116 rect.h = GetData<int32_t>();
117 return DISPLAY_SUCCESS;
118 }
119
UsingAllocmem()120 BufferHandle* UsingAllocmem()
121 {
122 AllocInfo info = { 0 };
123 int32_t ret = GetAllocInfo(info);
124 if (ret != DISPLAY_SUCCESS) {
125 HDF_LOGE("%{public}s: function GetAllocInfo failed", __func__);
126 return nullptr;
127 }
128
129 BufferHandle* handle = nullptr;
130 ret = g_bufferInterface->AllocMem(info, handle);
131 if (ret != DISPLAY_SUCCESS) {
132 HDF_LOGE("%{public}s: function AllocMem failed", __func__);
133 return nullptr;
134 }
135 return handle;
136 }
137
TestSetClientBufferCacheCount(uint32_t devId)138 int32_t TestSetClientBufferCacheCount(uint32_t devId)
139 {
140 uint32_t cacheCount = GetData<uint32_t>();
141 int32_t ret = g_composerInterface->SetClientBufferCacheCount(devId, cacheCount);
142 if (ret != DISPLAY_SUCCESS) {
143 HDF_LOGE("%{public}s: function SetClientBufferCacheCount failed", __func__);
144 return DISPLAY_FAILURE;
145 }
146 return ret;
147 }
148
TestGetDisplayCapability(uint32_t devId)149 int32_t TestGetDisplayCapability(uint32_t devId)
150 {
151 DisplayCapability info = { 0 };
152 int32_t ret = GetDisplayCapability(info);
153 if (ret != DISPLAY_SUCCESS) {
154 HDF_LOGE("%{public}s: function GetDisplayCapability failed", __func__);
155 return DISPLAY_FAILURE;
156 }
157 ret = g_composerInterface->GetDisplayCapability(devId, info);
158 if (ret != DISPLAY_SUCCESS) {
159 HDF_LOGE("%{public}s: function GetDisplayCapability failed", __func__);
160 return DISPLAY_FAILURE;
161 }
162 return ret;
163 }
164
TestGetDisplaySupportedModes(uint32_t devId)165 int32_t TestGetDisplaySupportedModes(uint32_t devId)
166 {
167 DisplayModeInfo info = { 0 };
168 info.width = GetData<int32_t>() % WIDTH;
169 info.height = GetData<int32_t>() % HEIGHT;
170 info.freshRate = GetData<uint32_t>();
171 info.id = GetData<int32_t>();
172
173 std::vector<DisplayModeInfo> infos;
174 infos.push_back(info);
175 int32_t ret = g_composerInterface->GetDisplaySupportedModes(devId, infos);
176 if (ret != DISPLAY_SUCCESS) {
177 HDF_LOGE("%{public}s: function GetDisplaySupportedModes failed", __func__);
178 return DISPLAY_FAILURE;
179 }
180 return ret;
181 }
182
TestSetGetDisplayMode(uint32_t devId)183 int32_t TestSetGetDisplayMode(uint32_t devId)
184 {
185 uint32_t modeId = GetData<uint32_t>();
186 int32_t ret = g_composerInterface->SetDisplayMode(devId, modeId);
187 if (ret != DISPLAY_SUCCESS) {
188 HDF_LOGE("%{public}s: function SetDisplayMode failed", __func__);
189 return DISPLAY_FAILURE;
190 }
191 ret = g_composerInterface->GetDisplayMode(devId, modeId);
192 if (ret != DISPLAY_SUCCESS) {
193 HDF_LOGE("%{public}s: function GetDisplayMode failed", __func__);
194 return DISPLAY_FAILURE;
195 }
196 return ret;
197 }
198
TestSetGetDisplayPowerStatus(uint32_t devId)199 int32_t TestSetGetDisplayPowerStatus(uint32_t devId)
200 {
201 uint32_t len = GetArrLength(CONVERT_TABLE_POWER_STATUS);
202 if (len == 0) {
203 HDF_LOGE("%{public}s: CONVERT_TABLE_POWER_STATUS length is equal to 0", __func__);
204 return DISPLAY_FAILURE;
205 }
206 DispPowerStatus status = CONVERT_TABLE_POWER_STATUS[GetData<uint32_t>() % len];
207 int32_t ret = g_composerInterface->SetDisplayPowerStatus(devId, status);
208 if (ret != DISPLAY_SUCCESS) {
209 HDF_LOGE("%{public}s: function SetDisplayPowerStatus failed", __func__);
210 return DISPLAY_FAILURE;
211 }
212 ret = g_composerInterface->GetDisplayPowerStatus(devId, status);
213 if (ret != DISPLAY_SUCCESS) {
214 HDF_LOGE("%{public}s: function GetDisplayPowerStatus failed", __func__);
215 return DISPLAY_FAILURE;
216 }
217 return ret;
218 }
219
TestPrepareDisplayLayers(uint32_t devId)220 int32_t TestPrepareDisplayLayers(uint32_t devId)
221 {
222 bool needFlushFb = GetRandBoolValue(GetData<uint32_t>());
223 int32_t ret = g_composerInterface->PrepareDisplayLayers(devId, needFlushFb);
224 if (ret != DISPLAY_SUCCESS) {
225 HDF_LOGE("%{public}s: function PrepareDisplayLayers failed", __func__);
226 return DISPLAY_FAILURE;
227 }
228 return ret;
229 }
230
TestSetGetDisplayBacklight(uint32_t devId)231 int32_t TestSetGetDisplayBacklight(uint32_t devId)
232 {
233 uint32_t level = GetData<uint32_t>();
234 int32_t ret = g_composerInterface->SetDisplayBacklight(devId, level);
235 if (ret != DISPLAY_SUCCESS) {
236 HDF_LOGE("%{public}s: function SetDisplayBacklight failed", __func__);
237 return DISPLAY_FAILURE;
238 }
239 ret = g_composerInterface->GetDisplayBacklight(devId, level);
240 if (ret != DISPLAY_SUCCESS) {
241 HDF_LOGE("%{public}s: function GetDisplayBacklight failed", __func__);
242 return DISPLAY_FAILURE;
243 }
244 return ret;
245 }
246
TestGetDisplayProperty(uint32_t devId)247 int32_t TestGetDisplayProperty(uint32_t devId)
248 {
249 uint32_t id = GetData<uint32_t>();
250 uint64_t value = GetData<uint32_t>();
251 int32_t ret = g_composerInterface->GetDisplayProperty(devId, id, value);
252 if (ret != DISPLAY_SUCCESS) {
253 HDF_LOGE("%{public}s: function GetDisplayProperty failed", __func__);
254 return DISPLAY_FAILURE;
255 }
256 return ret;
257 }
258
TestGetDisplayCompChange(uint32_t devId)259 int32_t TestGetDisplayCompChange(uint32_t devId)
260 {
261 std::vector<uint32_t> layers;
262 layers.push_back(GetData<uint32_t>());
263 std::vector<int32_t> types;
264 types.push_back(GetData<int32_t>());
265
266 int32_t ret = g_composerInterface->GetDisplayCompChange(devId, layers, types);
267 if (ret != DISPLAY_SUCCESS) {
268 HDF_LOGE("%{public}s: function GetDisplayCompChange failed", __func__);
269 return DISPLAY_FAILURE;
270 }
271 return ret;
272 }
273
TestSetDisplayClientCrop(uint32_t devId)274 int32_t TestSetDisplayClientCrop(uint32_t devId)
275 {
276 IRect rect;
277 int32_t ret = GetIRect(rect);
278 if (ret != DISPLAY_SUCCESS) {
279 HDF_LOGE("%{public}s: function GetIRect failed", __func__);
280 return DISPLAY_FAILURE;
281 }
282 ret = g_composerInterface->SetDisplayClientCrop(devId, rect);
283 if (ret != DISPLAY_SUCCESS) {
284 HDF_LOGE("%{public}s: function SetDisplayClientCrop failed", __func__);
285 return DISPLAY_FAILURE;
286 }
287 return ret;
288 }
289
TestSetDisplayClientBuffer(uint32_t devId)290 int32_t TestSetDisplayClientBuffer(uint32_t devId)
291 {
292 int32_t fence = GetData<int32_t>();
293 const BufferHandle* buffer = UsingAllocmem();
294 if (buffer == nullptr) {
295 HDF_LOGE("%{public}s: Failed to UsingAllocmem", __func__);
296 return DISPLAY_FAILURE;
297 }
298 uint32_t seqNo = GetData<uint32_t>();
299 int32_t ret = g_composerInterface->SetDisplayClientBuffer(devId, buffer, seqNo, fence);
300 if (ret != DISPLAY_SUCCESS) {
301 HDF_LOGE("%{public}s: function TestSetDisplayClientBuffer failed", __func__);
302 }
303 g_bufferInterface->FreeMem(*buffer);
304 return ret;
305 }
306
TestSetDisplayClientDamage(uint32_t devId)307 int32_t TestSetDisplayClientDamage(uint32_t devId)
308 {
309 IRect rect;
310 int32_t ret = GetIRect(rect);
311 if (ret != DISPLAY_SUCCESS) {
312 HDF_LOGE("%{public}s: function GetIRect failed", __func__);
313 return DISPLAY_FAILURE;
314 }
315 std::vector<IRect> rects;
316 rects.push_back(rect);
317 ret = g_composerInterface->SetDisplayClientDamage(devId, rects);
318 if (ret != DISPLAY_SUCCESS) {
319 HDF_LOGE("%{public}s: function SetDisplayClientDamage failed", __func__);
320 }
321 return ret;
322 }
323
TestSetDisplayVsyncEnabled(uint32_t devId)324 int32_t TestSetDisplayVsyncEnabled(uint32_t devId)
325 {
326 bool enabled = GetRandBoolValue(GetData<uint32_t>());
327 int32_t ret = g_composerInterface->SetDisplayVsyncEnabled(devId, enabled);
328 if (ret != DISPLAY_SUCCESS) {
329 HDF_LOGE("%{public}s: function SetDisplayVsyncEnabled failed", __func__);
330 }
331 return ret;
332 }
333
TestRegDisplayVBlankCallback(uint32_t devId)334 int32_t TestRegDisplayVBlankCallback(uint32_t devId)
335 {
336 uint32_t param1 = GetData<uint32_t>();
337 VBlankCallback param2 = GetData<VBlankCallback>();
338 void* param3 = malloc(PARAM_VOIDPTR_LEN);
339 if (param3 == nullptr) {
340 HDF_LOGE("%{public}s: void* param3 malloc failed", __func__);
341 return DISPLAY_FAILURE;
342 }
343 int32_t ret = g_composerInterface->RegDisplayVBlankCallback(param1, param2, param3);
344 if (ret != DISPLAY_SUCCESS) {
345 HDF_LOGE("%{public}s: function RegDisplayVBlankCallback failed", __func__);
346 }
347 free(param3);
348 param3 = nullptr;
349 return ret;
350 }
351
TestGetDisplayReleaseFence(uint32_t devId)352 int32_t TestGetDisplayReleaseFence(uint32_t devId)
353 {
354 std::vector<uint32_t> layers;
355 layers.push_back(GetData<uint32_t>());
356 std::vector<int32_t> fences;
357 fences.push_back(GetData<int32_t>());
358
359 int32_t ret = g_composerInterface->GetDisplayReleaseFence(devId, layers, fences);
360 if (ret != DISPLAY_SUCCESS) {
361 HDF_LOGE("%{public}s: function GetDisplayReleaseFence failed", __func__);
362 }
363 return ret;
364 }
365
TestDestroyVirtualDisplay(uint32_t devId)366 int32_t TestDestroyVirtualDisplay(uint32_t devId)
367 {
368 int32_t ret = g_composerInterface->DestroyVirtualDisplay(devId);
369 if (ret != DISPLAY_SUCCESS) {
370 HDF_LOGE("%{public}s: function DestroyVirtualDisplay failed", __func__);
371 }
372 return ret;
373 }
374
TestSetVirtualDisplayBuffer(uint32_t devId)375 int32_t TestSetVirtualDisplayBuffer(uint32_t devId)
376 {
377 int32_t fence = GetData<int32_t>();
378 BufferHandle* buffer = UsingAllocmem();
379 if (buffer == nullptr) {
380 HDF_LOGE("%{public}s: Failed to UsingAllocmem", __func__);
381 return DISPLAY_FAILURE;
382 }
383 int32_t ret = g_composerInterface->SetVirtualDisplayBuffer(devId, *buffer, fence);
384 if (ret != DISPLAY_SUCCESS) {
385 HDF_LOGE("%{public}s: function SetVirtualDisplayBuffer failed", __func__);
386 }
387 g_bufferInterface->FreeMem(*buffer);
388 return ret;
389 }
390
TestSetDisplayProperty(uint32_t devId)391 int32_t TestSetDisplayProperty(uint32_t devId)
392 {
393 uint32_t id = GetData<uint32_t>();
394 uint64_t value = GetData<uint64_t>();
395 int32_t ret = g_composerInterface->SetDisplayProperty(devId, id, value);
396 if (ret != DISPLAY_SUCCESS) {
397 HDF_LOGE("%{public}s: SetDisplayProperty failed", __func__);
398 }
399 return ret;
400 }
401
TestCommit(uint32_t devId)402 int32_t TestCommit(uint32_t devId)
403 {
404 int32_t fence = GetData<int32_t>();
405 int32_t ret = g_composerInterface->Commit(devId, fence);
406 if (ret != DISPLAY_SUCCESS) {
407 HDF_LOGE("%{public}s: function Commit failed", __func__);
408 }
409 return ret;
410 }
411
412 typedef int32_t (*TestFuncs[])(uint32_t);
413
414 TestFuncs g_testFuncs = {
415 TestSetClientBufferCacheCount,
416 TestGetDisplayCapability,
417 TestGetDisplaySupportedModes,
418 TestSetGetDisplayMode,
419 TestSetGetDisplayPowerStatus,
420 TestPrepareDisplayLayers,
421 TestSetGetDisplayBacklight,
422 TestGetDisplayProperty,
423 TestGetDisplayCompChange,
424 TestSetDisplayClientCrop,
425 TestSetDisplayClientBuffer,
426 TestSetDisplayClientDamage,
427 TestSetDisplayVsyncEnabled,
428 TestGetDisplayReleaseFence,
429 TestDestroyVirtualDisplay,
430 TestSetVirtualDisplayBuffer,
431 TestSetDisplayProperty,
432 TestCommit,
433 };
434
FuzzTest(const uint8_t * rawData,size_t size)435 bool FuzzTest(const uint8_t* rawData, size_t size)
436 {
437 if (rawData == nullptr) {
438 return false;
439 }
440
441 // initialize service
442 if (!g_isInit) {
443 g_isInit = true;
444 g_composerInterface = IDisplayComposerInterface::Get();
445 if (g_composerInterface == nullptr) {
446 HDF_LOGE("%{public}s: get IDisplayComposerInterface failed", __func__);
447 return false;
448 }
449 g_bufferInterface.reset(IDisplayBuffer::Get());
450 if (g_bufferInterface == nullptr) {
451 HDF_LOGE("%{public}s: get IDisplayBuffer failed", __func__);
452 return false;
453 }
454 }
455
456 // initialize data
457 g_data = rawData;
458 g_dataSize = size;
459 g_pos = 0;
460
461 uint32_t code = GetData<uint32_t>();
462 uint32_t devId = GetData<uint32_t>();
463 uint32_t len = GetArrLength(g_testFuncs);
464 if (len == 0) {
465 HDF_LOGE("%{public}s: g_testFuncs length is equal to 0", __func__);
466 return false;
467 }
468
469 int32_t ret = g_testFuncs[code % len](devId);
470 if (ret != DISPLAY_SUCCESS) {
471 HDF_LOGE("function %{public}u failed", code % len);
472 return false;
473 }
474
475 return true;
476 }
477 } // OHOS
478
479 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)480 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
481 {
482 if (size < OHOS::THRESHOLD) {
483 return 0;
484 }
485
486 OHOS::FuzzTest(data, size);
487 return 0;
488 }
489