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