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 "app_spawn_test_helper.h" 17 18#include <cstdint> 19#include <cstdio> 20#include <cstdlib> 21#include <fcntl.h> 22#include <pthread.h> 23#include <csignal> 24#include <string> 25#include <sys/eventfd.h> 26#include <sys/wait.h> 27#include <unistd.h> 28#include <inttypes.h> 29 30#include "appspawn.h" 31#include "appspawn_client.h" 32#include "appspawn_modulemgr.h" 33#include "appspawn_msg.h" 34#include "appspawn_server.h" 35#include "appspawn_service.h" 36#include "appspawn_manager.h" 37#include "appspawn_utils.h" 38#include "loop_event.h" 39#include "parameters.h" 40#include "securec.h" 41 42#include "app_spawn_stub.h" 43 44namespace OHOS { 45typedef struct { 46 int32_t bundleIndex; 47 char bundleName[APP_LEN_BUNDLE_NAME]; // process name 48} AppBundleInfo; 49 50typedef struct { 51 uint32_t hapFlags; 52 char apl[APP_APL_MAX_LEN]; 53} AppDomainInfo; 54 55const uint32_t AppSpawnTestServer::defaultProtectTime = 60000; // 60000 60s 56 57uint32_t AppSpawnTestServer::serverId = 0; 58static int TestChildLoopRun(AppSpawnContent *content, AppSpawnClient *client) 59{ 60 APPSPAWN_LOGV("ChildLoopRun ..."); 61 sleep(1); 62 return 0; 63} 64 65AppSpawnTestServer::~AppSpawnTestServer() 66{ 67 if (localServer_) { 68 delete localServer_; 69 localServer_ = nullptr; 70 } 71} 72 73void AppSpawnTestServer::CloseCheckHandler(void) 74{ 75 APPSPAWN_LOGV("CloseCheckHandler"); 76#ifdef USER_TIMER_TO_CHECK 77 if (timer_ != nullptr) { 78 LE_StopTimer(LE_GetDefaultLoop(), timer_); 79 timer_ = nullptr; 80 } 81#else 82 if (idle_) { 83 LE_DelIdle(idle_); 84 idle_ = nullptr; 85 } 86#endif 87} 88 89void AppSpawnTestServer::StartCheckHandler(void) 90{ 91#ifdef USER_TIMER_TO_CHECK 92 int ret = LE_CreateTimer(LE_GetDefaultLoop(), &timer_, ProcessIdle, this); 93 if (ret == 0) { 94 ret = LE_StartTimer(LE_GetDefaultLoop(), timer_, 100, 10000000); // 100 10000000 repeat 95 } 96#else 97 LE_AddIdle(LE_GetDefaultLoop(), &idle_, ProcessIdle, this, 10000000); // 10000000 repeat 98#endif 99} 100 101void AppSpawnTestServer::ServiceThread() 102{ 103 CmdArgs *args = nullptr; 104 pid_t pid = getpid(); 105 APPSPAWN_LOGV("AppSpawnTestServer::ServiceThread %{public}s", serviceCmd_.c_str()); 106 107 running_ = true; 108 // 测试server时,使用appspawn的server 109 if (testServer_) { 110 content_ = AppSpawnTestHelper::StartSpawnServer(serviceCmd_, args); 111 if (content_ == nullptr) { 112 return; 113 } 114 if (pid == getpid()) { // 主进程进行处理 115 APPSPAWN_LOGV("Service start timer %{public}s ", serviceCmd_.c_str()); 116 StartCheckHandler(); 117 AppSpawnMgr *content = reinterpret_cast<AppSpawnMgr *>(content_); 118 APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, return); 119 AppSpawnedProcess *info = GetSpawnedProcessByName(NWEBSPAWN_SERVER_NAME); 120 if (info != nullptr) { 121 APPSPAWN_LOGV("Save nwebspawn pid: %{public}d %{public}d", info->pid, serverId_); 122 appPid_.store(info->pid); 123 } 124 // register 125 RegChildLooper(&content->content, TestChildLoopRun); 126 } 127 content_->runAppSpawn(content_, args->argc, args->argv); 128 if (pid != getpid()) { // 子进程退出 129 exit(0); 130 } else { 131 content_ = nullptr; 132 } 133 } else { 134 StartCheckHandler(); 135 localServer_ = new LocalTestServer(); 136 localServer_->Run(APPSPAWN_SOCKET_NAME, recvMsgProcess_); 137 } 138 APPSPAWN_LOGV("AppSpawnTestServer::ServiceThread finish %{public}s ", serviceCmd_.c_str()); 139 if (args) { 140 free(args); 141 } 142 return; 143} 144 145void AppSpawnTestServer::Start(void) 146{ 147 Start(nullptr); 148} 149 150static void *ServiceHelperThread(void *arg) 151{ 152 AppSpawnTestServer *server = reinterpret_cast<AppSpawnTestServer *>(arg); 153 APPSPAWN_LOGV("AppSpawnTestServer::thread "); 154 server->ServiceThread(); 155 return nullptr; 156} 157 158void AppSpawnTestServer::Start(RecvMsgProcess process, uint32_t time) 159{ 160 APPSPAWN_LOGV("AppSpawnTestServer::Start serverId %{public}u", AppSpawnTestServer::serverId); 161 protectTime_ = time; 162 uint32_t retry = 0; 163 if (threadId_ != 0) { 164 return; 165 } 166 clock_gettime(CLOCK_MONOTONIC, &startTime_); 167 recvMsgProcess_ = process; 168 errno = 0; 169 int ret = 0; 170 do { 171 threadId_ = 0; 172 ret = pthread_create(&threadId_, nullptr, ServiceHelperThread, static_cast<void *>(this)); 173 if (ret == 0) { 174 break; 175 } 176 APPSPAWN_LOGE("AppSpawnTestServer::Start create thread fail %{public}d %{public}d", ret, errno); 177 usleep(20000); // 20000 20ms 178 retry++; 179 } while (ret == EAGAIN && retry < 10); // 10 max retry 180 181 // wait server thread run 182 retry = 0; 183 while (!running_ && (retry < 10)) { // 10 max retry 184 usleep(20000); // 20000 20ms 185 retry++; 186 } 187 APPSPAWN_LOGV("AppSpawnTestServer::Start retry %{public}u", retry); 188} 189 190void AppSpawnTestServer::Stop() 191{ 192 APPSPAWN_LOGV("AppSpawnTestServer::Stop serverId %{public}u", AppSpawnTestServer::serverId); 193 if (threadId_ != 0) { 194 stop_ = true; 195 pthread_join(threadId_, nullptr); 196 threadId_ = 0; 197 APPSPAWN_LOGV("Stop"); 198 } 199} 200 201void AppSpawnTestServer::KillNWebSpawnServer() 202{ 203 APPSPAWN_LOGV("Kill nwebspawn %{public}d", serverId_); 204 if (appPid_ > 0) { 205 kill(appPid_, SIGKILL); 206 } 207} 208 209void AppSpawnTestServer::StopSpawnService(void) 210{ 211 APPSPAWN_LOGV("StopSpawnService "); 212 if (serverStoped) { 213 CloseCheckHandler(); 214 } 215 serverStoped = true; 216 if (testServer_) { 217 struct signalfd_siginfo siginfo = {}; 218 siginfo.ssi_signo = SIGTERM; 219 siginfo.ssi_uid = 0; 220 ProcessSignal(&siginfo); 221 } else { 222 localServer_->Stop(); 223 } 224} 225 226#ifdef USER_TIMER_TO_CHECK 227void AppSpawnTestServer::ProcessIdle(const TimerHandle taskHandle, void *context) 228#else 229void AppSpawnTestServer::ProcessIdle(const IdleHandle taskHandle, void *context) 230#endif 231{ 232 APPSPAWN_LOGV("AppSpawnTestServer::ProcessIdle"); 233 AppSpawnTestServer *server = reinterpret_cast<AppSpawnTestServer *>(const_cast<void *>(context)); 234 if (server->stop_) { 235 server->StopSpawnService(); 236 return; 237 } 238 239 struct timespec end; 240 clock_gettime(CLOCK_MONOTONIC, &end); 241 uint64_t diff = DiffTime(&server->startTime_, &end); 242 if (diff >= (server->protectTime_ * 1000)) { // 1000 ms -> us 243 APPSPAWN_LOGV("AppSpawnTestServer:: timeout %{public}u %{public}" PRIu64 "", server->protectTime_, diff); 244 server->StopSpawnService(); 245 return; 246 } 247} 248 249static int HandleRecvMessage(const TaskHandle taskHandle, uint8_t * buffer, int bufferSize, int flags) 250{ 251 int socketFd = LE_GetSocketFd(taskHandle); 252 struct iovec iov = { 253 .iov_base = buffer, 254 .iov_len = bufferSize, 255 }; 256 char ctrlBuffer[CMSG_SPACE(APP_MAX_FD_COUNT * sizeof(int))]; 257 struct msghdr msg = { 258 .msg_iov = &iov, 259 .msg_iovlen = 1, 260 .msg_control = ctrlBuffer, 261 .msg_controllen = sizeof(ctrlBuffer), 262 }; 263 264 AppSpawnConnection *connection = (AppSpawnConnection *) LE_GetUserData(taskHandle); 265 errno = 0; 266 int recvLen = recvmsg(socketFd, &msg, flags); 267 APPSPAWN_CHECK_ONLY_LOG(errno == 0, "recvmsg with errno %d", errno); 268 struct cmsghdr *cmsg = nullptr; 269 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != nullptr; cmsg = CMSG_NXTHDR(&msg, cmsg)) { 270 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) { 271 int fdCount = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int); 272 int* fd = reinterpret_cast<int*>(CMSG_DATA(cmsg)); 273 APPSPAWN_CHECK(fdCount <= APP_MAX_FD_COUNT, 274 return -1, "failed to recv fd %d %d", connection->receiverCtx.fdCount, fdCount); 275 APPSPAWN_CHECK(memcpy_s(connection->receiverCtx.fds, fdCount * sizeof(int), fd, 276 fdCount * sizeof(int)) == 0, return -1, "memcpy_s fd failed"); 277 connection->receiverCtx.fdCount = fdCount; 278 } 279 } 280 281 return recvLen; 282} 283 284int LocalTestServer::OnConnection(const LoopHandle loopHandle, const TaskHandle server) 285{ 286 static uint32_t connectionId = 0; 287 TaskHandle stream; 288 LE_StreamInfo info = {}; 289 info.baseInfo.flags = TASK_STREAM | TASK_PIPE | TASK_CONNECT; 290 info.baseInfo.close = OnClose; 291 info.baseInfo.userDataSize = sizeof(TestConnection); 292 info.disConnectComplete = nullptr; 293 info.sendMessageComplete = SendMessageComplete; 294 info.recvMessage = OnReceiveRequest; 295 info.handleRecvMsg = HandleRecvMessage; 296 297 ServerInfo *serverInfo = (ServerInfo *)LE_GetUserData(server); 298 APPSPAWN_CHECK(serverInfo != nullptr, return -1, "Failed to alloc stream"); 299 300 LE_STATUS ret = LE_AcceptStreamClient(loopHandle, server, &stream, &info); 301 APPSPAWN_CHECK(ret == 0, return -1, "Failed to alloc stream"); 302 TestConnection *connection = (TestConnection *)LE_GetUserData(stream); 303 APPSPAWN_CHECK(connection != nullptr, return -1, "Failed to alloc stream"); 304 connection->connectionId = ++connectionId; 305 connection->stream = stream; 306 connection->msgRecvLen = 0; 307 (void)memset_s(&connection->msg, sizeof(connection->msg), 0, sizeof(connection->msg)); 308 connection->buffer = nullptr; 309 connection->recvMsgProcess = serverInfo->recvMsgProcess; 310 APPSPAWN_LOGI("OnConnection connection.id %{public}d fd %{public}d ", 311 connection->connectionId, LE_GetSocketFd(stream)); 312 return 0; 313} 314 315void LocalTestServer::SendMessageComplete(const TaskHandle taskHandle, BufferHandle handle) 316{ 317 return; 318} 319 320void LocalTestServer::OnClose(const TaskHandle taskHandle) 321{ 322 TestConnection *connection = (TestConnection *)LE_GetUserData(taskHandle); 323 APPSPAWN_CHECK(connection != nullptr, return, "Invalid connection"); 324 APPSPAWN_LOGI("OnClose connection.id %{public}d socket %{public}d", 325 connection->connectionId, LE_GetSocketFd(taskHandle)); 326 327 AppSpawnConnection *spawnConnection = (AppSpawnConnection *) LE_GetUserData(taskHandle); 328 if (spawnConnection != nullptr) { 329 int fdCount = spawnConnection->receiverCtx.fdCount; 330 for (int i = 0; i < fdCount; i++) { 331 APPSPAWN_LOGI("OnClose close fd %d", spawnConnection->receiverCtx.fds[i]); 332 if (spawnConnection->receiverCtx.fds[i] >= 0) { 333 close(spawnConnection->receiverCtx.fds[i]); 334 } 335 } 336 } 337} 338 339void LocalTestServer::OnReceiveRequest(const TaskHandle taskHandle, const uint8_t *buffer, uint32_t buffLen) 340{ 341 TestConnection *connection = (TestConnection *)LE_GetUserData(taskHandle); 342 APPSPAWN_CHECK(connection != nullptr, LE_CloseTask(LE_GetDefaultLoop(), taskHandle); 343 return, "Failed to get client form socket"); 344 345 if (connection->recvMsgProcess) { 346 connection->recvMsgProcess(connection, buffer, buffLen); 347 } 348} 349 350int LocalTestServer::Run(const char *socketName, RecvMsgProcess recvMsg) 351{ 352 char path[128] = {0}; // 128 max path 353 int ret = snprintf_s(path, sizeof(path), sizeof(path) - 1, "%s%s", APPSPAWN_SOCKET_DIR, socketName); 354 APPSPAWN_CHECK(ret >= 0, return -1, "Failed to snprintf_s %{public}d", ret); 355 LE_StreamServerInfo info = {}; 356 info.baseInfo.flags = TASK_STREAM | TASK_PIPE | TASK_SERVER; 357 info.baseInfo.userDataSize = sizeof(ServerInfo); 358 info.socketId = -1; 359 info.server = path; 360 info.baseInfo.close = nullptr; 361 info.incommingConnect = OnConnection; 362 363 MakeDirRec(path, 0711, 0); // 0711 default mask 364 ret = LE_CreateStreamServer(LE_GetDefaultLoop(), &serverHandle_, &info); 365 APPSPAWN_CHECK(ret == 0, return -1, "Failed to create socket for %{public}s errno: %{public}d", path, errno); 366 APPSPAWN_LOGI("LocalTestServer path %{public}s fd %{public}d", path, LE_GetSocketFd(serverHandle_)); 367 368 ServerInfo *serverInfo = (ServerInfo *)LE_GetUserData(serverHandle_); 369 APPSPAWN_CHECK(serverInfo != nullptr, return -1, "Failed to alloc stream"); 370 serverInfo->local = this; 371 serverInfo->recvMsgProcess = recvMsg; 372 LE_RunLoop(LE_GetDefaultLoop()); 373 LE_CloseStreamTask(LE_GetDefaultLoop(), serverHandle_); 374 LE_StopLoop(LE_GetDefaultLoop()); 375 LE_CloseLoop(LE_GetDefaultLoop()); 376 APPSPAWN_LOGI("LocalTestServer exit"); 377 return 0; 378} 379 380void LocalTestServer::Stop() 381{ 382 APPSPAWN_LOGI("Stop LocalTestServer "); 383 LE_StopLoop(LE_GetDefaultLoop()); 384} 385 386int TestConnection::SendResponse(const AppSpawnMsg *msg, int result, pid_t pid) 387{ 388 APPSPAWN_LOGV("SendResponse result: %{public}d pid: %{public}d", result, pid); 389 uint32_t bufferSize = sizeof(AppSpawnResponseMsg); 390 BufferHandle handle = LE_CreateBuffer(LE_GetDefaultLoop(), bufferSize); 391 AppSpawnResponseMsg *buffer = (AppSpawnResponseMsg *)LE_GetBufferInfo(handle, nullptr, &bufferSize); 392 int ret = memcpy_s(buffer, bufferSize, msg, sizeof(AppSpawnMsg)); 393 APPSPAWN_CHECK(ret == 0, return -1, "Failed to memcpy_s bufferSize"); 394 buffer->result.result = result; 395 buffer->result.pid = pid; 396 return LE_Send(LE_GetDefaultLoop(), stream, handle, bufferSize); 397} 398 399uint32_t AppSpawnTestHelper::GenRandom(void) 400{ 401 uint32_t random = 0; 402 int fd = open("/dev/random", O_RDONLY); 403 if (fd >= 0) { 404 read(fd, &random, sizeof(random)); 405 close(fd); 406 } 407 return random; 408} 409 410CmdArgs *AppSpawnTestHelper::ToCmdList(const char *cmd) 411{ 412 const uint32_t maxArgc = 20; 413 const uint32_t length = sizeof(CmdArgs) + maxArgc * sizeof(char *) + strlen(cmd) + APP_LEN_PROC_NAME + 1 + 2; 414 char *buffer = static_cast<char *>(malloc(length)); 415 CmdArgs *args = reinterpret_cast<CmdArgs *>(buffer); 416 APPSPAWN_CHECK(buffer != nullptr, return nullptr, "Failed to alloc args"); 417 (void)memset_s(args, length, 0, length); 418 char *start = buffer + sizeof(CmdArgs) + maxArgc * sizeof(char *); 419 char *end = buffer + length; 420 uint32_t index = 0; 421 char *curr = const_cast<char *>(cmd); 422 while (isspace(*curr)) { 423 curr++; 424 } 425 426 while (index < (maxArgc - 1) && *curr != '\0') { 427 if (args->argv[index] == nullptr) { 428 args->argv[index] = start; 429 } 430 *start = *curr; 431 if (isspace(*curr)) { 432 *start = '\0'; 433 // 为SetProcessName 预留空间 434 start = (index == 0) ? start + APP_LEN_PROC_NAME : start + 1; 435 while (isspace(*curr) && *curr != '\0') { 436 curr++; 437 } 438 if (*curr != '\0') { 439 index++; 440 } 441 } else { 442 start++; 443 curr++; 444 } 445 } 446 447 index++; 448 args->argv[index] = end - 2; // 2 last 449 args->argv[index][0] = '#'; 450 args->argv[index][1] = '\0'; 451 args->argc = index + 1; 452 return args; 453} 454 455int AppSpawnTestHelper::AddDacInfo(AppSpawnReqMsgHandle &reqHandle) 456{ 457 AppDacInfo dacInfo = {}; 458 dacInfo.uid = defaultTestUid_; 459 dacInfo.gid = defaultTestGid_; 460 dacInfo.gidCount = 2; // 2 count 461 dacInfo.gidTable[0] = defaultTestGidGroup_; 462 dacInfo.gidTable[1] = defaultTestGidGroup_ + 1; 463 APPSPAWN_CHECK_ONLY_EXPER(strcpy_s(dacInfo.userName, sizeof(dacInfo.userName), "test-app-name") == 0, 464 return APPSPAWN_ARG_INVALID); 465 return AppSpawnReqMsgSetAppDacInfo(reqHandle, &dacInfo); 466} 467 468int AppSpawnTestHelper::AddFdInfo(AppSpawnReqMsgHandle &reqHandle) 469{ 470 if (fdArg < 0) { 471 fdArg = open("/dev/random", O_RDONLY); 472 } 473 APPSPAWN_LOGE("Add fd info %d", fdArg); 474 APPSPAWN_CHECK(fdArg >= 0, return -1, "open fd failed "); 475 return AppSpawnReqMsgAddFd(reqHandle, "fdname", fdArg); 476} 477 478AppSpawnReqMsgHandle AppSpawnTestHelper::CreateMsg(AppSpawnClientHandle handle, uint32_t msgType, int base) 479{ 480 AppSpawnReqMsgHandle reqHandle = 0; 481 int ret = AppSpawnReqMsgCreate(static_cast<AppSpawnMsgType>(msgType), processName_.c_str(), &reqHandle); 482 APPSPAWN_CHECK(ret == 0, return INVALID_REQ_HANDLE, "Failed to create req %{public}s", processName_.c_str()); 483 APPSPAWN_CHECK_ONLY_EXPER(msgType == MSG_APP_SPAWN || msgType == MSG_SPAWN_NATIVE_PROCESS, return reqHandle); 484 do { 485 ret = AddFdInfo(reqHandle); 486 APPSPAWN_CHECK(ret == 0, break, "Failed to add fd %{public}s", processName_.c_str()); 487 ret = AppSpawnReqMsgSetBundleInfo(reqHandle, 100, processName_.c_str()); // 100 test index 488 APPSPAWN_CHECK(ret == 0, break, "Failed to add bundle info req %{public}s", processName_.c_str()); 489 ret = AddDacInfo(reqHandle); 490 APPSPAWN_CHECK(ret == 0, break, "Failed to add dac %{public}s", processName_.c_str()); 491 ret = AppSpawnReqMsgSetAppAccessToken(reqHandle, 12345678); // 12345678 492 APPSPAWN_CHECK(ret == 0, break, "Failed to add access token %{public}s", processName_.c_str()); 493 494 if (defaultMsgFlags_ != 0) { 495 (void)AppSpawnReqMsgSetFlags(reqHandle, TLV_MSG_FLAGS, defaultMsgFlags_); 496 } 497 if (base) { 498 return reqHandle; 499 } 500 const char *testData = "ssssssssssssss sssssssss ssssssss"; 501 ret = AppSpawnReqMsgAddExtInfo(reqHandle, "tlv-name-1", 502 reinterpret_cast<uint8_t *>(const_cast<char *>(testData)), strlen(testData)); 503 APPSPAWN_CHECK(ret == 0, break, "Failed to ext tlv %{public}s", processName_.c_str()); 504 size_t count = permissions_.size(); 505 for (size_t i = 0; i < count; i++) { 506 ret = AppSpawnReqMsgAddPermission(reqHandle, permissions_[i]); 507 APPSPAWN_CHECK(ret == 0, break, "Failed to permission %{public}s", permissions_[i]); 508 } 509 510 ret = AppSpawnReqMsgSetAppInternetPermissionInfo(reqHandle, 1, 0); 511 APPSPAWN_CHECK(ret == 0, break, "Failed to internet info %{public}s", processName_.c_str()); 512 513 ret = AppSpawnReqMsgSetAppOwnerId(reqHandle, "ohos.permission.FILE_ACCESS_MANAGER"); 514 APPSPAWN_CHECK(ret == 0, break, "Failed to ownerid %{public}s", processName_.c_str()); 515 const char *renderCmd = "/system/bin/sh ls -l "; 516 ret = AppSpawnReqMsgAddExtInfo(reqHandle, MSG_EXT_NAME_RENDER_CMD, 517 reinterpret_cast<const uint8_t *>(renderCmd), strlen(renderCmd)); 518 APPSPAWN_CHECK(ret == 0, break, "Failed to render cmd %{public}s", processName_.c_str()); 519 ret = AppSpawnReqMsgSetAppDomainInfo(reqHandle, 1, defaultApl_.c_str()); 520 APPSPAWN_CHECK(ret == 0, break, "Failed to domain info %{public}s", processName_.c_str()); 521 return reqHandle; 522 } while (0); 523 AppSpawnReqMsgFree(reqHandle); 524 return INVALID_REQ_HANDLE; 525} 526 527AppSpawnMsgNode *AppSpawnTestHelper::CreateAppSpawnMsg(AppSpawnMsg *msg) 528{ 529 AppSpawnMsgNode *msgNode = static_cast<AppSpawnMsgNode *>(calloc(1, sizeof(AppSpawnMsgNode))); 530 APPSPAWN_CHECK(msgNode != nullptr, return nullptr, "Failed to create receiver"); 531 int ret = memcpy_s(&msgNode->msgHeader, sizeof(msgNode->msgHeader), msg, sizeof(msgNode->msgHeader)); 532 APPSPAWN_CHECK(ret == 0, free(msgNode); 533 return nullptr, "Failed to memcpy msg"); 534 msgNode->buffer = static_cast<uint8_t *>(malloc(msg->msgLen)); 535 APPSPAWN_CHECK(msgNode->buffer != nullptr, free(msgNode); 536 return nullptr, "Failed to memcpy msg"); 537 uint32_t totalCount = msg->tlvCount + TLV_MAX; 538 msgNode->tlvOffset = static_cast<uint32_t *>(malloc(totalCount * sizeof(uint32_t))); 539 APPSPAWN_CHECK(msgNode->tlvOffset != nullptr, free(msgNode); 540 return nullptr, "Failed to alloc memory for recv message"); 541 for (uint32_t i = 0; i < totalCount; i++) { 542 msgNode->tlvOffset[i] = INVALID_OFFSET; 543 } 544 return msgNode; 545} 546 547AppSpawningCtx *AppSpawnTestHelper::GetAppProperty(AppSpawnClientHandle handle, AppSpawnReqMsgHandle reqHandle) 548{ 549 AppSpawnReqMsgNode *reqNode = static_cast<AppSpawnReqMsgNode *>(reqHandle); 550 APPSPAWN_CHECK(reqNode != nullptr && reqNode->msg != nullptr, AppSpawnReqMsgFree(reqHandle); 551 return nullptr, "Invalid reqNode"); 552 553 AppSpawnMsgNode *msgNode = CreateAppSpawnMsg(reqNode->msg); 554 APPSPAWN_CHECK(msgNode != nullptr, return nullptr, "Failed to alloc for msg"); 555 556 uint32_t bufferSize = reqNode->msg->msgLen; 557 uint32_t currIndex = 0; 558 uint32_t bufferStart = sizeof(AppSpawnMsg); 559 ListNode *node = reqNode->msgBlocks.next; 560 while (node != &reqNode->msgBlocks) { 561 AppSpawnMsgBlock *block = ListEntry(node, AppSpawnMsgBlock, node); 562 int ret = memcpy_s(msgNode->buffer + currIndex, bufferSize - currIndex, 563 block->buffer + bufferStart, block->currentIndex - bufferStart); 564 if (ret != 0) { 565 AppSpawnReqMsgFree(reqHandle); 566 DeleteAppSpawnMsg(msgNode); 567 return nullptr; 568 } 569 currIndex += block->currentIndex - bufferStart; 570 bufferStart = 0; 571 node = node->next; 572 } 573 APPSPAWN_LOGV("GetAppProperty header magic 0x%{public}x type %{public}u id %{public}u len %{public}u %{public}s", 574 msgNode->msgHeader.magic, msgNode->msgHeader.msgType, 575 msgNode->msgHeader.msgId, msgNode->msgHeader.msgLen, msgNode->msgHeader.processName); 576 577 // delete reqHandle 578 AppSpawnReqMsgFree(reqHandle); 579 int ret = DecodeAppSpawnMsg(msgNode); 580 APPSPAWN_CHECK(ret == 0, DeleteAppSpawnMsg(msgNode); 581 return nullptr, "Decode msg fail"); 582 AppSpawningCtx *property = CreateAppSpawningCtx(); 583 APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, DeleteAppSpawnMsg(msgNode); 584 return nullptr); 585 property->message = msgNode; 586 SetDefaultTestData(); 587 return property; 588} 589 590void AppSpawnTestHelper::SetDefaultTestData() 591{ 592 processName_ = std::string("com.example.myapplication"); 593 defaultTestUid_ = 20010029; // 20010029 test 594 defaultTestGid_ = 20010029; // 20010029 test 595 defaultTestGidGroup_ = 20010029; // 20010029 test 596 defaultTestBundleIndex_ = 100; // 100 test 597 defaultApl_ = std::string("system_core"); 598 defaultMsgFlags_ = 0; 599} 600 601int AppSpawnTestHelper::CreateSocket(int type) 602{ 603 const uint32_t maxCount = 10; 604 uint32_t count = 0; 605 int socketId = -1; 606 while ((socketId < 0) && (count < maxCount)) { 607 usleep(20000); // 20000 20ms 608 socketId = CreateClientSocket(type, 2); // 2s 609 if (socketId > 0) { 610 return socketId; 611 } 612 count++; 613 } 614 return socketId; 615} 616 617int AppSpawnTestHelper::CreateSendMsg(std::vector<uint8_t> &buffer, uint32_t msgType, uint32_t &msgLen, 618 const std::vector<AddTlvFunction> &addTlvFuncs) 619{ 620 if (buffer.size() < sizeof(AppSpawnMsg)) { 621 return -1; 622 } 623 AppSpawnMsg *msg = reinterpret_cast<AppSpawnMsg *>(buffer.data()); 624 msg->magic = APPSPAWN_MSG_MAGIC; 625 msg->msgType = msgType; 626 msg->msgLen = sizeof(AppSpawnMsg); 627 msg->msgId = 1; 628 msg->tlvCount = 0; 629 APPSPAWN_CHECK_ONLY_EXPER(strcpy_s(msg->processName, sizeof(msg->processName), processName_.c_str()) == 0, 630 return -1); 631 // add tlv 632 uint32_t currLen = sizeof(AppSpawnMsg); 633 for (auto addTlvFunc : addTlvFuncs) { 634 uint32_t realLen = 0; 635 uint32_t tlvCount = 0; 636 int ret = addTlvFunc(buffer.data() + currLen, buffer.size() - currLen, realLen, tlvCount); 637 APPSPAWN_CHECK(ret == 0 && (currLen + realLen) < buffer.size(), 638 return -1, "Failed add tlv to msg %{public}s", processName_.c_str()); 639 msg->msgLen += realLen; 640 currLen += realLen; 641 msg->tlvCount += tlvCount; 642 } 643 msgLen = msg->msgLen; 644 APPSPAWN_LOGV("CreateSendMsg msgLen %{public}d", msgLen); 645 return 0; 646} 647 648static int inline AddOneTlv(uint8_t *buffer, uint32_t bufferLen, const AppSpawnTlv &tlv, const uint8_t *data) 649{ 650 if (tlv.tlvLen > bufferLen) { 651 return -1; 652 } 653 int ret = memcpy_s(buffer, bufferLen, &tlv, sizeof(tlv)); 654 APPSPAWN_CHECK(ret == 0, return -1, "Failed to memcpy_s bufferSize"); 655 ret = memcpy_s(buffer + sizeof(tlv), bufferLen - sizeof(tlv), data, tlv.tlvLen - sizeof(tlv)); 656 APPSPAWN_CHECK(ret == 0, return -1, "Failed to memcpy_s bufferSize"); 657 return 0; 658} 659 660#define ADD_TLV(type, value, currLen, tlvCount) \ 661do { \ 662 AppSpawnTlv d_tlv = {}; \ 663 d_tlv.tlvType = (type); \ 664 d_tlv.tlvLen = sizeof(AppSpawnTlv) + sizeof(value); \ 665 ret = AddOneTlv(buffer + (currLen), bufferLen - (currLen), d_tlv, (uint8_t *)&(value)); \ 666 APPSPAWN_CHECK(ret == 0, return -1, "Failed add tlv %{public}u", d_tlv.tlvType); \ 667 (currLen) += d_tlv.tlvLen; \ 668 (tlvCount)++; \ 669} while (0) 670 671int AppSpawnTestHelper::AddBaseTlv(uint8_t *buffer, uint32_t bufferLen, uint32_t &realLen, uint32_t &tlvCount) 672{ 673 // add app flage 674 uint32_t currLen = 0; 675 uint32_t flags[2] = {1, 0b1010}; 676 AppSpawnTlv tlv = {}; 677 tlv.tlvType = TLV_MSG_FLAGS; 678 tlv.tlvLen = sizeof(AppSpawnTlv) + sizeof(flags); 679 int ret = AddOneTlv(buffer + currLen, bufferLen - currLen, tlv, (uint8_t *)flags); 680 APPSPAWN_CHECK(ret == 0, return -1, "Failed add tlv %{public}u", tlv.tlvType); 681 currLen += tlv.tlvLen; 682 tlvCount++; 683 684 tlv.tlvType = TLV_PERMISSION; 685 tlv.tlvLen = sizeof(AppSpawnTlv) + sizeof(flags); 686 ret = AddOneTlv(buffer + currLen, bufferLen - currLen, tlv, (uint8_t *)flags); 687 APPSPAWN_CHECK(ret == 0, return -1, "Failed add tlv %{public}u", tlv.tlvType); 688 currLen += tlv.tlvLen; 689 tlvCount++; 690 691 AppDomainInfo domainInfo = {0, "normal"}; 692 ADD_TLV(TLV_DOMAIN_INFO, domainInfo, currLen, tlvCount); 693 694 AppSpawnMsgAccessToken token = {12345678}; // 12345678 695 ADD_TLV(TLV_ACCESS_TOKEN_INFO, token, currLen, tlvCount); 696 697 AppSpawnMsgInternetInfo internetInfo = {0, 1}; 698 ADD_TLV(TLV_INTERNET_INFO, internetInfo, currLen, tlvCount); 699 700 // add bundle info 701 AppBundleInfo info = {}; 702 APPSPAWN_CHECK_ONLY_EXPER(strcpy_s(info.bundleName, sizeof(info.bundleName), "test-bundleName") == 0, 703 return -1); 704 info.bundleIndex = 100; // 100 test index 705 ADD_TLV(TLV_BUNDLE_INFO, info, currLen, tlvCount); 706 707 // add dac 708 AppDacInfo dacInfo = {}; 709 dacInfo.uid = 20010029; // 20010029 test uid 710 dacInfo.gid = 20010029; // 20010029 test gid 711 dacInfo.gidCount = 2; // 2 count 712 dacInfo.gidTable[0] = 20010029; // 20010029 test gid 713 dacInfo.gidTable[1] = 20010030; // 20010030 test gid 714 ADD_TLV(TLV_DAC_INFO, dacInfo, currLen, tlvCount); 715 realLen = currLen; 716 return 0; 717} 718 719AppSpawnContent *AppSpawnTestHelper::StartSpawnServer(std::string &cmd, CmdArgs *&args) 720{ 721 args = AppSpawnTestHelper::ToCmdList(cmd.c_str()); 722 APPSPAWN_CHECK(args != nullptr, return nullptr, "Failed to alloc args"); 723 724 AppSpawnStartArg startRrg = {}; 725 startRrg.mode = MODE_FOR_APP_SPAWN; 726 startRrg.socketName = APPSPAWN_SOCKET_NAME; 727 startRrg.serviceName = APPSPAWN_SERVER_NAME; 728 startRrg.moduleType = MODULE_APPSPAWN; 729 startRrg.initArg = 1; 730 if (args->argc <= MODE_VALUE_INDEX) { // appspawn start 731 startRrg.mode = MODE_FOR_APP_SPAWN; 732 } else if (strcmp(args->argv[MODE_VALUE_INDEX], "app_cold") == 0) { // cold start 733 APPSPAWN_CHECK(args->argc >= ARG_NULL, free(args); 734 return nullptr, "Invalid arg for cold start %{public}d", args->argc); 735 startRrg.mode = MODE_FOR_APP_COLD_RUN; 736 startRrg.initArg = 0; 737 } else if (strcmp(args->argv[MODE_VALUE_INDEX], "nweb_cold") == 0) { // cold start 738 APPSPAWN_CHECK(args->argc >= ARG_NULL, free(args); 739 return nullptr, "Invalid arg for cold start %{public}d", args->argc); 740 startRrg.mode = MODE_FOR_NWEB_COLD_RUN; 741 startRrg.serviceName = NWEBSPAWN_SERVER_NAME; 742 startRrg.initArg = 0; 743 } else if (strcmp(args->argv[MODE_VALUE_INDEX], NWEBSPAWN_SERVER_NAME) == 0) { // nweb spawn start 744 startRrg.mode = MODE_FOR_NWEB_SPAWN; 745 startRrg.moduleType = MODULE_NWEBSPAWN; 746 startRrg.socketName = NWEBSPAWN_SOCKET_NAME; 747 startRrg.serviceName = NWEBSPAWN_SERVER_NAME; 748 } 749 APPSPAWN_LOGV("Start service %{public}s", startRrg.serviceName); 750 AppSpawnContent *content = StartSpawnService(&startRrg, APP_LEN_PROC_NAME, args->argc, args->argv); 751 if (content == nullptr) { 752 free(args); 753 } 754 return content; 755} 756} // namespace OHOS 757 758MODULE_CONSTRUCTOR(void) 759{ 760 MakeDirRec(APPSPAWN_MSG_DIR "appspawn", 0771, 1); 761 MakeDirRec(APPSPAWN_MSG_DIR "nwebspawn", 0771, 1); 762} 763