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