1 /*
2  * Copyright (c) 2022 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 "hdibackend_fuzzer.h"
17 
18 #include <securec.h>
19 
20 #include "hdi_backend.h"
21 #include "surface.h"
22 using namespace OHOS::Rosen;
23 
24 namespace OHOS {
25     namespace {
26         constexpr size_t STR_LEN = 10;
27         const uint8_t* data_ = nullptr;
28         size_t size_ = 0;
29         size_t pos;
30     }
31 
32     /*
33     * describe: get data from outside untrusted data(data_) which size is according to sizeof(T)
34     * tips: only support basic type
35     */
36     template<class T>
GetData()37     T GetData()
38     {
39         T object {};
40         size_t objectSize = sizeof(object);
41         if (data_ == nullptr || objectSize > size_ - pos) {
42             return object;
43         }
44         errno_t ret = memcpy_s(&object, objectSize, data_ + pos, objectSize);
45         if (ret != EOK) {
46             return {};
47         }
48         pos += objectSize;
49         return object;
50     }
51 
52     /*
53     * get a string from data_
54     */
GetStringFromData(int strlen)55     std::string GetStringFromData(int strlen)
56     {
57         char cstr[strlen];
58         cstr[strlen - 1] = '\0';
59         for (int i = 0; i < strlen - 1; i++) {
60             cstr[i] = GetData<char>();
61         }
62         std::string str(cstr);
63         return str;
64     }
65 
DoSomethingInterestingWithMyAPI(const uint8_t * data,size_t size)66     bool DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size)
67     {
68         if (data == nullptr) {
69             return false;
70         }
71 
72         // initialize
73         data_ = data;
74         size_ = size;
75         pos = 0;
76 
77         // get data
78         uint32_t screenId = GetData<uint32_t>();
79         void* data1 = static_cast<void*>(GetStringFromData(STR_LEN).data());
80         void* data2 = static_cast<void*>(GetStringFromData(STR_LEN).data());
81 
82         // test
83         OutputPtr outputptr = HdiOutput::CreateHdiOutput(screenId);
84         outputptr->Init();
85         std::vector<LayerInfoPtr> layerInfos;
86         LayerInfoPtr layerInfoptr = HdiLayerInfo::CreateHdiLayerInfo();
87         sptr<IConsumerSurface> cSurface = IConsumerSurface::Create();
88         layerInfoptr->SetSurface(cSurface);
89         layerInfos.push_back(layerInfoptr);
90         outputptr->SetLayerInfo(layerInfos);
91 
92         HdiBackend* hdiBackend_ = HdiBackend::GetInstance();
93         auto onScreenHotplugFunc = [](OutputPtr &, bool, void*) -> void {};
94         auto onPrepareCompleteFunc = [](sptr<Surface> &, const struct PrepareCompleteParam &, void*) -> void {};
95         hdiBackend_->RegScreenHotplug(onScreenHotplugFunc, data1);
96         hdiBackend_->RegPrepareComplete(onPrepareCompleteFunc, data2);
97         hdiBackend_->Repaint(outputptr);
98 
99         return true;
100     }
101 }
102 
103 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)104 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
105 {
106     /* Run your code on data */
107     OHOS::DoSomethingInterestingWithMyAPI(data, size);
108     return 0;
109 }
110 
111