1 /*
2 * Copyright (c) 2024 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 "devicemanager_fuzzer.h"
17
18 #include "devicestatus_define.h"
19
20 #undef LOG_TAG
21 #define LOG_TAG "DeviceManagerFuzzTest"
22 namespace OHOS {
23 namespace Msdp {
24 namespace DeviceStatus {
25 namespace {
26 struct DeviceStatusEpollEvent {
27 int32_t fd { -1 };
28 EpollEventType eventType { EPOLL_EVENT_BEGIN };
29 };
30
31 const uint8_t *g_baseFuzzData = nullptr;
32 size_t g_baseFuzzSize = 0;
33 size_t g_baseFuzzPos = 0;
34 constexpr size_t STR_LEN = 255;
35 ContextService *g_instance = nullptr;
36 constexpr int32_t DEFAULT_WAIT_TIME_MS { 1000 };
37 constexpr int32_t WAIT_FOR_ONCE { 1 };
38 constexpr int32_t MAX_N_RETRIES { 100 };
39 } // namespace
40
ContextService()41 ContextService::ContextService()
42 {
43 OnStart();
44 }
45
~ContextService()46 ContextService::~ContextService()
47 {
48 OnStop();
49 }
50
GetDelegateTasks()51 IDelegateTasks& ContextService::GetDelegateTasks()
52 {
53 return delegateTasks_;
54 }
55
GetDeviceManager()56 IDeviceManager& ContextService::GetDeviceManager()
57 {
58 return devMgr_;
59 }
60
GetTimerManager()61 ITimerManager& ContextService::GetTimerManager()
62 {
63 return timerMgr_;
64 }
65
GetDragManager()66 IDragManager& ContextService::GetDragManager()
67 {
68 return dragMgr_;
69 }
70
GetInstance()71 ContextService* ContextService::GetInstance()
72 {
73 static std::once_flag flag;
74 std::call_once(flag, [&]() {
75 ContextService *cooContext = new (std::nothrow) ContextService();
76 CHKPL(cooContext);
77 g_instance = cooContext;
78 });
79 return g_instance;
80 }
81
GetSocketSessionManager()82 ISocketSessionManager& ContextService::GetSocketSessionManager()
83 {
84 return socketSessionMgr_;
85 }
86
GetPluginManager()87 IPluginManager& ContextService::GetPluginManager()
88 {
89 return *pluginMgr_;
90 }
91
GetInput()92 IInputAdapter& ContextService::GetInput()
93 {
94 return *input_;
95 }
96
GetDSoftbus()97 IDSoftbusAdapter& ContextService::GetDSoftbus()
98 {
99 return *dsoftbusAda_;
100 }
101
Init()102 bool ContextService::Init()
103 {
104 CALL_DEBUG_ENTER;
105 if (EpollCreate() != RET_OK) {
106 FI_HILOGE("Create epoll failed");
107 return false;
108 }
109 if (InitDelegateTasks() != RET_OK) {
110 FI_HILOGE("Delegate tasks init failed");
111 goto INIT_FAIL;
112 }
113 if (InitTimerMgr() != RET_OK) {
114 FI_HILOGE("TimerMgr init failed");
115 goto INIT_FAIL;
116 }
117 if (InitDevMgr() != RET_OK) {
118 FI_HILOGE("DevMgr init failed");
119 goto INIT_FAIL;
120 }
121
122 return true;
123
124 INIT_FAIL:
125 EpollClose();
126 return false;
127 }
InitDevMgr()128 int32_t ContextService::InitDevMgr()
129 {
130 CALL_DEBUG_ENTER;
131 int32_t ret = devMgr_.Init(this);
132 if (ret != RET_OK) {
133 FI_HILOGE("DevMgr init failed");
134 return ret;
135 }
136 return ret;
137 }
138
InitTimerMgr()139 int32_t ContextService::InitTimerMgr()
140 {
141 CALL_DEBUG_ENTER;
142 int32_t ret = timerMgr_.Init(this);
143 if (ret != RET_OK) {
144 FI_HILOGE("TimerMgr init failed");
145 return ret;
146 }
147
148 ret = AddEpoll(EPOLL_EVENT_TIMER, timerMgr_.GetTimerFd());
149 if (ret != RET_OK) {
150 FI_HILOGE("AddEpoll for timer failed");
151 }
152 return ret;
153 }
154
InitDelegateTasks()155 int32_t ContextService::InitDelegateTasks()
156 {
157 CALL_DEBUG_ENTER;
158 if (!delegateTasks_.Init()) {
159 FI_HILOGE("The delegate task init failed");
160 return RET_ERR;
161 }
162 int32_t ret = AddEpoll(EPOLL_EVENT_ETASK, delegateTasks_.GetReadFd());
163 if (ret != RET_OK) {
164 FI_HILOGE("AddEpoll error ret:%{public}d", ret);
165 }
166 FI_HILOGI("AddEpoll, epollfd:%{public}d, fd:%{public}d", epollFd_, delegateTasks_.GetReadFd());
167 return ret;
168 }
169
EpollCreate()170 int32_t ContextService::EpollCreate()
171 {
172 CALL_DEBUG_ENTER;
173 epollFd_ = ::epoll_create1(EPOLL_CLOEXEC);
174 if (epollFd_ < 0) {
175 FI_HILOGE("epoll_create1 failed:%{public}s", ::strerror(errno));
176 return RET_ERR;
177 }
178 return RET_OK;
179 }
180
AddEpoll(EpollEventType type,int32_t fd)181 int32_t ContextService::AddEpoll(EpollEventType type, int32_t fd)
182 {
183 CALL_DEBUG_ENTER;
184 if (!(type >= EPOLL_EVENT_BEGIN && type < EPOLL_EVENT_END)) {
185 FI_HILOGE("Invalid type:%{public}d", type);
186 return RET_ERR;
187 }
188 if (fd < 0) {
189 FI_HILOGE("Invalid fd:%{public}d", fd);
190 return RET_ERR;
191 }
192 auto eventData = static_cast<DeviceStatusEpollEvent*>(malloc(sizeof(DeviceStatusEpollEvent)));
193 if (!eventData) {
194 FI_HILOGE("Malloc failed");
195 return RET_ERR;
196 }
197 eventData->fd = fd;
198 eventData->eventType = type;
199 FI_HILOGD("EventData:[fd:%{public}d, type:%{public}d]", eventData->fd, eventData->eventType);
200
201 struct epoll_event ev {};
202 ev.events = EPOLLIN;
203 ev.data.ptr = eventData;
204 if (EpollCtl(fd, EPOLL_CTL_ADD, ev) != RET_OK) {
205 free(eventData);
206 eventData = nullptr;
207 ev.data.ptr = nullptr;
208 FI_HILOGE("EpollCtl failed");
209 return RET_ERR;
210 }
211 return RET_OK;
212 }
213
DelEpoll(EpollEventType type,int32_t fd)214 int32_t ContextService::DelEpoll(EpollEventType type, int32_t fd)
215 {
216 CALL_DEBUG_ENTER;
217 if (!(type >= EPOLL_EVENT_BEGIN && type < EPOLL_EVENT_END)) {
218 FI_HILOGE("Invalid type:%{public}d", type);
219 return RET_ERR;
220 }
221 if (fd < 0) {
222 FI_HILOGE("Invalid fd:%{public}d", fd);
223 return RET_ERR;
224 }
225 struct epoll_event ev {};
226 if (EpollCtl(fd, EPOLL_CTL_DEL, ev) != RET_OK) {
227 FI_HILOGE("DelEpoll failed");
228 return RET_ERR;
229 }
230 return RET_OK;
231 }
232
EpollClose()233 void ContextService::EpollClose()
234 {
235 CALL_DEBUG_ENTER;
236 if (epollFd_ >= 0) {
237 if (close(epollFd_) < 0) {
238 FI_HILOGE("Close epoll fd failed, error:%{public}s, epollFd_:%{public}d", strerror(errno), epollFd_);
239 }
240 epollFd_ = -1;
241 }
242 }
243
EpollCtl(int32_t fd,int32_t op,struct epoll_event & event)244 int32_t ContextService::EpollCtl(int32_t fd, int32_t op, struct epoll_event &event)
245 {
246 CALL_DEBUG_ENTER;
247 if (fd < 0) {
248 FI_HILOGE("Invalid fd:%{public}d", fd);
249 return RET_ERR;
250 }
251 if (epollFd_ < 0) {
252 FI_HILOGE("Invalid epollFd:%{public}d", epollFd_);
253 return RET_ERR;
254 }
255 if (::epoll_ctl(epollFd_, op, fd, &event) != 0) {
256 FI_HILOGE("epoll_ctl(%{public}d,%{public}d,%{public}d) failed:%{public}s", epollFd_, op, fd, ::strerror(errno));
257 return RET_ERR;
258 }
259 return RET_OK;
260 }
261
EpollWait(int32_t maxevents,int32_t timeout,struct epoll_event & events)262 int32_t ContextService::EpollWait(int32_t maxevents, int32_t timeout, struct epoll_event &events)
263 {
264 if (epollFd_ < 0) {
265 FI_HILOGE("Invalid epollFd:%{public}d", epollFd_);
266 return RET_ERR;
267 }
268 return epoll_wait(epollFd_, &events, maxevents, timeout);
269 }
270
OnTimeout(const struct epoll_event & ev)271 void ContextService::OnTimeout(const struct epoll_event &ev)
272 {
273 CALL_DEBUG_ENTER;
274 if ((ev.events & EPOLLIN) == EPOLLIN) {
275 uint64_t expiration {};
276 ssize_t ret = read(timerMgr_.GetTimerFd(), &expiration, sizeof(expiration));
277 if (ret < 0) {
278 FI_HILOGE("Read expiration failed:%{public}s", strerror(errno));
279 }
280 timerMgr_.ProcessTimers();
281 } else if ((ev.events & (EPOLLHUP | EPOLLERR)) != 0) {
282 FI_HILOGE("Epoll hangup:%{public}s", strerror(errno));
283 }
284 }
285
OnDeviceMgr(const struct epoll_event & ev)286 void ContextService::OnDeviceMgr(const struct epoll_event &ev)
287 {
288 CALL_DEBUG_ENTER;
289 if ((ev.events & EPOLLIN) == EPOLLIN) {
290 devMgr_.Dispatch(ev);
291 } else if ((ev.events & (EPOLLHUP | EPOLLERR)) != 0) {
292 FI_HILOGE("Epoll hangup:%{public}s", strerror(errno));
293 }
294 }
295
EnableDevMgr(int32_t nRetries)296 int32_t ContextService::EnableDevMgr(int32_t nRetries)
297 {
298 CALL_INFO_TRACE;
299 static int32_t timerId { -1 };
300 int32_t ret = devMgr_.Enable();
301 if (ret != RET_OK) {
302 FI_HILOGE("Failed to enable device manager");
303 if (nRetries > 0) {
304 timerId = timerMgr_.AddTimer(DEFAULT_WAIT_TIME_MS, WAIT_FOR_ONCE,
305 [this, nRetries] { return this->EnableDevMgr(nRetries - 1); });
306 if (timerId < 0) {
307 FI_HILOGE("AddTimer failed, Failed to enable device manager");
308 }
309 } else {
310 FI_HILOGE("Maximum number of retries exceeded, Failed to enable device manager");
311 }
312 return ret;
313 }
314 AddEpoll(EPOLL_EVENT_DEVICE_MGR, devMgr_.GetFd());
315 if (timerId >= 0) {
316 timerMgr_.RemoveTimer(timerId);
317 timerId = -1;
318 }
319 return RET_OK;
320 }
321
DisableDevMgr()322 void ContextService::DisableDevMgr()
323 {
324 DelEpoll(EPOLL_EVENT_DEVICE_MGR, devMgr_.GetFd());
325 devMgr_.Disable();
326 }
327
OnStart()328 void ContextService::OnStart()
329 {
330 CALL_DEBUG_ENTER;
331 uint64_t tid = GetThisThreadId();
332 delegateTasks_.SetWorkerThreadId(tid);
333
334 if (!Init()) {
335 FI_HILOGE("On start call init failed");
336 return;
337 }
338 state_ = ServiceRunningState::STATE_RUNNING;
339 ready_ = true;
340
341 worker_ = std::thread(std::bind(&ContextService::OnThread, this));
342 }
343
OnStop()344 void ContextService::OnStop()
345 {
346 CALL_DEBUG_ENTER;
347 if (timerMgr_.GetTimerFd() >= 0) {
348 if (close(timerMgr_.GetTimerFd()) < 0) {
349 FI_HILOGE("Close timer fd failed, error:%{public}s", strerror(errno));
350 }
351 }
352 if (!ready_) {
353 FI_HILOGI("ready state is false");
354 return;
355 }
356 ready_ = false;
357 state_ = ServiceRunningState::STATE_EXIT;
358
359 delegateTasks_.PostAsyncTask([]() -> int32_t {
360 FI_HILOGD("No asynchronous operations");
361 return RET_OK;
362 });
363 if (worker_.joinable()) {
364 worker_.join();
365 }
366 DisableDevMgr();
367 EpollClose();
368 FI_HILOGI("OnStop leave");
369 }
370
OnThread()371 void ContextService::OnThread()
372 {
373 CALL_DEBUG_ENTER;
374 SetThreadName(std::string("os_ds_service"));
375 uint64_t tid = GetThisThreadId();
376 delegateTasks_.SetWorkerThreadId(tid);
377 EnableDevMgr(MAX_N_RETRIES);
378 FI_HILOGD("Main worker thread start, tid:%{public}" PRId64 "", tid);
379
380 while (state_ == ServiceRunningState::STATE_RUNNING) {
381 struct epoll_event ev[MAX_EVENT_SIZE] {};
382 int32_t count = EpollWait(MAX_EVENT_SIZE, -1, ev[0]);
383 for (int32_t i = 0; i < count && state_ == ServiceRunningState::STATE_RUNNING; i++) {
384 auto epollEvent = reinterpret_cast<DeviceStatusEpollEvent*>(ev[i].data.ptr);
385 CHKPC(epollEvent);
386 if (epollEvent->eventType == EPOLL_EVENT_TIMER) {
387 OnTimeout(ev[i]);
388 } else if (epollEvent->eventType == EPOLL_EVENT_ETASK) {
389 OnDelegateTask(ev[i]);
390 } else if (epollEvent->eventType == EPOLL_EVENT_DEVICE_MGR) {
391 OnDeviceMgr(ev[i]);
392 } else {
393 FI_HILOGW("Unknown epoll event type:%{public}d", epollEvent->eventType);
394 }
395 }
396 }
397 FI_HILOGD("Main worker thread stop, tid:%{public}" PRId64 "", tid);
398 }
399
OnDelegateTask(const struct epoll_event & ev)400 void ContextService::OnDelegateTask(const struct epoll_event &ev)
401 {
402 if ((ev.events & EPOLLIN) == 0) {
403 FI_HILOGW("Not epollin");
404 return;
405 }
406 DelegateTasks::TaskData data {};
407 ssize_t res = read(delegateTasks_.GetReadFd(), &data, sizeof(data));
408 if (res == -1) {
409 FI_HILOGW("Read failed erron:%{public}d", errno);
410 }
411 FI_HILOGD("RemoteRequest notify td:%{public}" PRId64 ", std:%{public}" PRId64 ""
412 ", taskId:%{public}d", GetThisThreadId(), data.tid, data.taskId);
413 delegateTasks_.ProcessTasks();
414 }
415
GetData()416 template <class T> T GetData()
417 {
418 T objetct{};
419 size_t objetctSize = sizeof(objetct);
420 if (g_baseFuzzData == nullptr || objetctSize > g_baseFuzzSize - g_baseFuzzPos) {
421 return objetct;
422 }
423 errno_t ret = memcpy_s(&objetct, objetctSize, g_baseFuzzData + g_baseFuzzPos, objetctSize);
424 if (ret != EOK) {
425 return {};
426 }
427 g_baseFuzzPos += objetctSize;
428 return objetct;
429 }
430
SetGlobalFuzzData(const uint8_t * data,size_t size)431 void SetGlobalFuzzData(const uint8_t *data, size_t size)
432 {
433 g_baseFuzzData = data;
434 g_baseFuzzSize = size;
435 g_baseFuzzPos = 0;
436 }
437
GetStringFromData(int strlen)438 std::string GetStringFromData(int strlen)
439 {
440 if (strlen < 1) {
441 return "";
442 }
443
444 char cstr[strlen];
445 cstr[strlen - 1] = '\0';
446 for (int i = 0; i < strlen - 1; i++) {
447 cstr[i] = GetData<char>();
448 }
449 std::string str(cstr);
450 return str;
451 }
452
DeviceManagerFuzzTest(const uint8_t * data,size_t size)453 bool DeviceManagerFuzzTest(const uint8_t* data, size_t size)
454 {
455 if ((data == nullptr) || (size < 1)) {
456 return false;
457 }
458 SetGlobalFuzzData(data, size);
459
460 std::string devStr = GetStringFromData(STR_LEN);
461 int32_t id = GetData<int32_t>();
462
463 struct epoll_event ev {};
464 std::weak_ptr<IDeviceObserver> weakObserver = std::weak_ptr<IDeviceObserver>();
465 auto env = ContextService::GetInstance();
466
467 env->devMgr_.AddDevice(devStr);
468 env->devMgr_.FindDevice(devStr);
469 env->devMgr_.Dispatch(ev);
470 env->GetDeviceManager().GetDevice(id);
471 env->GetDeviceManager().RetriggerHotplug(weakObserver);
472 env->GetDeviceManager().AddDeviceObserver(weakObserver);
473 env->GetDeviceManager().RemoveDeviceObserver(weakObserver);
474 env->devMgr_.HasLocalPointerDevice();
475 env->devMgr_.HasLocalKeyboardDevice();
476 env->devMgr_.HasKeyboard();
477 env->devMgr_.GetKeyboard();
478 env->devMgr_.RemoveDevice(devStr);
479 return true;
480 }
481
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)482 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
483 {
484 /* Run your code on data */
485 if (data == nullptr) {
486 return 0;
487 }
488
489 OHOS::Msdp::DeviceStatus::DeviceManagerFuzzTest(data, size);
490
491 return 0;
492 }
493 } // namespace DeviceStatus
494 } // namespace Msdp
495 } // namespace OHOS