• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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