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
24 #include "iremote_stub.h"
25 #include "ires_sched_service.h"
26 #include "iservice_registry.h"
27 #include "oobe_datashare_utils.h"
28 #include "oobe_manager.h"
29 #include "ioobe_task.h"
30 #include "plugin_mgr.h"
31 #include "res_sched_service.h"
32 #include "singleton.h"
33 #include "system_ability_definition.h"
34 #include "res_sched_client.h"
35 #include "res_sched_service_stub.h"
36 #include "res_sched_systemload_notifier_client.h"
37 #include "res_sched_systemload_notifier_proxy.h"
38 #include "notifier_mgr.h"
39
40 #define private public
41 #define protected public
42
43 #ifndef errno_t
44 typedef int errno_t;
45 #endif
46
47 #ifndef EOK
48 #define EOK 0
49 #endif
50
51 namespace OHOS {
52 namespace ResourceSchedule {
53 namespace {
54 static const int32_t TWO_PARAMETERS = 2;
55 }
56
57 constexpr int32_t MAX_CODE = 5;
58 constexpr int32_t MIN_LEN = 4;
59 std::mutex mutexLock;
60 sptr<IRemoteObject> remoteObj;
61 const uint8_t* DATA = nullptr;
62 size_t g_size = 0;
63 size_t g_pos;
64
65 /**
66 * describe: get data from outside untrusted data(DATA) which size is according to sizeof(T)
67 * tips: only support basic type
68 */
69 template<class T>
GetData()70 T GetData()
71 {
72 T object {};
73 size_t objectSize = sizeof(object);
74 if (DATA == nullptr || objectSize > g_size - g_pos) {
75 return object;
76 }
77 errno_t ret = memcpy_s(&object, objectSize, DATA + g_pos, objectSize);
78 if (ret != EOK) {
79 return {};
80 }
81 g_pos += objectSize;
82 return object;
83 }
84
GetStringFromData(int strlen)85 std::string GetStringFromData(int strlen)
86 {
87 if (strlen <= 0) {
88 return "";
89 }
90 char cstr[strlen];
91 cstr[strlen - 1] = '\0';
92 for (int i = 0; i < strlen - 1; i++) {
93 char tmp = GetData<char>();
94 if (tmp == '\0') {
95 tmp = '1';
96 }
97 cstr[i] = tmp;
98 }
99 std::string str(cstr);
100 return str;
101 }
102
DoInit()103 bool DoInit()
104 {
105 std::lock_guard<std::mutex> lock(mutexLock);
106 if (remoteObj) {
107 return true;
108 }
109 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
110 if (!samgr) {
111 return false;
112 }
113 remoteObj = samgr->GetSystemAbility(RES_SCHED_SYS_ABILITY_ID);
114 if (!remoteObj) {
115 return false;
116 }
117 return true;
118 }
119
onRemoteRequest(uint32_t code,MessageParcel & data)120 int32_t onRemoteRequest(uint32_t code, MessageParcel& data)
121 {
122 if (!DoInit()) {
123 return -1;
124 }
125 MessageParcel reply;
126 MessageOption option;
127 return remoteObj->SendRequest(code, data, reply, option);
128 }
129
DoSomethingInterestingWithMyAPI(const uint8_t * data,size_t size)130 bool DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size)
131 {
132 if (size <= MIN_LEN) {
133 return false;
134 }
135
136 MessageParcel dataMessageParcel;
137 if (!dataMessageParcel.WriteInterfaceToken(IRemoteStub<IResSchedService>::GetDescriptor())) {
138 return false;
139 }
140
141 uint32_t code = *(reinterpret_cast<const uint32_t*>(data));
142 size -= sizeof(uint32_t);
143
144 dataMessageParcel.WriteBuffer(data + sizeof(uint32_t), size);
145 dataMessageParcel.RewindRead(0);
146
147 onRemoteRequest(code, dataMessageParcel);
148 return true;
149 }
150
OnRemoteRequest(const uint8_t * data,size_t size)151 bool OnRemoteRequest(const uint8_t* data, size_t size)
152 {
153 if (data == nullptr) {
154 return false;
155 }
156
157 if (size <= MIN_LEN) {
158 return false;
159 }
160
161 // initialize
162 DATA = data;
163 g_size = size;
164 g_pos = 0;
165
166 // getdata
167 uint32_t fuzzCode = GetData<uint32_t>();
168 MessageParcel fuzzData;
169 fuzzData.WriteInterfaceToken(ResSchedServiceStub::GetDescriptor());
170 fuzzData.WriteBuffer(DATA + g_pos, g_size - g_pos);
171 fuzzData.RewindRead(0);
172 MessageParcel fuzzReply;
173 MessageOption fuzzOption;
174 DelayedSingleton<ResSchedService>::GetInstance()->OnRemoteRequest(fuzzCode % MAX_CODE,
175 fuzzData, fuzzReply, fuzzOption);
176 return true;
177 }
178
SyncEventFuzzTest(const uint8_t * data,size_t size)179 bool SyncEventFuzzTest(const uint8_t* data, size_t size)
180 {
181 if (data == nullptr) {
182 return false;
183 }
184
185 if (size <= MIN_LEN) {
186 return false;
187 }
188
189 // initialize
190 DATA = data;
191 g_size = size;
192 g_pos = 0;
193
194 // getdata
195 MessageParcel fuzzData;
196 fuzzData.WriteInterfaceToken(ResSchedServiceStub::GetDescriptor());
197 fuzzData.WriteBuffer(DATA + g_pos, g_size - g_pos);
198 fuzzData.RewindRead(0);
199 MessageParcel fuzzReply;
200 DelayedSingleton<ResSchedService>::GetInstance()->ReportSyncEventInner(fuzzData, fuzzReply);
201 return true;
202 }
203
ResSchedClientFuzzTest(const uint8_t * data,size_t size)204 bool ResSchedClientFuzzTest(const uint8_t* data, size_t size)
205 {
206 if (data == nullptr) {
207 return false;
208 }
209
210 if (size <= sizeof(uint32_t) + sizeof(int64_t) + TWO_PARAMETERS * sizeof(std::string)) {
211 return false;
212 }
213
214 // initialize
215 DATA = data;
216 g_size = size;
217 g_pos = 0;
218
219 uint32_t resType = GetData<uint32_t>();
220 int64_t value = GetData<int64_t>();
221 std::unordered_map<std::string, std::string> mapPayload;
222 mapPayload["pid"] = GetStringFromData(int(size) - sizeof(uint32_t) - sizeof(int64_t));
223 mapPayload["processName"] = GetStringFromData(int(size) - sizeof(std::string) -
224 sizeof(uint32_t) - sizeof(int64_t));
225
226 ResSchedClient::GetInstance().ReportData(resType, value, mapPayload);
227 ResSchedClient::GetInstance().KillProcess(mapPayload);
228 ResSchedClient::GetInstance().StopRemoteObject();
229
230 sptr<ResSchedSystemloadNotifierClient> callbackObj;
231 ResSchedClient::GetInstance().RegisterSystemloadNotifier(callbackObj);
232 ResSchedClient::GetInstance().UnRegisterSystemloadNotifier(callbackObj);
233 ResSchedClient::GetInstance().GetSystemloadLevel();
234 return true;
235 }
236
OnSystemloadLevelFuzzTest(const uint8_t * data,size_t size)237 bool OnSystemloadLevelFuzzTest(const uint8_t* data, size_t size)
238 {
239 if (data == nullptr) {
240 return false;
241 }
242
243 // initialize
244 DATA = data;
245 g_size = size;
246 g_pos = 0;
247
248 int32_t level = GetData<int32_t>();
249 if (!DoInit()) {
250 return false;
251 }
252 auto resSchedSystemloadNotifierProxy = std::make_unique<ResSchedSystemloadNotifierProxy>(remoteObj);
253 resSchedSystemloadNotifierProxy->OnSystemloadLevel(level);
254 return true;
255 }
256
NotifierMgrFuzzTest(const uint8_t * data,size_t size)257 bool NotifierMgrFuzzTest(const uint8_t* data, size_t size)
258 {
259 if (data == nullptr) {
260 return false;
261 }
262
263 // initialize
264 DATA = data;
265 g_size = size;
266 g_pos = 0;
267
268 int32_t pid = GetData<int32_t>();
269 int32_t type = GetData<int32_t>();
270 int32_t level = GetData<int32_t>();
271 int32_t state = GetData<int32_t>();
272 if (!DoInit()) {
273 return false;
274 }
275
276 NotifierMgr::GetInstance().Init();
277 NotifierMgr::GetInstance().RegisterNotifier(pid, remoteObj);
278 NotifierMgr::GetInstance().UnRegisterNotifier(pid);
279 NotifierMgr::GetInstance().OnRemoteNotifierDied(remoteObj);
280 NotifierMgr::GetInstance().OnDeviceLevelChanged(type, level);
281 NotifierMgr::GetInstance().OnApplicationStateChange(state, level);
282 NotifierMgr::GetInstance().GetSystemloadLevel();
283 NotifierMgr::GetInstance().DumpRegisterInfo();
284 NotifierMgr::GetInstance().Deinit();
285 return true;
286 }
287
OOBEManagerFuzzTest(const uint8_t * data,size_t size)288 bool OOBEManagerFuzzTest(const uint8_t* data, size_t size)
289 {
290 if (data == nullptr) {
291 return false;
292 }
293
294 if (size <= sizeof(std::string)) {
295 return false;
296 }
297
298 std::string key = GetStringFromData(int(size));
299 OOBEManager::ResDataAbilityObserver::UpdateFunc updateFunc = [&]() {};
300 if (!DoInit()) {
301 return false;
302 }
303
304 OOBEManager::GetInstance().GetOOBValue();
305 OOBEManager::GetInstance().RegisterObserver(key, updateFunc);
306 OOBEManager::GetInstance().UnregisterObserver();
307 sptr<OOBEManager::ResDataAbilityObserver> oobeObserver = new OOBEManager::ResDataAbilityObserver();
308 oobeObserver->OnChange();
309 oobeObserver->SetUpdateFunc(updateFunc);
310 OOBEManager::GetInstance().Initialize();
311 OOBEManager::GetInstance().StartListen();
312 return true;
313 }
314
OOBEDatashareUtilsFuzzTest(const uint8_t * data,size_t size)315 bool OOBEDatashareUtilsFuzzTest(const uint8_t* data, size_t size)
316 {
317 if (data == nullptr) {
318 return false;
319 }
320
321 if (size <= TWO_PARAMETERS * sizeof(std::string)) {
322 return false;
323 }
324
325 std::string key = GetStringFromData(int(size));
326 std::string value = GetStringFromData(int(size));
327 if (!DoInit()) {
328 return false;
329 }
330
331 DataShareUtils::GetInstance().GetValue(key, value);
332 DataShareUtils::GetInstance().GetStringValue(key, value);
333 std::shared_ptr<DataShare::DataShareHelper> helper = DataShareUtils::GetInstance().CreateDataShareHelper();
334 DataShareUtils::GetInstance().ReleaseDataShareHelper(helper);
335 DataShareUtils::GetInstance().InitSystemAbilityManager();
336 DataShareUtils::GetInstance().AssembleUri(key);
337 DataShareUtils::GetInstance().GetDataShareReadyFlag();
338 DataShareUtils::GetInstance().SetDataShareReadyFlag(true);
339 return true;
340 }
341 } // namespace ResourceSchedule
342 } // namespace OHOS
343
344 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)345 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
346 {
347 /* Run your code on data */
348 OHOS::ResourceSchedule::DoSomethingInterestingWithMyAPI(data, size);
349 OHOS::ResourceSchedule::OnRemoteRequest(data, size);
350 OHOS::ResourceSchedule::SyncEventFuzzTest(data, size);
351 OHOS::ResourceSchedule::ResSchedClientFuzzTest(data, size);
352 OHOS::ResourceSchedule::OnSystemloadLevelFuzzTest(data, size);
353 OHOS::ResourceSchedule::NotifierMgrFuzzTest(data, size);
354 OHOS::ResourceSchedule::OOBEManagerFuzzTest(data, size);
355 OHOS::ResourceSchedule::OOBEDatashareUtilsFuzzTest(data, size);
356 return 0;
357 }
358