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 "screenmanager_fuzzer.h"
17 
18 #include <iostream>
19 #include <securec.h>
20 
21 #include "dm_common.h"
22 #include "screen.h"
23 #include "screen_manager.h"
24 
25 namespace OHOS::Rosen {
26 namespace {
27 constexpr size_t DATA_MIN_SIZE = 32;
28 }
29 class ScreenListener : public ScreenManager::IScreenListener {
30 public:
OnConnect(ScreenId screenId)31     virtual void OnConnect(ScreenId screenId) override
32     {
33     };
34 
OnDisconnect(ScreenId screenId)35     virtual void OnDisconnect(ScreenId screenId) override
36     {
37     }
38 
OnChange(ScreenId screenId)39     virtual void OnChange(ScreenId screenId) override
40     {
41     }
42 };
43 
44 class ScreenGroupListener : public ScreenManager::IScreenGroupListener {
45 public:
OnChange(const std::vector<ScreenId> & screenIds,ScreenGroupChangeEvent event)46     virtual void OnChange(const std::vector<ScreenId>& screenIds, ScreenGroupChangeEvent event) override
47     {
48     }
49 };
50 
51 class VirtualScreenGroupListener : public ScreenManager::IVirtualScreenGroupListener {
52 public:
53     void OnMirrorChange([[maybe_unused]]const ChangeInfo& info) override
54     {
55     }
56 };
57 
58 template<class T>
GetObject(T & object,const uint8_t * data,size_t size)59 size_t GetObject(T &object, const uint8_t *data, size_t size)
60 {
61     size_t objectSize = sizeof(object);
62     if (objectSize > size) {
63         return 0;
64     }
65     return memcpy_s(&object, objectSize, data, objectSize) == EOK ? objectSize : 0;
66 }
67 
ScreenPowerFuzzTest(const uint8_t * data,size_t size)68 bool ScreenPowerFuzzTest(const uint8_t *data, size_t size)
69 {
70     uint32_t screenPowerState;
71     uint32_t powerStateChangeReason;
72     if (data == nullptr || size < sizeof(screenPowerState) + sizeof(powerStateChangeReason)) {
73         return false;
74     }
75     size_t startPos = 0;
76     ScreenManager &screenManager = ScreenManager::GetInstance();
77     sptr<ScreenManager::IScreenListener> screenListener = new ScreenListener();
78     screenManager.RegisterScreenListener(screenListener);
79     sptr<ScreenManager::IScreenGroupListener> screenGroupListener = new ScreenGroupListener();
80     screenManager.RegisterScreenGroupListener(screenGroupListener);
81 
82     startPos += GetObject<uint32_t>(screenPowerState, data + startPos, size - startPos);
83     startPos += GetObject<uint32_t>(powerStateChangeReason, data + startPos, size - startPos);
84     screenManager.SetScreenPowerForAll(static_cast<ScreenPowerState>(screenPowerState),
85         static_cast<PowerStateChangeReason>(startPos));
86     std::vector<sptr<Screen>> allScreen;
87     screenManager.GetAllScreens(allScreen);
88     for (auto screen: allScreen) {
89         screenManager.GetScreenPower(screen->GetId());
90     }
91 
92     screenManager.UnregisterScreenGroupListener(screenGroupListener);
93     screenManager.UnregisterScreenListener(screenListener);
94     return true;
95 }
96 
MakeMirrorWithVirtualScreenFuzzTest(const uint8_t * data,size_t size)97 bool MakeMirrorWithVirtualScreenFuzzTest(const uint8_t *data, size_t size)
98 {
99     if (data == nullptr || size < DATA_MIN_SIZE) {
100         return false;
101     }
102     size_t startPos = 0;
103     ScreenManager &screenManager = ScreenManager::GetInstance();
104     sptr<ScreenManager::IScreenListener> screenListener = new ScreenListener();
105     screenManager.RegisterScreenListener(screenListener);
106     sptr<ScreenManager::IScreenGroupListener> screenGroupListener = new ScreenGroupListener();
107     screenManager.RegisterScreenGroupListener(screenGroupListener);
108     screenManager.UnregisterScreenGroupListener(screenGroupListener);
109     screenManager.UnregisterScreenListener(screenListener);
110 
111     std::string name = "screen";
112     VirtualScreenOption option = { name };
113     startPos += GetObject<uint32_t>(option.width_, data + startPos, size - startPos);
114     startPos += GetObject<uint32_t>(option.height_, data + startPos, size - startPos);
115     startPos += GetObject<float>(option.density_, data + startPos, size - startPos);
116     startPos += GetObject<int32_t>(option.flags_, data + startPos, size - startPos);
117     GetObject<bool>(option.isForShot_, data + startPos, size - startPos);
118     ScreenId screenId = screenManager.CreateVirtualScreen(option);
119 
120     screenManager.SetVirtualScreenSurface(screenId, nullptr);
121 
122     // make mirror
123     ScreenId groupId;
124     screenManager.MakeMirror(0, { screenId }, groupId);
125     if (groupId == SCREEN_ID_INVALID) {
126         screenManager.DestroyVirtualScreen(screenId);
127     }
128     sptr<ScreenGroup> group = screenManager.GetScreenGroup(groupId);
129     if (group == nullptr) {
130         screenManager.DestroyVirtualScreen(screenId);
131         return false;
132     }
133     std::vector<ScreenId> ids = group->GetChildIds();
134     screenManager.RemoveVirtualScreenFromGroup(ids);
135     return true;
136 }
137 
MakeExpandWithVirtualScreenFuzzTest(const uint8_t * data,size_t size)138 bool MakeExpandWithVirtualScreenFuzzTest(const uint8_t *data, size_t size)
139 {
140     if (data == nullptr || size < DATA_MIN_SIZE) {
141         return false;
142     }
143     size_t startPos = 0;
144     ScreenManager &screenManager = ScreenManager::GetInstance();
145     sptr<ScreenManager::IScreenListener> screenListener = new ScreenListener();
146     screenManager.RegisterScreenListener(screenListener);
147     sptr<ScreenManager::IScreenGroupListener> screenGroupListener = new ScreenGroupListener();
148     screenManager.RegisterScreenGroupListener(screenGroupListener);
149     screenManager.UnregisterScreenGroupListener(screenGroupListener);
150     screenManager.UnregisterScreenListener(screenListener);
151 
152     std::string name = "screen";
153     VirtualScreenOption option = { name };
154     startPos += GetObject<uint32_t>(option.width_, data + startPos, size - startPos);
155     startPos += GetObject<uint32_t>(option.height_, data + startPos, size - startPos);
156     startPos += GetObject<float>(option.density_, data + startPos, size - startPos);
157     startPos += GetObject<int32_t>(option.flags_, data + startPos, size - startPos);
158     GetObject<bool>(option.isForShot_, data + startPos, size - startPos);
159     ScreenId screenId = screenManager.CreateVirtualScreen(option);
160 
161     screenManager.SetVirtualScreenSurface(screenId, nullptr);
162     // make expand
163     std::vector<ExpandOption> options = {{0, 0, 0}, {screenId, 0, 0}};
164     ScreenId groupId;
165     screenManager.MakeExpand(options, groupId);
166     if (groupId == SCREEN_ID_INVALID) {
167         screenManager.DestroyVirtualScreen(screenId);
168     }
169     sptr<ScreenGroup> group = screenManager.GetScreenGroup(groupId);
170     if (group == nullptr) {
171         screenManager.DestroyVirtualScreen(screenId);
172         return false;
173     }
174     std::vector<ScreenId> ids = group->GetChildIds();
175     screenManager.RemoveVirtualScreenFromGroup(ids);
176     return true;
177 }
178 
CreateAndDestroyVirtualScreenFuzzTest(const uint8_t * data,size_t size)179 bool CreateAndDestroyVirtualScreenFuzzTest(const uint8_t *data, size_t size)
180 {
181     if (data == nullptr || size < DATA_MIN_SIZE) {
182         return false;
183     }
184     size_t startPos = 0;
185     ScreenManager &screenManager = ScreenManager::GetInstance();
186     sptr<ScreenManager::IScreenListener> screenListener = new ScreenListener();
187     screenManager.RegisterScreenListener(screenListener);
188     sptr<ScreenManager::IScreenGroupListener> screenGroupListener = new ScreenGroupListener();
189     screenManager.RegisterScreenGroupListener(screenGroupListener);
190 
191     std::string name = "screen";
192     VirtualScreenOption option = { name };
193     startPos += GetObject<uint32_t>(option.width_, data + startPos, size - startPos);
194     startPos += GetObject<uint32_t>(option.height_, data + startPos, size - startPos);
195     startPos += GetObject<float>(option.density_, data + startPos, size - startPos);
196     startPos += GetObject<int32_t>(option.flags_, data + startPos, size - startPos);
197     startPos += GetObject<bool>(option.isForShot_, data + startPos, size - startPos);
198     ScreenId screenId = screenManager.CreateVirtualScreen(option);
199 
200     screenManager.UnregisterScreenGroupListener(screenGroupListener);
201     screenManager.UnregisterScreenListener(screenListener);
202     screenManager.GetScreenById(screenId);
203     screenManager.DestroyVirtualScreen(screenId);
204     return true;
205 }
206 
SetVirtualScreenSurfaceFuzzTest(const uint8_t * data,size_t size)207 bool SetVirtualScreenSurfaceFuzzTest(const uint8_t *data, size_t size)
208 {
209     ScreenId screenId;
210     if (data == nullptr || size < sizeof(screenId)) {
211         return false;
212     }
213     size_t startPos = 0;
214     ScreenManager &screenManager = ScreenManager::GetInstance();
215     GetObject<ScreenId>(screenId, data + startPos, size - startPos);
216     screenManager.SetVirtualScreenSurface(screenId, nullptr);
217     return true;
218 }
219 
SetScreenRotationLockedFuzzTest(const uint8_t * data,size_t size)220 bool SetScreenRotationLockedFuzzTest(const uint8_t *data, size_t size)
221 {
222     ScreenId screenId;
223     if (data == nullptr || size < sizeof(screenId)) {
224         return false;
225     }
226     size_t startPos = 0;
227     ScreenManager &screenManager = ScreenManager::GetInstance();
228     bool flag = true;
229     startPos += GetObject<bool>(flag, data + startPos, size - startPos);
230     screenManager.SetScreenRotationLocked(flag);
231     return true;
232 }
233 
IsScreenRotationLocked(const uint8_t * data,size_t size)234 bool IsScreenRotationLocked(const uint8_t *data, size_t size)
235 {
236     ScreenId screenId;
237     if (data == nullptr || size < sizeof(screenId)) {
238         return false;
239     }
240     size_t startPos = 0;
241     ScreenManager &screenManager = ScreenManager::GetInstance();
242     bool flag = true;
243     startPos += GetObject<bool>(flag, data + startPos, size - startPos);
244     screenManager.IsScreenRotationLocked(flag);
245     return true;
246 }
247 
RemoveVirtualScreenFromGroupFuzzTest(const uint8_t * data,size_t size)248 bool RemoveVirtualScreenFromGroupFuzzTest(const uint8_t *data, size_t size)
249 {
250     ScreenId screenId;
251     if (data == nullptr || size < sizeof(screenId)) {
252         return false;
253     }
254     size_t startPos = 0;
255     ScreenManager &screenManager = ScreenManager::GetInstance();
256     GetObject<ScreenId>(screenId, data + startPos, size - startPos);
257     std::vector<ScreenId> screenIds = {screenId, screenId, screenId};
258     screenManager.RemoveVirtualScreenFromGroup(screenIds);
259     return true;
260 }
261 
MakeMirrorFuzzTest(const uint8_t * data,size_t size)262 bool MakeMirrorFuzzTest(const uint8_t *data, size_t size)
263 {
264     ScreenId screenId;
265     // 10 screens.
266     if (data == nullptr || size < sizeof(ScreenId)) {
267         return false;
268     }
269     size_t startPos = 0;
270     ScreenManager &screenManager = ScreenManager::GetInstance();
271     sptr<ScreenManager::IScreenListener> screenListener = new ScreenListener();
272     screenManager.RegisterScreenListener(screenListener);
273     sptr<ScreenManager::IScreenGroupListener> screenGroupListener = new ScreenGroupListener();
274     screenManager.RegisterScreenGroupListener(screenGroupListener);
275 
276     std::vector<ScreenId> screenIds;
277     // 10 screens
278     for (size_t i = 0; i < 10; i++) {
279         startPos += GetObject<ScreenId>(screenId, data + startPos, size - startPos);
280         screenIds.emplace_back(screenId);
281     }
282     ScreenId screenGroupId;
283     GetObject<ScreenId>(screenId, data + startPos, size - startPos);
284     screenManager.MakeMirror(screenId, screenIds, screenGroupId);
285     screenManager.UnregisterScreenGroupListener(screenGroupListener);
286     screenManager.UnregisterScreenListener(screenListener);
287     return true;
288 }
289 
MakeExpandFuzzTest(const uint8_t * data,size_t size)290 bool MakeExpandFuzzTest(const uint8_t *data, size_t size)
291 {
292     ScreenId screenId;
293     // 10 screens.
294     if (data == nullptr || size < sizeof(ScreenId)) {
295         return false;
296     }
297     size_t startPos = 0;
298     ScreenManager &screenManager = ScreenManager::GetInstance();
299     sptr<ScreenManager::IScreenListener> screenListener = new ScreenListener();
300     startPos += GetObject<ScreenId>(screenId, data + startPos, size - startPos);
301     screenListener->OnConnect(screenId);
302     screenListener->OnDisconnect(screenId);
303     screenListener->OnChange(screenId);
304     screenManager.RegisterScreenListener(screenListener);
305     sptr<ScreenManager::IScreenGroupListener> screenGroupListener = new ScreenGroupListener();
306     screenManager.RegisterScreenGroupListener(screenGroupListener);
307     std::vector<ExpandOption> options;
308     // 10 screens
309     for (size_t i = 0; i < 10; i++) {
310         startPos += GetObject<ScreenId>(screenId, data + startPos, size - startPos);
311         ExpandOption option = {screenId, 0, 0};
312         options.emplace_back(option);
313     }
314     ScreenId screenGroupId;
315     screenManager.MakeExpand(options, screenGroupId);
316     screenManager.UnregisterScreenGroupListener(screenGroupListener);
317     screenManager.UnregisterScreenListener(screenListener);
318     sptr<ScreenManager::IVirtualScreenGroupListener> virtualScreenGroupListener = new VirtualScreenGroupListener();
319     screenManager.RegisterVirtualScreenGroupListener(virtualScreenGroupListener);
320     screenManager.UnregisterVirtualScreenGroupListener(virtualScreenGroupListener);
321     return true;
322 }
323 } // namespace.OHOS::Rosen
324 
325 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)326 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
327 {
328     /* Run your code on data */
329     OHOS::Rosen::ScreenPowerFuzzTest(data, size);
330     OHOS::Rosen::MakeMirrorWithVirtualScreenFuzzTest(data, size);
331     OHOS::Rosen::MakeMirrorFuzzTest(data, size);
332     OHOS::Rosen::MakeExpandWithVirtualScreenFuzzTest(data, size);
333     OHOS::Rosen::MakeExpandFuzzTest(data, size);
334     OHOS::Rosen::CreateAndDestroyVirtualScreenFuzzTest(data, size);
335     OHOS::Rosen::SetVirtualScreenSurfaceFuzzTest(data, size);
336     OHOS::Rosen::RemoveVirtualScreenFromGroupFuzzTest(data, size);
337     OHOS::Rosen::SetScreenRotationLockedFuzzTest(data, size);
338     OHOS::Rosen::IsScreenRotationLocked(data, size);
339     return 0;
340 }
341 
342