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 <refbase.h>
17 #include <parcel.h>
18 #include <securec.h>
19
20 #include "windowroot_fuzzer.h"
21
22 #include "display_info.h"
23 #include "display_manager.h"
24 #include "marshalling_helper.h"
25 #include "window.h"
26 #include "window_node.h"
27 #include "window_root.h"
28 #include "window_manager.h"
29 #include "window_manager_service.h"
30 #include "window_scene.h"
31 #include "window_dumper.h"
32
33 using namespace OHOS::Rosen;
34
35 namespace OHOS {
36 namespace {
37 constexpr size_t DATA_MIN_SIZE = 2;
38 constexpr size_t VECTOR_MAX_LEN = 4;
39 }
40
41 template<class T>
GetObject(T & object,const uint8_t * data,size_t size)42 size_t GetObject(T &object, const uint8_t *data, size_t size)
43 {
44 size_t objectSize = sizeof(object);
45 if (objectSize > size) {
46 return 0;
47 }
48 return memcpy_s(&object, objectSize, data, objectSize) == EOK ? objectSize : 0;
49 }
50
CreateWindowNode(const std::string & windowName,const uint8_t * data,size_t size)51 sptr<WindowNode> CreateWindowNode(const std::string& windowName,
52 const uint8_t *data, size_t size)
53 {
54 sptr<OHOS::Rosen::WindowProperty> property = nullptr;
55 Parcel parcel;
56 if (parcel.WriteBuffer(data, size)) {
57 property = OHOS::Rosen::WindowProperty::Unmarshalling(parcel);
58 }
59
60 sptr<OHOS::Rosen::WindowNode> windowNode = new OHOS::Rosen::WindowNode(property);
61 if (windowNode == nullptr) {
62 return nullptr;
63 }
64 return windowNode;
65 }
66
CreateDisplayInfo(const uint8_t * data,size_t size)67 sptr<OHOS::Rosen::DisplayInfo> CreateDisplayInfo(const uint8_t *data, size_t size)
68 {
69 sptr<OHOS::Rosen::DisplayInfo> displayInfo = nullptr;
70 Parcel parcel;
71 if (parcel.WriteBuffer(data, size)) {
72 displayInfo = OHOS::Rosen::DisplayInfo::Unmarshalling(parcel);
73 }
74 return displayInfo;
75 }
76
WindowRootFuzzPart1(sptr<WindowRoot> windowRoot,sptr<WindowNode> windowNode,const uint8_t * data,size_t size)77 void WindowRootFuzzPart1(sptr<WindowRoot> windowRoot, sptr<WindowNode> windowNode,
78 const uint8_t *data, size_t size)
79 {
80 if (windowRoot == nullptr || windowNode == nullptr || data == nullptr || size < DATA_MIN_SIZE) {
81 return;
82 }
83 size_t startPos = 0;
84 OHOS::Rosen::DisplayId displayId;
85 startPos += GetObject<OHOS::Rosen::DisplayId>(displayId, data + startPos, size - startPos);
86 windowRoot->GetOrCreateWindowNodeContainer(displayId);
87 windowRoot->GetWindowNodeContainer(displayId);
88
89 auto displayInfo = CreateDisplayInfo(data, size);
90 windowRoot->CreateWindowNodeContainer(displayInfo);
91
92 uint32_t windowId;
93 startPos += GetObject<uint32_t>(windowId, data + startPos, size - startPos);
94 windowRoot->GetWindowNode(windowId);
95
96 std::vector<sptr<OHOS::Rosen::WindowNode>> windowNodes;
97 OHOS::Rosen::ScreenId screenGroupId;
98 startPos += GetObject<OHOS::Rosen::ScreenId>(screenGroupId, data + startPos, size - startPos);
99 windowRoot->GetBackgroundNodesByScreenId(screenGroupId, windowNodes);
100
101 windowRoot->FindWindowNodeWithToken(windowNode->abilityToken_);
102
103 bool fromStartingWin;
104 startPos += GetObject<bool>(fromStartingWin, data + startPos, size - startPos);
105 windowRoot->AddWindowNode(windowNode->GetParentId(), windowNode, fromStartingWin);
106
107 OHOS::Rosen::WindowUpdateReason reason;
108 startPos += GetObject<OHOS::Rosen::WindowUpdateReason>(reason, data + startPos, size - startPos);
109 windowRoot->UpdateWindowNode(windowNode->GetWindowId(), reason);
110
111 uint64_t surfaceNodeId;
112 GetObject<uint64_t>(surfaceNodeId, data + startPos, size - startPos);
113 windowRoot->AddSurfaceNodeIdWindowNodePair(surfaceNodeId, windowNode);
114
115 windowRoot->IsVerticalDisplay(windowNode);
116
117 windowRoot->RemoveWindowNode(windowNode->GetWindowId(), fromStartingWin);
118 }
119
WindowRootFuzzPart2(sptr<WindowRoot> windowRoot,sptr<WindowNode> windowNode,const uint8_t * data,size_t size)120 void WindowRootFuzzPart2(sptr<WindowRoot> windowRoot, sptr<WindowNode> windowNode,
121 const uint8_t *data, size_t size)
122 {
123 if (windowRoot == nullptr || windowNode == nullptr || data == nullptr || size < DATA_MIN_SIZE) {
124 return;
125 }
126 size_t startPos = 0;
127 DisplayId displayId;
128 startPos += GetObject<DisplayId>(displayId, data + startPos, size - startPos);
129
130 windowRoot->IsForbidDockSliceMove(displayId);
131 windowRoot->IsDockSliceInExitSplitModeArea(displayId);
132 windowRoot->ExitSplitMode(displayId);
133
134 windowRoot->RequestFocus(windowNode->GetWindowId());
135 windowRoot->RequestActiveWindow(windowNode->GetWindowId());
136
137 windowRoot->MinimizeStructuredAppWindowsExceptSelf(windowNode);
138
139 AvoidAreaType avoidAreaType;
140 startPos += GetObject<AvoidAreaType>(avoidAreaType, data + startPos, size - startPos);
141 windowRoot->GetAvoidAreaByType(windowNode->GetWindowId(), avoidAreaType);
142
143 WindowMode dstMode;
144 startPos += GetObject<WindowMode>(dstMode, data + startPos, size - startPos);
145 windowRoot->SetWindowMode(windowNode, dstMode);
146
147 uint32_t mainWinId;
148 uint32_t topWinId;
149 startPos += GetObject<uint32_t>(mainWinId, data + startPos, size - startPos);
150 startPos += GetObject<uint32_t>(topWinId, data + startPos, size - startPos);
151 windowRoot->GetTopWindowId(mainWinId, topWinId);
152
153 startPos += GetObject<DisplayId>(displayId, data + startPos, size - startPos);
154 windowRoot->MinimizeAllAppWindows(displayId);
155
156 windowRoot->ToggleShownStateForAllAppWindows();
157
158 WindowLayoutMode windowLayoutMode;
159 startPos += GetObject<WindowLayoutMode>(windowLayoutMode, data + startPos, size - startPos);
160 windowRoot->SetWindowLayoutMode(displayId, windowLayoutMode);
161
162 WindowState windowState;
163 WindowStateChangeReason windowStateChangeReason;
164 startPos += GetObject<WindowState>(windowState, data + startPos, size - startPos);
165 GetObject<WindowStateChangeReason>(windowStateChangeReason, data + startPos, size - startPos);
166 windowRoot->ProcessWindowStateChange(windowState, windowStateChangeReason);
167 }
168
WindowRootFuzzPart3(sptr<WindowRoot> windowRoot,sptr<WindowNode> windowNode,const uint8_t * data,size_t size)169 void WindowRootFuzzPart3(sptr<WindowRoot> windowRoot, sptr<WindowNode> windowNode,
170 const uint8_t *data, size_t size)
171 {
172 if (windowRoot == nullptr || windowNode == nullptr || data == nullptr || size < DATA_MIN_SIZE) {
173 return;
174 }
175 size_t startPos = 0;
176 windowRoot->RaiseZOrderForAppWindow(windowNode);
177
178 DisplayId displayId;
179 startPos += GetObject<DisplayId>(displayId, data + startPos, size - startPos);
180 windowRoot->GetVirtualPixelRatio(displayId);
181 windowRoot->GetDisplayGroupRect(displayId);
182
183 WindowSizeChangeReason windowSizeChangeReason;
184 startPos += GetObject<WindowSizeChangeReason>(windowSizeChangeReason, data + startPos, size - startPos);
185 windowRoot->UpdateSizeChangeReason(windowNode->GetWindowId(), windowSizeChangeReason);
186
187 float brightNess;
188 startPos += GetObject<float>(brightNess, data + startPos, size - startPos);
189 windowRoot->SetBrightness(windowNode->GetWindowId(), brightNess);
190
191 windowRoot->UpdateFocusableProperty(windowNode->GetWindowId());
192 bool requireLock;
193 startPos += GetObject<bool>(requireLock, data + startPos, size - startPos);
194
195 windowRoot->HandleKeepScreenOn(windowNode->GetWindowId(), requireLock);
196
197 uint32_t windowNum;
198 startPos += GetObject<uint32_t>(windowNum, data + startPos, size - startPos);
199 windowRoot->SetMaxAppWindowNumber(windowNum);
200
201 uint32_t uniAppWindowNum;
202 startPos += GetObject<uint32_t>(uniAppWindowNum, data + startPos, size - startPos);
203 windowRoot->SetMaxUniRenderAppWindowNumber(uniAppWindowNum);
204
205 ModeChangeHotZones hotZones;
206 ModeChangeHotZonesConfig config;
207 startPos += GetObject<ModeChangeHotZones>(hotZones, data + startPos, size - startPos);
208 startPos += GetObject<ModeChangeHotZonesConfig>(config, data + startPos, size - startPos);
209 windowRoot->GetModeChangeHotZones(displayId, hotZones, config);
210
211 std::vector<float> splitRatioNumbers;
212 for (size_t i = 0; i < VECTOR_MAX_LEN; i++) {
213 float value;
214 startPos += GetObject<float>(value, data + startPos, size - startPos);
215 splitRatioNumbers.emplace_back(value);
216 }
217 windowRoot->SetSplitRatios(splitRatioNumbers);
218 windowRoot->SetExitSplitRatios(splitRatioNumbers);
219 }
220
WindowRootFuzzPart4(sptr<WindowRoot> windowRoot,sptr<WindowNode> windowNode,const uint8_t * data,size_t size)221 void WindowRootFuzzPart4(sptr<WindowRoot> windowRoot, sptr<WindowNode> windowNode,
222 const uint8_t *data, size_t size)
223 {
224 if (windowRoot == nullptr || windowNode == nullptr || data == nullptr || size < DATA_MIN_SIZE) {
225 return;
226 }
227 size_t startPos = 0;
228
229 DisplayId displayId;
230 startPos += GetObject<DisplayId>(displayId, data + startPos, size - startPos);
231 windowRoot->HasPrivateWindow(displayId);
232 windowRoot->GetDisplayRectWithoutSystemBarAreas(displayId);
233 windowRoot->GetSplitScreenWindowNodes(displayId);
234 windowRoot->GetAllDisplayIds();
235 windowRoot->GetTotalWindowNum();
236
237 bool isUniRender;
238 startPos += GetObject<bool>(isUniRender, data + startPos, size - startPos);
239 windowRoot->OnRenderModeChanged(isUniRender);
240
241 windowRoot->TakeWindowPairSnapshot(displayId);
242 windowRoot->ClearWindowPairSnapshot(displayId);
243
244 std::vector<wptr<WindowNode>> windowNodes;
245 windowNodes.emplace_back(windowNode);
246 windowRoot->GetAllAnimationPlayingNodes(windowNodes);
247
248 std::vector<sptr<WindowVisibilityInfo>> infos;
249 for (size_t i = 0; i < VECTOR_MAX_LEN; i++) {
250 sptr<WindowVisibilityInfo> visibilityInfo = nullptr;
251 Parcel parcel;
252 if (parcel.WriteBuffer(data, size)) {
253 visibilityInfo = WindowVisibilityInfo::Unmarshalling(parcel);
254 }
255 if (visibilityInfo != nullptr) {
256 infos.emplace_back(visibilityInfo);
257 }
258 }
259 windowRoot->GetVisibilityWindowInfo(infos);
260 infos.clear();
261
262 int accountId;
263 GetObject<int>(accountId, data + startPos, size - startPos);
264 windowRoot->RemoveSingleUserWindowNodes(accountId);
265
266 windowRoot->NotifySystemBarTints();
267
268 windowRoot->FocusFaultDetection();
269 windowRoot->GetMaxUniRenderAppWindowNumber();
270
271 windowRoot->GetWindowForDumpAceHelpInfo();
272 windowRoot->DestroyLeakStartingWindow();
273 }
274
WindowRootFuzzPart5(sptr<WindowRoot> windowRoot,sptr<WindowNode> windowNode,const uint8_t * data,size_t size)275 void WindowRootFuzzPart5(sptr<WindowRoot> windowRoot, sptr<WindowNode> windowNode,
276 const uint8_t *data, size_t size)
277 {
278 if (windowRoot == nullptr || windowNode == nullptr || data == nullptr || size < DATA_MIN_SIZE) {
279 return;
280 }
281 size_t startPos = 0;
282 std::vector<uint32_t> windowIds;
283 for (size_t i = 0; i < VECTOR_MAX_LEN; i++) {
284 uint32_t value;
285 startPos += GetObject<uint32_t>(value, data + startPos, size - startPos);
286 windowIds.emplace_back(value);
287 }
288 windowRoot->MinimizeTargetWindows(windowIds);
289 windowRoot->UpdateRsTree(windowNode->GetWindowId(), false);
290
291 windowRoot->SwitchRenderModeIfNeeded();
292 windowRoot->IsUniRender();
293
294 bool afterAnimation;
295 GetObject<bool>(afterAnimation, data + startPos, size - startPos);
296 windowRoot->LayoutWhenAddWindowNode(windowNode, afterAnimation);
297 }
298
WindowRootFuzzPart6(sptr<WindowRoot> windowRoot,sptr<WindowNode> windowNode,const uint8_t * data,size_t size)299 void WindowRootFuzzPart6(sptr<WindowRoot> windowRoot, sptr<WindowNode> windowNode,
300 const uint8_t *data, size_t size)
301 {
302 if (windowRoot == nullptr || windowNode == nullptr || data == nullptr || size < DATA_MIN_SIZE) {
303 return;
304 }
305 size_t startPos = 0;
306
307 windowRoot->GenAllWindowsLogInfo();
308 DisplayId displayId;
309 bool isRecordedDisplay;
310 startPos += GetObject<DisplayId>(displayId, data + startPos, size - startPos);
311 startPos += GetObject<bool>(isRecordedDisplay, data + startPos, size - startPos);
312
313 windowRoot->GetScreenGroupId(displayId, isRecordedDisplay);
314
315 std::vector<DisplayId> infos;
316 for (size_t i = 0; i < VECTOR_MAX_LEN; i++) {
317 DisplayId disId;
318 startPos += GetObject<DisplayId>(disId, data + startPos, size - startPos);
319 infos.emplace_back(disId);
320 }
321 windowRoot->GetAllDisplayInfos(infos);
322
323 DisplayId defaultDisplayId;
324 startPos += GetObject<DisplayId>(defaultDisplayId, data + startPos, size - startPos);
325 windowRoot->MoveNotShowingWindowToDefaultDisplay(defaultDisplayId, displayId);
326
327 bool isToUnified;
328 GetObject<bool>(isToUnified, data + startPos, size - startPos);
329 windowRoot->ChangeRSRenderModeIfNeeded(isToUnified);
330 windowRoot->IsAppWindowExceed();
331 }
332
DoFuzzTest(const uint8_t * data,size_t size)333 void DoFuzzTest(const uint8_t* data, size_t size)
334 {
335 if (data == nullptr || size < DATA_MIN_SIZE) {
336 return;
337 }
338 auto windowRoot = OHOS::Rosen::WindowManagerService::GetInstance().windowRoot_;
339 auto windowNode = CreateWindowNode("TestWindowNode", data, size);
340 if (windowNode == nullptr || windowRoot == nullptr) {
341 return;
342 }
343 windowRoot->SaveWindow(windowNode);
344
345 OHOS::WindowRootFuzzPart1(windowRoot, windowNode, data, size);
346 OHOS::WindowRootFuzzPart2(windowRoot, windowNode, data, size);
347 OHOS::WindowRootFuzzPart3(windowRoot, windowNode, data, size);
348 OHOS::WindowRootFuzzPart4(windowRoot, windowNode, data, size);
349 OHOS::WindowRootFuzzPart5(windowRoot, windowNode, data, size);
350 OHOS::WindowRootFuzzPart6(windowRoot, windowNode, data, size);
351
352 windowRoot->DestroyWindow(windowNode->GetWindowId(), false);
353 windowRoot->surfaceIdWindowNodeMap_.clear();
354 }
355 } // namespace.OHOS
356
357 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)358 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
359 {
360 /* Run your code on data */
361 OHOS::DoFuzzTest(data, size);
362 return 0;
363 }
364
365