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