• 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_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