1 /*
2 * Copyright (c) 2022-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 "ressched_fuzzer.h"
17
18 #include <cstddef>
19 #include <cstdint>
20 #include <cstdlib>
21 #include <securec.h>
22 #include <vector>
23 #include <unordered_set>
24 #include <random>
25
26 #include "iremote_stub.h"
27 #include "ires_sched_service.h"
28 #include "iservice_registry.h"
29 #include "oobe_datashare_utils.h"
30 #include "oobe_manager.h"
31 #include "ioobe_task.h"
32 #include "plugin_mgr.h"
33 #include "res_sched_service.h"
34 #include "scene_recognizer_mgr.h"
35 #include "singleton.h"
36 #include "system_ability_definition.h"
37 #include "slide_recognizer.h"
38 #include "ffrt_inner.h"
39 #include "res_sched_client.h"
40 #include "res_sched_service_stub.h"
41 #include "res_sched_systemload_notifier_client.h"
42 #include "res_sched_systemload_notifier_proxy.h"
43 #include "notifier_mgr.h"
44 #include "res_type.h"
45 #include "accesstoken_kit.h"
46 #include "token_setproc.h"
47 #include <fuzzer/FuzzedDataProvider.h>
48
49 #define private public
50 #define protected public
51
52 #ifndef errno_t
53 typedef int errno_t;
54 #endif
55
56 #ifndef EOK
57 #define EOK 0
58 #endif
59
60 namespace OHOS {
61 namespace ResourceSchedule {
62 namespace {
63 static const int32_t TWO_PARAMETERS = 2;
64 static const int32_t TIME_SECOND = 1000000;
65
66 static const std::unordered_set<uint32_t> THIRDPARTY_RES = {
67 ResType::RES_TYPE_CLICK_RECOGNIZE,
68 ResType::RES_TYPE_PUSH_PAGE,
69 ResType::RES_TYPE_SLIDE_RECOGNIZE,
70 ResType::RES_TYPE_POP_PAGE,
71 ResType::RES_TYPE_LOAD_PAGE,
72 ResType::RES_TYPE_WEB_GESTURE,
73 ResType::RES_TYPE_REPORT_KEY_THREAD,
74 ResType::RES_TYPE_REPORT_WINDOW_STATE,
75 ResType::RES_TYPE_REPORT_SCENE_SCHED,
76 ResType::RES_TYPE_WEB_GESTURE_MOVE,
77 ResType::RES_TYPE_WEB_SLIDE_NORMAL,
78 ResType::RES_TYPE_LOAD_URL,
79 ResType::RES_TYPE_MOUSEWHEEL,
80 ResType::RES_TYPE_WEBVIEW_AUDIO_STATUS_CHANGE,
81 ResType::RES_TYPE_REPORT_RENDER_THREAD,
82 ResType::RES_TYPE_LONG_FRAME,
83 ResType::RES_TYPE_REPORT_DISTRIBUTE_TID,
84 ResType::RES_TYPE_WEBVIEW_SCREEN_CAPTURE,
85 ResType::RES_TYPE_WEBVIEW_VIDEO_STATUS_CHANGE,
86 ResType::RES_TYPE_BT_SERVICE_EVENT
87 };
88
89 static const std::unordered_map<uint32_t, std::vector<std::string>> RESTYPE_TO_PARAMS = {
90 {ResType::RES_TYPE_CLICK_RECOGNIZE, {"clientPid", "name"}},
91 {ResType::RES_TYPE_PUSH_PAGE, {"pageUrl"}},
92 {ResType::RES_TYPE_SLIDE_RECOGNIZE, {"clientPid"}},
93 {ResType::RES_TYPE_POP_PAGE, {}},
94 {ResType::RES_TYPE_LOAD_PAGE, {}},
95 {ResType::RES_TYPE_WEB_GESTURE, {}},
96 {ResType::RES_TYPE_REPORT_KEY_THREAD, {"uid", "pid", "tid", "role"}},
97 {ResType::RES_TYPE_REPORT_WINDOW_STATE, {"uid", "pid", "windowId", "serialNum", "state"}},
98 {ResType::RES_TYPE_REPORT_SCENE_SCHED, {"uid", "sceneId"}},
99 {ResType::RES_TYPE_WEB_GESTURE_MOVE, {}},
100 {ResType::RES_TYPE_WEB_SLIDE_NORMAL, {}},
101 {ResType::RES_TYPE_LOAD_URL, {}},
102 {ResType::RES_TYPE_MOUSEWHEEL, {}},
103 {ResType::RES_TYPE_WEBVIEW_AUDIO_STATUS_CHANGE, {"uid", "pid", "tid"}},
104 {ResType::RES_TYPE_REPORT_RENDER_THREAD, {"uid", "pid"}},
105 {ResType::RES_TYPE_LONG_FRAME, {"pid", "uid", "bundleName", "abilityName"}},
106 {ResType::RES_TYPE_REPORT_DISTRIBUTE_TID, {"uid", "pid"}},
107 {ResType::RES_TYPE_WEBVIEW_SCREEN_CAPTURE, {"uid", "pid"}},
108 {ResType::RES_TYPE_WEBVIEW_VIDEO_STATUS_CHANGE, {"uid", "pid"}},
109 {ResType::RES_TYPE_BT_SERVICE_EVENT, {"ADDRESS", "STATE", "ROLE", "CONNECTIF", "STATUS"}}
110 };
111
112 static const int32_t DEFAULT_API_VERSION = 11;
113 static const int32_t PAYLOAD_MAX_SIZE = 3500;
114
115 Security::AccessToken::PermissionStateFull HapState = {
116 .permissionName = "",
117 .isGeneral = true,
118 .resDeviceID = {"local"},
119 .grantStatus = {Security::AccessToken::PermissionState::PERMISSION_GRANTED},
120 .grantFlags = {1}
121 };
122
123 Security::AccessToken::HapPolicyParams HapPolicyParams = {
124 .apl = Security::AccessToken::APL_SYSTEM_BASIC,
125 .domain = "test.domain.ressched",
126 .permList = {},
127 .permStateList = {HapState}
128 };
129
130 Security::AccessToken::HapInfoParams info = {
131 .userID = 100,
132 .bundleName = "com.hos.ressched",
133 .instIndex = 0,
134 .appIDDesc = "thirdParty",
135 .apiVersion = DEFAULT_API_VERSION,
136 .isSystemApp = false
137 };
138 }
139
140 constexpr int32_t MAX_CODE = 5;
141 constexpr int32_t MIN_LEN = 4;
142 std::mutex mutexLock;
143 sptr<IRemoteObject> remoteObj;
144
DoInit()145 bool DoInit()
146 {
147 std::lock_guard<std::mutex> lock(mutexLock);
148 if (remoteObj) {
149 return true;
150 }
151 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
152 if (!samgr) {
153 return false;
154 }
155 remoteObj = samgr->GetSystemAbility(RES_SCHED_SYS_ABILITY_ID);
156 if (!remoteObj) {
157 return false;
158 }
159 return true;
160 }
161
onRemoteRequest(uint32_t code,MessageParcel & data)162 int32_t onRemoteRequest(uint32_t code, MessageParcel& data)
163 {
164 if (!DoInit()) {
165 return -1;
166 }
167 MessageParcel reply;
168 MessageOption option;
169 return remoteObj->SendRequest(code, data, reply, option);
170 }
171
DoSomethingInterestingWithMyAPI(FuzzedDataProvider * fdp)172 bool DoSomethingInterestingWithMyAPI(FuzzedDataProvider* fdp)
173 {
174 MessageParcel dataMessageParcel;
175 if (!dataMessageParcel.WriteInterfaceToken(IRemoteStub<IResSchedService>::GetDescriptor())) {
176 return false;
177 }
178
179 uint32_t code = fdp->ConsumeIntegral<uint32_t>();
180 std::string data = fdp->ConsumeRandomLengthString();
181 dataMessageParcel.WriteBuffer(data.c_str(), data.size());
182 dataMessageParcel.RewindRead(0);
183
184 onRemoteRequest(code, dataMessageParcel);
185 return true;
186 }
187
OnRemoteRequest(FuzzedDataProvider * fdp)188 bool OnRemoteRequest(FuzzedDataProvider* fdp)
189 {
190 // getdata
191 uint32_t fuzzCode = fdp->ConsumeIntegral<uint32_t>();
192 std::string data = fdp->ConsumeRandomLengthString();
193 MessageParcel fuzzData;
194 fuzzData.WriteInterfaceToken(ResSchedServiceStub::GetDescriptor());
195 fuzzData.WriteBuffer(data.c_str(), data.size());
196 fuzzData.RewindRead(0);
197 MessageParcel fuzzReply;
198 MessageOption fuzzOption;
199 DelayedSingleton<ResSchedService>::GetInstance()->OnRemoteRequest(fuzzCode % MAX_CODE,
200 fuzzData, fuzzReply, fuzzOption);
201 return true;
202 }
203
ResSchedClientFuzzTest(FuzzedDataProvider * fdp)204 bool ResSchedClientFuzzTest(FuzzedDataProvider* fdp)
205 {
206 uint32_t resType = fdp->ConsumeIntegral<uint32_t>();
207 int64_t value = fdp->ConsumeIntegral<int64_t>();
208 std::unordered_map<std::string, std::string> mapPayload;
209 mapPayload["pid"] = fdp->ConsumeRandomLengthString();
210 mapPayload["processName"] = fdp->ConsumeRandomLengthString();
211
212 ResSchedClient::GetInstance().ReportData(resType, value, mapPayload);
213 ResSchedClient::GetInstance().KillProcess(mapPayload);
214 ResSchedClient::GetInstance().StopRemoteObject();
215
216 sptr<ResSchedSystemloadNotifierClient> callbackObj;
217 ResSchedClient::GetInstance().RegisterSystemloadNotifier(callbackObj);
218 ResSchedClient::GetInstance().UnRegisterSystemloadNotifier(callbackObj);
219 ResSchedClient::GetInstance().GetSystemloadLevel();
220 return true;
221 }
222
OnSystemloadLevelFuzzTest(FuzzedDataProvider * fdp)223 bool OnSystemloadLevelFuzzTest(FuzzedDataProvider* fdp)
224 {
225 int32_t level = fdp->ConsumeIntegral<int32_t>();
226 if (!DoInit()) {
227 return false;
228 }
229 auto resSchedSystemloadNotifierProxy = std::make_unique<ResSchedSystemloadNotifierProxy>(remoteObj);
230 resSchedSystemloadNotifierProxy->OnSystemloadLevel(level);
231 return true;
232 }
233
NotifierMgrFuzzTest(FuzzedDataProvider * fdp)234 bool NotifierMgrFuzzTest(FuzzedDataProvider* fdp)
235 {
236 int32_t pid = fdp->ConsumeIntegral<int32_t>();
237 int32_t type = fdp->ConsumeIntegral<int32_t>();
238 int32_t level = fdp->ConsumeIntegral<int32_t>();
239 int32_t state = fdp->ConsumeIntegral<int32_t>();
240 if (!DoInit()) {
241 return false;
242 }
243
244 NotifierMgr::GetInstance().Init();
245 NotifierMgr::GetInstance().RegisterNotifier(pid, remoteObj);
246 NotifierMgr::GetInstance().UnRegisterNotifier(pid);
247 NotifierMgr::GetInstance().OnRemoteNotifierDied(remoteObj);
248 NotifierMgr::GetInstance().OnDeviceLevelChanged(type, level);
249 NotifierMgr::GetInstance().OnApplicationStateChange(state, level);
250 NotifierMgr::GetInstance().GetSystemloadLevel();
251 NotifierMgr::GetInstance().DumpRegisterInfo();
252 NotifierMgr::GetInstance().Deinit();
253 return true;
254 }
255
SlideRecognizerFuzzTest(FuzzedDataProvider * fdp)256 bool SlideRecognizerFuzzTest(FuzzedDataProvider* fdp)
257 {
258 uint32_t resType = fdp->ConsumeIntegral<uint32_t>();
259 int64_t value = fdp->ConsumeIntegral<int64_t>();
260 nlohmann::json payload;
261 auto slideRecognizer = std::make_shared<SlideRecognizer>();
262 slideRecognizer->SetListFlingTimeoutTime(TIME_SECOND);
263 slideRecognizer->SetListFlingEndTime(TIME_SECOND);
264 slideRecognizer->OnDispatchResource(resType, value, payload);
265 slideRecognizer->HandleSlideDetecting(payload);
266 slideRecognizer->HandleSlideEvent(value, payload);
267 slideRecognizer->HandleListFlingStart(payload);
268 slideRecognizer->HandleSendFrameEvent(payload);
269 slideRecognizer->HandleClickEvent(value, payload);
270 slideRecognizer->HandleSlideOFFEvent();
271 if (slideRecognizer->listFlingEndTask_) {
272 ffrt::skip(slideRecognizer->listFlingEndTask_);
273 }
274 if (slideRecognizer->listFlingTimeOutTask_) {
275 ffrt::skip(slideRecognizer->listFlingTimeOutTask_);
276 }
277 auto lastTask = SceneRecognizerMgr::GetInstance().ffrtQueue_->submit_h([]() {});
278 SceneRecognizerMgr::GetInstance().ffrtQueue_->wait(lastTask);
279 return true;
280 }
281
OOBEManagerFuzzTest(FuzzedDataProvider * fdp)282 bool OOBEManagerFuzzTest(FuzzedDataProvider* fdp)
283 {
284 std::string key = fdp->ConsumeRandomLengthString();
285 OOBEManager::ResDataAbilityObserver::UpdateFunc updateFunc = [&]() {};
286 if (!DoInit()) {
287 return false;
288 }
289
290 OOBEManager::GetInstance().GetOOBValue();
291 OOBEManager::GetInstance().RegisterObserver(key, updateFunc);
292 OOBEManager::GetInstance().UnregisterObserver();
293 sptr<OOBEManager::ResDataAbilityObserver> oobeObserver = new OOBEManager::ResDataAbilityObserver();
294 oobeObserver->OnChange();
295 oobeObserver->SetUpdateFunc(updateFunc);
296 OOBEManager::GetInstance().Initialize();
297 OOBEManager::GetInstance().StartListen();
298 return true;
299 }
300
OOBEDatashareUtilsFuzzTest(FuzzedDataProvider * fdp)301 bool OOBEDatashareUtilsFuzzTest(FuzzedDataProvider* fdp)
302 {
303 std::string key = fdp->ConsumeRandomLengthString();
304 std::string value = fdp->ConsumeRandomLengthString();
305 if (!DoInit()) {
306 return false;
307 }
308
309 DataShareUtils::GetInstance().GetValue(key, value);
310 DataShareUtils::GetInstance().GetStringValue(key, value);
311 std::shared_ptr<DataShare::DataShareHelper> helper = DataShareUtils::GetInstance().CreateDataShareHelper();
312 DataShareUtils::GetInstance().ReleaseDataShareHelper(helper);
313 DataShareUtils::GetInstance().InitSystemAbilityManager();
314 DataShareUtils::GetInstance().AssembleUri(key);
315 DataShareUtils::GetInstance().GetDataShareReadyFlag();
316 DataShareUtils::GetInstance().SetDataShareReadyFlag(true);
317 return true;
318 }
319
SetHapToken()320 void SetHapToken()
321 {
322 Security::AccessToken::AccessTokenIDEx tokenIdEx = {0};
323 tokenIdEx = Security::AccessToken::AccessTokenKit::AllocHapToken(info, HapPolicyParams);
324 SetSelfTokenID(tokenIdEx.tokenIDEx);
325 }
326
DeleteHapToken()327 void DeleteHapToken()
328 {
329 Security::AccessToken::AccessTokenID tokenId =
330 Security::AccessToken::AccessTokenKit::GetHapTokenID(info.userID, info.bundleName, info.instIndex);
331 Security::AccessToken::AccessTokenKit::DeleteToken(tokenId);
332 }
333
GetPayload(FuzzedDataProvider * fdp,uint32_t resType)334 std::unordered_map<std::string, std::string> GetPayload(FuzzedDataProvider* fdp, uint32_t resType)
335 {
336 std::unordered_map<std::string, std::string> payload;
337 const auto ¶ms = RESTYPE_TO_PARAMS.at(resType);
338 size_t paramSize = params.size();
339 if (paramSize == 0) {
340 return payload;
341 }
342 size_t maxLen = PAYLOAD_MAX_SIZE / paramSize;
343 size_t minLen = sizeof(int32_t);
344 if (minLen > maxLen) {
345 minLen = maxLen;
346 }
347 std::mt19937_64 gen(std::random_device{}());
348 std::uniform_int_distribution<size_t> dis(minLen, maxLen);
349 for (const auto ¶m : params) {
350 payload[param] = fdp->ConsumeRandomLengthString();
351 }
352 return payload;
353 }
354
ResSchedThirdPartyFuzzTest(FuzzedDataProvider * fdp)355 bool ResSchedThirdPartyFuzzTest(FuzzedDataProvider* fdp)
356 {
357 uint32_t selfToken = GetSelfTokenID();
358 SetHapToken();
359
360 uint32_t resType = fdp->ConsumeIntegral<uint32_t>() % ResType::RES_TYPE_LAST;
361 if (THIRDPARTY_RES.find(resType) == THIRDPARTY_RES.end()) {
362 return false;
363 }
364
365 int64_t value = fdp->ConsumeIntegral<int64_t>();
366 auto mapPayload = GetPayload(fdp, resType);
367 ResSchedClient::GetInstance().ReportData(resType, value, mapPayload);
368
369 DeleteHapToken();
370 SetSelfTokenID(selfToken);
371 return true;
372 }
373 } // namespace ResourceSchedule
374 } // namespace OHOS
375
376 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)377 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
378 {
379 /* Run your code on data */
380 FuzzedDataProvider fdp(data, size);
381 OHOS::ResourceSchedule::DoSomethingInterestingWithMyAPI(&fdp);
382 OHOS::ResourceSchedule::OnRemoteRequest(&fdp);
383 OHOS::ResourceSchedule::ResSchedClientFuzzTest(&fdp);
384 OHOS::ResourceSchedule::ResSchedThirdPartyFuzzTest(&fdp);
385 OHOS::ResourceSchedule::OnSystemloadLevelFuzzTest(&fdp);
386 OHOS::ResourceSchedule::NotifierMgrFuzzTest(&fdp);
387 OHOS::ResourceSchedule::OOBEManagerFuzzTest(&fdp);
388 OHOS::ResourceSchedule::OOBEDatashareUtilsFuzzTest(&fdp);
389 OHOS::ResourceSchedule::SlideRecognizerFuzzTest(&fdp);
390 return 0;
391 }
392