• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &params = 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 &param : 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