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" 22namespace OHOS { 23namespace Msdp { 24namespace DeviceStatus { 25namespace { 26struct DeviceStatusEpollEvent { 27 int32_t fd { -1 }; 28 EpollEventType eventType { EPOLL_EVENT_BEGIN }; 29}; 30 31const uint8_t *g_baseFuzzData = nullptr; 32size_t g_baseFuzzSize = 0; 33size_t g_baseFuzzPos = 0; 34constexpr size_t STR_LEN = 255; 35ContextService *g_instance = nullptr; 36constexpr int32_t DEFAULT_WAIT_TIME_MS { 1000 }; 37constexpr int32_t WAIT_FOR_ONCE { 1 }; 38constexpr int32_t MAX_N_RETRIES { 100 }; 39} // namespace 40 41ContextService::ContextService() 42{ 43 ddm_ = std::make_unique<DDMAdapter>(); 44 45 OnStart(); 46} 47 48ContextService::~ContextService() 49{ 50 OnStop(); 51} 52 53IDelegateTasks& ContextService::GetDelegateTasks() 54{ 55 return delegateTasks_; 56} 57 58IDeviceManager& ContextService::GetDeviceManager() 59{ 60 return devMgr_; 61} 62 63ITimerManager& ContextService::GetTimerManager() 64{ 65 return timerMgr_; 66} 67 68IDragManager& ContextService::GetDragManager() 69{ 70 return dragMgr_; 71} 72 73ContextService* 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 84ISocketSessionManager& ContextService::GetSocketSessionManager() 85{ 86 return socketSessionMgr_; 87} 88 89IDDMAdapter& ContextService::GetDDM() 90{ 91 return *ddm_; 92} 93 94IPluginManager& ContextService::GetPluginManager() 95{ 96 return *pluginMgr_; 97} 98 99IInputAdapter& ContextService::GetInput() 100{ 101 return *input_; 102} 103 104IDSoftbusAdapter& ContextService::GetDSoftbus() 105{ 106 return *dsoftbusAda_; 107} 108 109bool 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 131INIT_FAIL: 132 EpollClose(); 133 return false; 134} 135int32_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 146int32_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 162int32_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 177int32_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 188int32_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 221int32_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 240void 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 251int32_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 269int32_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 278void 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 293void 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 303int32_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 329void ContextService::DisableDevMgr() 330{ 331 DelEpoll(EPOLL_EVENT_DEVICE_MGR, devMgr_.GetFd()); 332 devMgr_.Disable(); 333} 334 335void 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 351void 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 378void 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 407void 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 423template <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 438void SetGlobalFuzzData(const uint8_t *data, size_t size) 439{ 440 g_baseFuzzData = data; 441 g_baseFuzzSize = size; 442 g_baseFuzzPos = 0; 443} 444 445std::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 460bool 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 490extern "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