• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "appspawn_service.h"
17 
18 #include <dirent.h>
19 #include <fcntl.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <sys/signalfd.h>
24 #include <sys/socket.h>
25 #include <sys/wait.h>
26 #include <sys/mman.h>
27 #include <sys/syscall.h>
28 #include <signal.h>
29 #include <sys/mount.h>
30 #include <unistd.h>
31 #include <sys/prctl.h>
32 #include <sched.h>
33 #include "appspawn.h"
34 #include "appspawn_hook.h"
35 #include "appspawn_modulemgr.h"
36 #include "appspawn_manager.h"
37 #include "appspawn_msg.h"
38 #include "appspawn_server.h"
39 #include "appspawn_trace.h"
40 #include "appspawn_utils.h"
41 #include "init_socket.h"
42 #include "init_utils.h"
43 #include "parameter.h"
44 #include "appspawn_adapter.h"
45 #include "securec.h"
46 #include "cJSON.h"
47 #ifdef APPSPAWN_HISYSEVENT
48 #include "appspawn_hisysevent.h"
49 #include "hisysevent_adapter.h"
50 #endif
51 #define PARAM_BUFFER_SIZE 10
52 #define PATH_SIZE 256
53 #define FD_PATH_SIZE 128
54 
55 #define PREFORK_PROCESS "apppool"
56 #define APPSPAWN_MSG_USER_CHECK_COUNT 4
57 #define USER_ID_MIN_VALUE 100
58 #define USER_ID_MAX_VALUE 10736
59 #define LOCK_STATUS_PARAM_SIZE 64
60 #ifndef PIDFD_NONBLOCK
61 #define PIDFD_NONBLOCK O_NONBLOCK
62 #endif
63 
64 static void WaitChildTimeout(const TimerHandle taskHandle, void *context);
65 static void ProcessChildResponse(const WatcherHandle taskHandle, int fd, uint32_t *events, const void *context);
66 static void WaitChildDied(pid_t pid);
67 static void OnReceiveRequest(const TaskHandle taskHandle, const uint8_t *buffer, uint32_t buffLen);
68 static void ProcessRecvMsg(AppSpawnConnection *connection, AppSpawnMsgNode *message);
69 
70 // FD_CLOEXEC
SetFdCtrl(int fd,int opt)71 static inline void SetFdCtrl(int fd, int opt)
72 {
73     int option = fcntl(fd, F_GETFD);
74     APPSPAWN_CHECK(option >= 0, return, "SetFdCtrl fcntl failed %{public}d, %{public}d", option, errno);
75     int ret = fcntl(fd, F_SETFD, (unsigned int)option | (unsigned int)opt);
76     if (ret < 0) {
77         APPSPAWN_LOGI("Set fd %{public}d option %{public}d %{public}d result: %{public}d", fd, option, opt, errno);
78     }
79 }
80 
AppQueueDestroyProc(const AppSpawnMgr * mgr,AppSpawnedProcess * appInfo,void * data)81 static void AppQueueDestroyProc(const AppSpawnMgr *mgr, AppSpawnedProcess *appInfo, void *data)
82 {
83     pid_t pid = appInfo->pid;
84     APPSPAWN_LOGI("kill %{public}s pid: %{public}d", appInfo->name, appInfo->pid);
85     // notify child proess died,clean sandbox info
86     ProcessMgrHookExecute(STAGE_SERVER_APP_DIED, GetAppSpawnContent(), appInfo);
87     OH_ListRemove(&appInfo->node);
88     OH_ListInit(&appInfo->node);
89     free(appInfo);
90     if (pid > 0 && kill(pid, SIGKILL) != 0) {
91         APPSPAWN_LOGE("unable to kill process, pid: %{public}d errno: %{public}d", pid, errno);
92     }
93 }
94 
StopAppSpawn(void)95 static void StopAppSpawn(void)
96 {
97     // delete nwespawn, and wait exit. Otherwise, the process of nwebspawn spawning will become zombie
98     AppSpawnedProcess *appInfo = GetSpawnedProcessByName(NWEBSPAWN_SERVER_NAME);
99     if (appInfo != NULL) {
100         APPSPAWN_LOGI("kill %{public}s pid: %{public}d", appInfo->name, appInfo->pid);
101         int exitStatus = 0;
102         KillAndWaitStatus(appInfo->pid, SIGTERM, &exitStatus);
103         OH_ListRemove(&appInfo->node);
104         OH_ListInit(&appInfo->node);
105         free(appInfo);
106     }
107     // delete nativespawn, and wait exit. Otherwise, the process of nativespawn spawning will become zombie
108     appInfo = GetSpawnedProcessByName(NATIVESPAWN_SERVER_NAME);
109     if (appInfo != NULL) {
110         APPSPAWN_LOGI("kill %{public}s pid: %{public}d", appInfo->name, appInfo->pid);
111         int exitStatus = 0;
112         KillAndWaitStatus(appInfo->pid, SIGTERM, &exitStatus);
113         OH_ListRemove(&appInfo->node);
114         OH_ListInit(&appInfo->node);
115         free(appInfo);
116     }
117 
118     AppSpawnContent *content = GetAppSpawnContent();
119     if (content != NULL && content->reservedPid > 0) {
120         int ret = kill(content->reservedPid, SIGKILL);
121         APPSPAWN_CHECK_ONLY_LOG(ret == 0, "kill reserved pid %{public}d failed %{public}d %{public}d",
122             content->reservedPid, ret, errno);
123         content->reservedPid = 0;
124     }
125     TraversalSpawnedProcess(AppQueueDestroyProc, NULL);
126     APPSPAWN_LOGI("StopAppSpawn ");
127 #ifdef APPSPAWN_HISYSEVENT
128     AppSpawnHiSysEventWrite();
129 #endif
130     LE_StopLoop(LE_GetDefaultLoop());
131 }
132 
DumpStatus(const char * appName,pid_t pid,int status,int * signal)133 static inline void DumpStatus(const char *appName, pid_t pid, int status, int *signal)
134 {
135     if (WIFSIGNALED(status)) {
136         *signal = WTERMSIG(status);
137         APPSPAWN_LOGW("%{public}s with pid %{public}d exit with signal:%{public}d", appName, pid, *signal);
138     }
139     if (WIFEXITED(status)) {
140         *signal = WEXITSTATUS(status);
141         APPSPAWN_LOGW("%{public}s with pid %{public}d exit with code:%{public}d", appName, pid, *signal);
142     }
143 }
144 
WriteSignalInfoToFd(AppSpawnedProcess * appInfo,AppSpawnContent * content,int signal)145 APPSPAWN_STATIC void WriteSignalInfoToFd(AppSpawnedProcess *appInfo, AppSpawnContent *content, int signal)
146 {
147     APPSPAWN_CHECK(content->signalFd > 0, return, "Invalid signal fd[%{public}d]", content->signalFd);
148     APPSPAWN_CHECK(appInfo->pid > 0, return, "Invalid pid[%{public}d]", appInfo->pid);
149     APPSPAWN_CHECK(appInfo->uid > 0, return, "Invalid uid[%{public}d]", appInfo->uid);
150     APPSPAWN_CHECK(appInfo->name != NULL, return, "Invalid name");
151 
152     cJSON *root = cJSON_CreateObject();
153     if (root == NULL) {
154         APPSPAWN_LOGE("signal json write create root object unsuccess");
155         return;
156     }
157     cJSON_AddNumberToObject(root, "pid", appInfo->pid);
158     cJSON_AddNumberToObject(root, "uid", appInfo->uid);
159     cJSON_AddNumberToObject(root, "signal", signal);
160     cJSON_AddStringToObject(root, "bundleName", appInfo->name);
161     char *jsonString = cJSON_Print(root);
162     cJSON_Delete(root);
163 
164     int ret = write(content->signalFd, jsonString, strlen(jsonString) + 1);
165     if (ret < 0) {
166         free(jsonString);
167         APPSPAWN_LOGE("Spawn Listen failed to write signal info to fd errno %{public}d", errno);
168         return;
169     }
170     APPSPAWN_LOGI("Spawn Listen successfully write signal info[%{public}s] to fd", jsonString);
171     free(jsonString);
172 }
173 
HandleDiedPid(pid_t pid,uid_t uid,int status)174 static void HandleDiedPid(pid_t pid, uid_t uid, int status)
175 {
176     AppSpawnContent *content = GetAppSpawnContent();
177     APPSPAWN_CHECK(content != NULL, return, "Invalid content");
178 
179     if (pid == content->reservedPid) {
180         APPSPAWN_LOGW("HandleDiedPid with reservedPid %{public}d", pid);
181         content->reservedPid = 0;
182     }
183     int signal = 0;
184     AppSpawnedProcess *appInfo = GetSpawnedProcess(pid);
185     if (appInfo == NULL) { // If an exception occurs during app spawning, kill pid, return failed
186         WaitChildDied(pid);
187         DumpStatus("unknown", pid, status, &signal);
188         return;
189     }
190 
191     appInfo->exitStatus = status;
192     APPSPAWN_CHECK_ONLY_LOG(appInfo->uid == uid, "Invalid uid %{public}u %{public}u", appInfo->uid, uid);
193     DumpStatus(appInfo->name, pid, status, &signal);
194     WriteSignalInfoToFd(appInfo, content, signal);
195     ProcessMgrHookExecute(STAGE_SERVER_APP_DIED, GetAppSpawnContent(), appInfo);
196     ProcessMgrHookExecute(STAGE_SERVER_APP_UMOUNT, GetAppSpawnContent(), appInfo);
197 
198     // if current process of death is nwebspawn, restart appspawn
199     if (strcmp(appInfo->name, NWEBSPAWN_SERVER_NAME) == 0) {
200         OH_ListRemove(&appInfo->node);
201         free(appInfo);
202         APPSPAWN_LOGW("Current process of death is nwebspawn, pid = %{public}d, restart appspawn", pid);
203         StopAppSpawn();
204         return;
205     }
206     // move app info to died queue in NWEBSPAWN, or delete appinfo
207     TerminateSpawnedProcess(appInfo);
208 }
209 
ProcessSignal(const struct signalfd_siginfo * siginfo)210 APPSPAWN_STATIC void ProcessSignal(const struct signalfd_siginfo *siginfo)
211 {
212     APPSPAWN_LOGI("ProcessSignal signum %{public}d %{public}d", siginfo->ssi_signo, siginfo->ssi_pid);
213     switch (siginfo->ssi_signo) {
214         case SIGCHLD: { // delete pid from app map
215             pid_t pid;
216             int status;
217             while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
218                 APPSPAWN_CHECK(WIFSIGNALED(status) || WIFEXITED(status), return,
219                     "ProcessSignal with wrong status:%{public}d", status);
220                 HandleDiedPid(pid, siginfo->ssi_uid, status);
221             }
222 #if (defined(CJAPP_SPAWN) || defined(NATIVE_SPAWN))
223             if (OH_ListGetCnt(&GetAppSpawnMgr()->appQueue) == 0) {
224                 LE_StopLoop(LE_GetDefaultLoop());
225             }
226 #endif
227             break;
228         }
229         case SIGTERM: { // appswapn killed, use kill without parameter
230             StopAppSpawn();
231             break;
232         }
233         default:
234             APPSPAWN_LOGI("SigHandler, unsupported signal %{public}d.", siginfo->ssi_signo);
235             break;
236     }
237 }
238 
AppSpawningCtxOnClose(const AppSpawnMgr * mgr,AppSpawningCtx * ctx,void * data)239 static void AppSpawningCtxOnClose(const AppSpawnMgr *mgr, AppSpawningCtx *ctx, void *data)
240 {
241     if (ctx == NULL || ctx->message == NULL || ctx->message->connection != data) {
242         return;
243     }
244     APPSPAWN_LOGI("Kill process, pid: %{public}d app: %{public}s", ctx->pid, GetProcessName(ctx));
245     if (ctx->pid > 0 && kill(ctx->pid, SIGKILL) != 0) {
246         APPSPAWN_LOGE("unable to kill process, pid: %{public}d errno: %{public}d", ctx->pid, errno);
247     }
248     DeleteAppSpawningCtx(ctx);
249 }
250 
OnClose(const TaskHandle taskHandle)251 static void OnClose(const TaskHandle taskHandle)
252 {
253     if (!IsSpawnServer(GetAppSpawnMgr())) {
254         return;
255     }
256     AppSpawnConnection *connection = (AppSpawnConnection *)LE_GetUserData(taskHandle);
257     APPSPAWN_CHECK(connection != NULL, return, "Invalid connection");
258     if (connection->receiverCtx.timer) {
259         LE_StopTimer(LE_GetDefaultLoop(), connection->receiverCtx.timer);
260         connection->receiverCtx.timer = NULL;
261     }
262     APPSPAWN_LOGI("OnClose connectionId: %{public}u socket %{public}d",
263         connection->connectionId, LE_GetSocketFd(taskHandle));
264     DeleteAppSpawnMsg(&connection->receiverCtx.incompleteMsg);
265     connection->receiverCtx.incompleteMsg = NULL;
266     // connect close, to close spawning app
267     AppSpawningCtxTraversal(AppSpawningCtxOnClose, connection);
268 }
269 
OnDisConnect(const TaskHandle taskHandle)270 static void OnDisConnect(const TaskHandle taskHandle)
271 {
272     AppSpawnConnection *connection = (AppSpawnConnection *)LE_GetUserData(taskHandle);
273     APPSPAWN_CHECK(connection != NULL, return, "Invalid connection");
274     APPSPAWN_LOGI("OnDisConnect connectionId: %{public}u socket %{public}d",
275         connection->connectionId, LE_GetSocketFd(taskHandle));
276     OnClose(taskHandle);
277 }
278 
SendMessageComplete(const TaskHandle taskHandle,BufferHandle handle)279 static void SendMessageComplete(const TaskHandle taskHandle, BufferHandle handle)
280 {
281     AppSpawnConnection *connection = (AppSpawnConnection *)LE_GetUserData(taskHandle);
282     APPSPAWN_CHECK(connection != NULL, return, "Invalid connection");
283     uint32_t bufferSize = sizeof(AppSpawnResponseMsg);
284     AppSpawnResponseMsg *msg = (AppSpawnResponseMsg *)LE_GetBufferInfo(handle, NULL, &bufferSize);
285     if (msg == NULL) {
286         return;
287     }
288     AppSpawnedProcess *appInfo = GetSpawnedProcess(msg->result.pid);
289     if (appInfo == NULL) {
290         return;
291     }
292     APPSPAWN_LOGI("SendMessageComplete connectionId: %{public}u result %{public}d app %{public}s pid %{public}d",
293         connection->connectionId, LE_GetSendResult(handle), appInfo->name, msg->result.pid);
294     if (LE_GetSendResult(handle) != 0 && msg->result.pid > 0) {
295         kill(msg->result.pid, SIGKILL);
296     }
297 }
298 
SendResponse(const AppSpawnConnection * connection,const AppSpawnMsg * msg,int result,pid_t pid)299 static int SendResponse(const AppSpawnConnection *connection, const AppSpawnMsg *msg, int result, pid_t pid)
300 {
301     APPSPAWN_LOGV("SendResponse connectionId: %{public}u result: 0x%{public}x pid: %{public}d",
302         connection->connectionId, result, pid);
303     uint32_t bufferSize = sizeof(AppSpawnResponseMsg);
304     BufferHandle handle = LE_CreateBuffer(LE_GetDefaultLoop(), bufferSize);
305     AppSpawnResponseMsg *buffer = (AppSpawnResponseMsg *)LE_GetBufferInfo(handle, NULL, &bufferSize);
306     int ret = memcpy_s(buffer, bufferSize, msg, sizeof(AppSpawnMsg));
307     APPSPAWN_CHECK(ret == 0, LE_FreeBuffer(LE_GetDefaultLoop(), NULL, handle);
308         return -1, "Failed to memcpy_s bufferSize");
309     buffer->result.result = result;
310     buffer->result.pid = pid;
311     return LE_Send(LE_GetDefaultLoop(), connection->stream, handle, bufferSize);
312 }
313 
WaitMsgCompleteTimeOut(const TimerHandle taskHandle,void * context)314 static void WaitMsgCompleteTimeOut(const TimerHandle taskHandle, void *context)
315 {
316     AppSpawnConnection *connection = (AppSpawnConnection *)context;
317     APPSPAWN_LOGE("Long time no msg complete so close connectionId: %{public}u", connection->connectionId);
318     DeleteAppSpawnMsg(&connection->receiverCtx.incompleteMsg);
319     connection->receiverCtx.incompleteMsg = NULL;
320     LE_CloseStreamTask(LE_GetDefaultLoop(), connection->stream);
321 }
322 
StartTimerForCheckMsg(AppSpawnConnection * connection)323 static inline int StartTimerForCheckMsg(AppSpawnConnection *connection)
324 {
325     if (connection->receiverCtx.timer != NULL) {
326         return 0;
327     }
328     int ret = LE_CreateTimer(LE_GetDefaultLoop(), &connection->receiverCtx.timer, WaitMsgCompleteTimeOut, connection);
329     if (ret == 0) {
330         ret = LE_StartTimer(LE_GetDefaultLoop(), connection->receiverCtx.timer, MAX_WAIT_MSG_COMPLETE, 1);
331     }
332     return ret;
333 }
334 
HandleRecvMessage(const TaskHandle taskHandle,uint8_t * buffer,int bufferSize,int flags)335 static int HandleRecvMessage(const TaskHandle taskHandle, uint8_t * buffer, int bufferSize, int flags)
336 {
337     int socketFd = LE_GetSocketFd(taskHandle);
338     struct iovec iov = {
339         .iov_base = buffer,
340         .iov_len = bufferSize,
341     };
342     char ctrlBuffer[CMSG_SPACE(APP_MAX_FD_COUNT * sizeof(int))];
343     struct msghdr msg = {
344         .msg_iov = &iov,
345         .msg_iovlen = 1,
346         .msg_control = ctrlBuffer,
347         .msg_controllen = sizeof(ctrlBuffer),
348     };
349 
350     AppSpawnConnection *connection = (AppSpawnConnection *) LE_GetUserData(taskHandle);
351     APPSPAWN_CHECK(connection != NULL, return -1, "Invalid connection");
352     errno = 0;
353     int recvLen = recvmsg(socketFd, &msg, flags);
354     APPSPAWN_CHECK_ONLY_LOG(errno == 0, "recvmsg with errno %{public}d", errno);
355     struct cmsghdr *cmsg = NULL;
356     for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
357         if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
358             int fdCount = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
359             int *fd = (int *) CMSG_DATA(cmsg);
360             APPSPAWN_CHECK(fdCount <= APP_MAX_FD_COUNT, return -1,
361                 "failed to recv fd %{public}d %{public}d", connection->receiverCtx.fdCount, fdCount);
362             int ret = memcpy_s(connection->receiverCtx.fds,
363                 fdCount * sizeof(int), fd, fdCount * sizeof(int));
364             APPSPAWN_CHECK(ret == 0, return -1, "memcpy_s fd ret %{public}d", ret);
365             connection->receiverCtx.fdCount = fdCount;
366         }
367     }
368 
369     return recvLen;
370 }
371 
OnConnectionUserCheck(uid_t uid)372 APPSPAWN_STATIC bool OnConnectionUserCheck(uid_t uid)
373 {
374     const uid_t uids[APPSPAWN_MSG_USER_CHECK_COUNT] = {
375         0, // root 0
376         3350, // app_fwk_update 3350
377         5523, // foundation 5523
378         1090, //storage_manager 1090
379     };
380 
381     for (int i = 0; i < APPSPAWN_MSG_USER_CHECK_COUNT; i++) {
382         if (uid == uids[i]) {
383             return true;
384         }
385     }
386 
387     // shell 2000
388     if (uid == 2000 && IsDeveloperModeOpen()) {
389         return true;
390     }
391 
392     return false;
393 }
394 
OnConnection(const LoopHandle loopHandle,const TaskHandle server)395 static int OnConnection(const LoopHandle loopHandle, const TaskHandle server)
396 {
397     APPSPAWN_CHECK(server != NULL && loopHandle != NULL, return -1, "Error server");
398     static uint32_t connectionId = 0;
399     TaskHandle stream;
400     LE_StreamInfo info = {};
401     info.baseInfo.flags = TASK_STREAM | TASK_PIPE | TASK_CONNECT;
402     info.baseInfo.close = OnClose;
403     info.baseInfo.userDataSize = sizeof(AppSpawnConnection);
404     info.disConnectComplete = OnDisConnect;
405     info.sendMessageComplete = SendMessageComplete;
406     info.recvMessage = OnReceiveRequest;
407     info.handleRecvMsg = HandleRecvMessage;
408     LE_STATUS ret = LE_AcceptStreamClient(loopHandle, server, &stream, &info);
409     APPSPAWN_CHECK(ret == 0, return -1, "Failed to alloc stream");
410 
411     AppSpawnConnection *connection = (AppSpawnConnection *)LE_GetUserData(stream);
412     APPSPAWN_CHECK(connection != NULL, return -1, "Failed to alloc stream");
413     struct ucred cred = {-1, -1, -1};
414     socklen_t credSize = sizeof(struct ucred);
415     if ((getsockopt(LE_GetSocketFd(stream), SOL_SOCKET, SO_PEERCRED, &cred, &credSize) < 0) ||
416         !OnConnectionUserCheck(cred.uid)) {
417         APPSPAWN_LOGE("Invalid uid %{public}d from client", cred.uid);
418         LE_CloseStreamTask(LE_GetDefaultLoop(), stream);
419         return -1;
420     }
421     SetFdCtrl(LE_GetSocketFd(stream), FD_CLOEXEC);
422 
423     connection->connectionId = ++connectionId;
424     connection->stream = stream;
425     connection->receiverCtx.fdCount = 0;
426     connection->receiverCtx.incompleteMsg = NULL;
427     connection->receiverCtx.timer = NULL;
428     connection->receiverCtx.msgRecvLen = 0;
429     connection->receiverCtx.nextMsgId = 1;
430     APPSPAWN_LOGI("OnConnection connectionId: %{public}u fd %{public}d ",
431         connection->connectionId, LE_GetSocketFd(stream));
432     return 0;
433 }
434 
MsgDevicedebugCheck(TaskHandle stream,AppSpawnMsgNode * message)435 APPSPAWN_STATIC bool MsgDevicedebugCheck(TaskHandle stream, AppSpawnMsgNode *message)
436 {
437     struct ucred cred = {0, 0, 0};
438     socklen_t credSize = sizeof(cred);
439     if (getsockopt(LE_GetSocketFd(stream), SOL_SOCKET, SO_PEERCRED, &cred, &credSize) < 0) {
440         return false;
441     }
442 
443     if (cred.uid != DecodeUid("shell")) {
444         return true;
445     }
446 
447     AppSpawnMsg *msg = &message->msgHeader;
448     if (msg->msgType != MSG_DEVICE_DEBUG) {
449         APPSPAWN_LOGE("appspawn devicedebug msg type is not devicedebug [%{public}d]", msg->msgType);
450         return false;
451     }
452 
453     return true;
454 }
455 
OnReceiveRequest(const TaskHandle taskHandle,const uint8_t * buffer,uint32_t buffLen)456 static void OnReceiveRequest(const TaskHandle taskHandle, const uint8_t *buffer, uint32_t buffLen)
457 {
458     AppSpawnConnection *connection = (AppSpawnConnection *)LE_GetUserData(taskHandle);
459     APPSPAWN_CHECK(connection != NULL, LE_CloseTask(LE_GetDefaultLoop(), taskHandle);
460         return, "Failed to get client form socket");
461     APPSPAWN_CHECK(buffLen < MAX_MSG_TOTAL_LENGTH, LE_CloseTask(LE_GetDefaultLoop(), taskHandle);
462         return, "Message too long %{public}u", buffLen);
463 
464     uint32_t reminder = 0;
465     uint32_t currLen = 0;
466     AppSpawnMsgNode *message = connection->receiverCtx.incompleteMsg; // incomplete msg
467     connection->receiverCtx.incompleteMsg = NULL;
468     int ret = 0;
469     do {
470         APPSPAWN_LOGI("OnReceiveRequest connectionId: %{public}u start: 0x%{public}x buffLen %{public}d",
471             connection->connectionId, *(uint32_t *)(buffer + currLen), buffLen - currLen);
472 
473         ret = GetAppSpawnMsgFromBuffer(buffer + currLen, buffLen - currLen,
474             &message, &connection->receiverCtx.msgRecvLen, &reminder);
475         APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
476 
477         if (connection->receiverCtx.msgRecvLen != message->msgHeader.msgLen) {  // recv complete msg
478             connection->receiverCtx.incompleteMsg = message;
479             message = NULL;
480             break;
481         }
482         connection->receiverCtx.msgRecvLen = 0;
483         if (connection->receiverCtx.timer) {
484             LE_StopTimer(LE_GetDefaultLoop(), connection->receiverCtx.timer);
485             connection->receiverCtx.timer = NULL;
486         }
487 
488         APPSPAWN_CHECK_ONLY_EXPER(MsgDevicedebugCheck(connection->stream, message),
489             LE_CloseTask(LE_GetDefaultLoop(), taskHandle); return);
490 
491         // decode msg
492         ret = DecodeAppSpawnMsg(message);
493         APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
494         StartAppspawnTrace("ProcessRecvMsg");
495         (void)ProcessRecvMsg(connection, message);
496         FinishAppspawnTrace();
497         message = NULL;
498         currLen += buffLen - reminder;
499     } while (reminder > 0);
500 
501     if (message) {
502         DeleteAppSpawnMsg(&message);
503     }
504     if (ret != 0) {
505         LE_CloseTask(LE_GetDefaultLoop(), taskHandle);
506         return;
507     }
508     if (connection->receiverCtx.incompleteMsg != NULL) { // Start the detection timer
509         ret = StartTimerForCheckMsg(connection);
510         APPSPAWN_CHECK(ret == 0, LE_CloseStreamTask(LE_GetDefaultLoop(), taskHandle);
511             return, "Failed to create time for connection");
512     }
513 }
514 
GetMapMem(uint32_t clientId,const char * processName,uint32_t size,bool readOnly,bool isNweb)515 static char *GetMapMem(uint32_t clientId, const char *processName, uint32_t size, bool readOnly, bool isNweb)
516 {
517     char path[PATH_MAX] = {};
518     int len = sprintf_s(path, sizeof(path), APPSPAWN_MSG_DIR "%s/%s_%u",
519         isNweb ? "nwebspawn" : "appspawn", processName, clientId);
520     APPSPAWN_CHECK(len > 0, return NULL, "Failed to format path %{public}s", processName);
521     APPSPAWN_LOGV("GetMapMem for child %{public}s memSize %{public}u", path, size);
522     int prot = PROT_READ;
523     int mode = O_RDONLY;
524     if (!readOnly) {
525         mode = O_CREAT | O_RDWR | O_TRUNC;
526         prot = PROT_READ | PROT_WRITE;
527     }
528     int fd = open(path, mode, S_IRWXU);
529     APPSPAWN_CHECK(fd >= 0, return NULL, "Failed to open errno %{public}d path %{public}s", errno, path);
530     if (!readOnly) {
531         ftruncate(fd, size);
532     }
533     void *areaAddr = (void *)mmap(NULL, size, prot, MAP_SHARED, fd, 0);
534     close(fd);
535     APPSPAWN_CHECK(areaAddr != MAP_FAILED && areaAddr != NULL,
536         return NULL, "Failed to map memory error %{public}d fileName %{public}s ", errno, path);
537     return (char *)areaAddr;
538 }
539 
WriteMsgToChild(AppSpawningCtx * property,bool isNweb)540 APPSPAWN_STATIC int WriteMsgToChild(AppSpawningCtx *property, bool isNweb)
541 {
542     APPSPAWN_CHECK(property != NULL && property->message != NULL, return APPSPAWN_MSG_INVALID,
543         "Failed to WriteMsgToChild property invalid");
544     const uint32_t memSize = (property->message->msgHeader.msgLen / 4096 + 1) * 4096; // 4096 4K
545     char *buffer = GetMapMem(property->client.id, GetProcessName(property), memSize, false, isNweb);
546     APPSPAWN_CHECK(buffer != NULL, return APPSPAWN_SYSTEM_ERROR,
547         "Failed to map memory error %{public}d fileName %{public}s ", errno, GetProcessName(property));
548     // copy msg header
549     int ret = memcpy_s(buffer, memSize, &property->message->msgHeader, sizeof(AppSpawnMsg));
550     if (ret == 0) {
551         ret = memcpy_s((char *)buffer + sizeof(AppSpawnMsg), memSize - sizeof(AppSpawnMsg),
552             property->message->buffer, property->message->msgHeader.msgLen - sizeof(AppSpawnMsg));
553     }
554     if (ret != 0) {
555         APPSPAWN_LOGE("Failed to copy msg fileName %{public}s ", GetProcessName(property));
556         munmap((char *)buffer, memSize);
557         return APPSPAWN_SYSTEM_ERROR;
558     }
559     property->forkCtx.msgSize = memSize;
560     property->forkCtx.childMsg = buffer;
561     APPSPAWN_LOGV("Write msg to child: %{public}u success", property->client.id);
562     return 0;
563 }
564 
InitForkContext(AppSpawningCtx * property)565 static int InitForkContext(AppSpawningCtx *property)
566 {
567     if (pipe(property->forkCtx.fd) == -1) {
568         APPSPAWN_LOGE("create pipe fail, errno: %{public}d", errno);
569         return errno;
570     }
571     int option = fcntl(property->forkCtx.fd[0], F_GETFD);
572     if (option > 0) {
573         (void)fcntl(property->forkCtx.fd[0], F_SETFD, (unsigned int)option | O_NONBLOCK);
574     }
575     return 0;
576 }
577 
ClosePidfdWatcher(const TaskHandle taskHandle)578 static void ClosePidfdWatcher(const TaskHandle taskHandle)
579 {
580     int fd = LE_GetSocketFd(taskHandle);
581     if (fd >= 0) {
582         close(fd);
583     }
584     void *p = LE_GetUserData(taskHandle);
585     if (p != NULL) {
586         free(*(void **)p);
587     }
588 }
589 
ProcessChildProcessFd(const WatcherHandle taskHandle,int fd,uint32_t * events,const void * context)590 static void ProcessChildProcessFd(const WatcherHandle taskHandle, int fd, uint32_t *events, const void *context)
591 {
592     APPSPAWN_CHECK_ONLY_EXPER(context != NULL, return);
593     pid_t pid = *(pid_t *)context;
594     APPSPAWN_LOGI("Clear process group with pid %{public}d, pidFd %{public}d", pid, fd);
595     AppSpawnedProcess *appInfo = GetSpawnedProcess(pid);
596     if (appInfo == NULL) {
597         APPSPAWN_LOGW("Cannot get app info by bundle name: %{public}d", pid);
598         return;
599     }
600     ProcessMgrHookExecute(STAGE_SERVER_APP_DIED, GetAppSpawnContent(), appInfo);
601     LE_CloseTask(LE_GetDefaultLoop(), taskHandle);
602 }
603 
OpenPidFd(pid_t pid,unsigned int flags)604 static int OpenPidFd(pid_t pid, unsigned int flags)
605 {
606     return syscall(SYS_pidfd_open, pid, flags);
607 }
608 
WatchChildProcessFd(AppSpawningCtx * property)609 static void WatchChildProcessFd(AppSpawningCtx *property)
610 {
611     if (property->pid <= 0) {
612         APPSPAWN_LOGW("Invalid child process pid, skip watch");
613         return;
614     }
615     if (IsNWebSpawnMode((AppSpawnMgr *)GetAppSpawnContent())) {
616         APPSPAWN_LOGV("Nwebspawn don't need add pidfd");
617         return;
618     }
619     AppSpawnedProcess *appInfo = GetSpawnedProcess(property->pid);
620     if (appInfo == NULL) {
621         APPSPAWN_LOGW("Cannot get app info of pid %{public}d", property->pid);
622         return;
623     }
624     int fd = OpenPidFd(property->pid, PIDFD_NONBLOCK); // PIDFD_NONBLOCK  since Linux kernel 5.10
625     if (fd < 0) {
626         APPSPAWN_LOGW("Failed to open pid fd for app: %{public}s, err = %{public}d",
627             GetBundleName(property), errno);
628         return;
629     }
630     APPSPAWN_LOGI("watch app process pid %{public}d, pidFd %{public}d", property->pid, fd);
631     LE_WatchInfo watchInfo = {};
632     watchInfo.fd = fd;
633     watchInfo.flags = WATCHER_ONCE;
634     watchInfo.events = EVENT_READ;
635     watchInfo.close = ClosePidfdWatcher;
636     watchInfo.processEvent = ProcessChildProcessFd;
637 
638     pid_t *appPid = (pid_t *)malloc(sizeof(pid_t));
639     APPSPAWN_CHECK_ONLY_EXPER(appPid != NULL, return);
640     *appPid = property->pid;
641     LE_STATUS status = LE_StartWatcher(LE_GetDefaultLoop(), &property->forkCtx.pidFdWatcherHandle, &watchInfo, appPid);
642     if (status != LE_SUCCESS) {
643 #ifndef APPSPAWN_TEST
644         close(fd);
645 #endif
646         APPSPAWN_LOGW("Failed to watch child pid fd, pid is %{public}d", property->pid);
647     }
648 }
649 
IsChildColdRun(AppSpawningCtx * property)650 static int IsChildColdRun(AppSpawningCtx *property)
651 {
652     return CheckAppMsgFlagsSet(property, APP_FLAGS_UBSAN_ENABLED)
653         || CheckAppMsgFlagsSet(property, APP_FLAGS_ASANENABLED)
654         || CheckAppMsgFlagsSet(property, APP_FLAGS_TSAN_ENABLED)
655         || CheckAppMsgFlagsSet(property, APP_FLAGS_HWASAN_ENABLED)
656         || (property->client.flags & APP_COLD_START);
657 }
658 
AddChildWatcher(AppSpawningCtx * property)659 static int AddChildWatcher(AppSpawningCtx *property)
660 {
661     uint32_t defTimeout = IsChildColdRun(property) ? COLD_CHILD_RESPONSE_TIMEOUT : WAIT_CHILD_RESPONSE_TIMEOUT;
662     uint32_t timeout = GetSpawnTimeout(defTimeout);
663 
664     LE_WatchInfo watchInfo = {};
665     watchInfo.fd = property->forkCtx.fd[0];
666     watchInfo.flags = WATCHER_ONCE;
667     watchInfo.events = EVENT_READ;
668     watchInfo.processEvent = ProcessChildResponse;
669     LE_STATUS status = LE_StartWatcher(LE_GetDefaultLoop(), &property->forkCtx.watcherHandle, &watchInfo, property);
670     APPSPAWN_LOGI("AddChildWatcher with timeout %{public}u fd %{public}d", timeout, watchInfo.fd);
671     APPSPAWN_CHECK(status == LE_SUCCESS,
672         return APPSPAWN_SYSTEM_ERROR, "Failed to watch child %{public}d", property->pid);
673     status = LE_CreateTimer(LE_GetDefaultLoop(), &property->forkCtx.timer, WaitChildTimeout, property);
674     if (status == LE_SUCCESS) {
675         status = LE_StartTimer(LE_GetDefaultLoop(), property->forkCtx.timer, timeout * 1000, 0); // 1000 1s
676     }
677     if (status != LE_SUCCESS) {
678         if (property->forkCtx.timer != NULL) {
679             LE_StopTimer(LE_GetDefaultLoop(), property->forkCtx.timer);
680         }
681         property->forkCtx.timer = NULL;
682         LE_RemoveWatcher(LE_GetDefaultLoop(), property->forkCtx.watcherHandle);
683         property->forkCtx.watcherHandle = NULL;
684         APPSPAWN_LOGE("Failed to watch child %{public}d", property->pid);
685         return APPSPAWN_SYSTEM_ERROR;
686     }
687     return 0;
688 }
689 
IsSupportRunHnp()690 static bool IsSupportRunHnp()
691 {
692     char buffer[PARAM_BUFFER_SIZE] = {0};
693     int ret = GetParameter("const.startup.hnp.execute.enable", "false", buffer, PARAM_BUFFER_SIZE);
694     if (ret <= 0) {
695         APPSPAWN_LOGE("Get hnp execute enable param unsuccess! ret =%{public}d", ret);
696         return false;
697     }
698 
699     if (strcmp(buffer, "true") == 0) {
700         return true;
701     }
702 
703     return false;
704 }
705 
ClearMMAP(int clientId,uint32_t memSize)706 static void ClearMMAP(int clientId, uint32_t memSize)
707 {
708     char path[PATH_MAX] = {0};
709     int ret = snprintf_s(path, sizeof(path), sizeof(path) - 1, APPSPAWN_MSG_DIR "appspawn/prefork_%d", clientId);
710     APPSPAWN_CHECK_ONLY_LOG(ret > 0, "snprintf failed with %{public}d %{public}d", ret, errno);
711     if (ret > 0 && access(path, F_OK) == 0) {
712         ret =  unlink(path);
713         APPSPAWN_CHECK_ONLY_LOG(ret == 0, "prefork unlink result %{public}d %{public}d", ret, errno);
714     }
715 
716     AppSpawnContent *content = GetAppSpawnContent();
717     if (content != NULL && content->propertyBuffer != NULL) {
718         ret = munmap(content->propertyBuffer, memSize);
719         APPSPAWN_CHECK_ONLY_LOG(ret == 0, "munmap failed %{public}d %{public}d", ret, errno);
720         content->propertyBuffer = NULL;
721     }
722 }
723 
WritePreforkMsg(AppSpawningCtx * property,uint32_t memSize)724 static int WritePreforkMsg(AppSpawningCtx *property, uint32_t memSize)
725 {
726     AppSpawnContent *content = GetAppSpawnContent();
727     if (content == NULL || content->propertyBuffer == NULL) {
728         APPSPAWN_LOGE("buffer is null can not write propery");
729         return  -1;
730     }
731 
732     int ret = memcpy_s(content->propertyBuffer, memSize, &property->message->msgHeader, sizeof(AppSpawnMsg));
733     if (ret != 0) {
734         APPSPAWN_LOGE("memcpys_s msgHeader failed");
735         ClearMMAP(property->client.id, memSize);
736         return ret;
737     }
738 
739     ret = memcpy_s((char *)content->propertyBuffer + sizeof(AppSpawnMsg), memSize - sizeof(AppSpawnMsg),
740         property->message->buffer, property->message->msgHeader.msgLen - sizeof(AppSpawnMsg));
741     if (ret != 0) {
742         APPSPAWN_LOGE("memcpys_s AppSpawnMsg failed");
743         ClearMMAP(property->client.id, memSize);
744         return ret;
745     }
746     ret = munmap((char *)content->propertyBuffer, memSize);
747     APPSPAWN_CHECK_ONLY_LOG(ret == 0, "munmap failed %{public}d,%{public}d", ret, errno);
748     content->propertyBuffer = NULL;
749     return ret;
750 }
751 
GetAppSpawnMsg(AppSpawningCtx * property,uint32_t memSize)752 static int GetAppSpawnMsg(AppSpawningCtx *property, uint32_t memSize)
753 {
754     uint8_t *buffer = (uint8_t *)GetMapMem(property->client.id, "prefork", memSize, true, false);
755     if (buffer == NULL) {
756         APPSPAWN_LOGE("prefork buffer is null can not write propery");
757         return  -1;
758     }
759     uint32_t msgRecvLen = 0;
760     uint32_t remainLen = 0;
761     property->forkCtx.childMsg = (char *)buffer;
762     property->forkCtx.msgSize = memSize;
763     AppSpawnMsgNode *message = NULL;
764     int ret = GetAppSpawnMsgFromBuffer(buffer, ((AppSpawnMsg *)buffer)->msgLen, &message, &msgRecvLen, &remainLen);
765     // release map
766     APPSPAWN_LOGV("prefork GetAppSpawnMsg ret:%{public}d", ret);
767     if (ret == 0 && DecodeAppSpawnMsg(message) == 0 && CheckAppSpawnMsg(message) == 0) {
768         property->message = message;
769         message = NULL;
770         return 0;
771     }
772     return -1;
773 }
774 
SetPreforkProcessName(AppSpawnContent * content)775 static int SetPreforkProcessName(AppSpawnContent *content)
776 {
777     int ret = prctl(PR_SET_NAME, PREFORK_PROCESS);
778     if (ret == -1) {
779         return errno;
780     }
781 
782     ret = memset_s(content->longProcName,
783         (size_t)content->longProcNameLen, 0, (size_t)content->longProcNameLen);
784     if (ret != EOK) {
785         return EINVAL;
786     }
787 
788     ret = strncpy_s(content->longProcName, content->longProcNameLen,
789         PREFORK_PROCESS, strlen(PREFORK_PROCESS));
790     if (ret != EOK) {
791         return EINVAL;
792     }
793 
794     return 0;
795 }
796 
ProcessPreFork(AppSpawnContent * content,AppSpawningCtx * property)797 static void ProcessPreFork(AppSpawnContent *content, AppSpawningCtx *property)
798 {
799     APPSPAWN_CHECK(pipe(content->preforkFd) == 0, return, "prefork with prefork pipe failed %{public}d", errno);
800     APPSPAWN_CHECK_ONLY_EXPER(content->parentToChildFd[0] <= 0, close(content->parentToChildFd[0]);
801         content->parentToChildFd[0] = -1);
802     APPSPAWN_CHECK_ONLY_EXPER(content->parentToChildFd[1] <= 0, close(content->parentToChildFd[1]);
803         content->parentToChildFd[1] = -1);
804     APPSPAWN_CHECK(pipe(content->parentToChildFd) == 0, return, "prefork with prefork pipe failed %{public}d", errno);
805     enum fdsan_error_level errorLevel = fdsan_get_error_level();
806     content->reservedPid = fork();
807     APPSPAWN_LOGV("prefork fork finish %{public}d,%{public}d,%{public}d,%{public}d,%{public}d",
808         content->reservedPid, content->preforkFd[0], content->preforkFd[1], content->parentToChildFd[0],
809         content->parentToChildFd[1]);
810     if (content->reservedPid == 0) {
811         (void)close(property->forkCtx.fd[0]);
812         (void)close(property->forkCtx.fd[1]);
813         int isRet = SetPreforkProcessName(content);
814         APPSPAWN_LOGV("prefork process start wait read msg with set processname %{public}d", isRet);
815         AppSpawnPreforkMsg preforkMsg = {0};
816         int infoSize = read(content->parentToChildFd[0], &preforkMsg, sizeof(AppSpawnPreforkMsg));
817         if (infoSize != sizeof(AppSpawnPreforkMsg) || preforkMsg.msgLen > MAX_MSG_TOTAL_LENGTH ||
818             preforkMsg.msgLen < sizeof(AppSpawnMsg)) {
819             APPSPAWN_LOGE("prefork process read msg failed %{public}d,%{public}d", infoSize, errno);
820             ProcessExit(0);
821             return;
822         }
823 
824         property->client.id = preforkMsg.id;
825         property->client.flags = preforkMsg.flags;
826         property->isPrefork = true;
827         property->forkCtx.fd[0] = content->preforkFd[0];
828         property->forkCtx.fd[1] = content->preforkFd[1];
829         property->state = APP_STATE_SPAWNING;
830         const uint32_t memSize = (preforkMsg.msgLen / MAX_MSG_BLOCK_LEN + 1) * MAX_MSG_BLOCK_LEN;
831         if (GetAppSpawnMsg(property, memSize) == -1) {
832             APPSPAWN_LOGE("prefork child read GetAppSpawnMsg failed");
833             ClearMMAP(property->client.id, memSize);
834             content->notifyResToParent(content, &property->client, APPSPAWN_MSG_INVALID);
835             ProcessExit(0);
836             return;
837         }
838         ClearMMAP(property->client.id, memSize);
839         // Inherit the error level of the original process
840         (void)fdsan_set_error_level(errorLevel);
841         ProcessExit(AppSpawnChild(content, &property->client));
842     } else if (content->reservedPid < 0) {
843         APPSPAWN_LOGE("prefork fork child process failed %{public}d", content->reservedPid);
844     }
845 }
846 
NormalSpawnChild(AppSpawnContent * content,AppSpawnClient * client,pid_t * childPid)847 static int NormalSpawnChild(AppSpawnContent *content, AppSpawnClient *client, pid_t *childPid)
848 {
849     APPSPAWN_CHECK(client != NULL, return APPSPAWN_ARG_INVALID, "client is null");
850     int ret = InitForkContext((AppSpawningCtx *)client);
851     APPSPAWN_CHECK(ret == 0, return ret, "init fork context failed");
852     return AppSpawnProcessMsg(content, client, childPid);
853 }
854 
AppSpawnProcessMsgForPrefork(AppSpawnContent * content,AppSpawnClient * client,pid_t * childPid)855 static int AppSpawnProcessMsgForPrefork(AppSpawnContent *content, AppSpawnClient *client, pid_t *childPid)
856 {
857     int ret = 0;
858     AppSpawningCtx *property = (AppSpawningCtx *)client;
859     if (content->reservedPid <= 0) {
860         ret = NormalSpawnChild(content, client, childPid);
861     } else {
862         const uint32_t memSize = (property->message->msgHeader.msgLen / MAX_MSG_BLOCK_LEN + 1) *
863             MAX_MSG_BLOCK_LEN;
864         content->propertyBuffer = GetMapMem(property->client.id, "prefork", memSize, false, false);
865         if (content->propertyBuffer == NULL) {
866             ClearMMAP(property->client.id, memSize);
867             return NormalSpawnChild(content, client, childPid);
868         }
869         ret = WritePreforkMsg(property, memSize);
870         if (ret != 0) {
871             ClearMMAP(property->client.id, memSize);
872             return NormalSpawnChild(content, client, childPid);
873         }
874         *childPid = content->reservedPid;
875         property->forkCtx.fd[0] = content->preforkFd[0];
876         property->forkCtx.fd[1] = content->preforkFd[1];
877         int option = fcntl(property->forkCtx.fd[0], F_GETFD);
878         if (option > 0) {
879             ret = fcntl(property->forkCtx.fd[0], F_SETFD, (unsigned int)option | O_NONBLOCK);
880             APPSPAWN_CHECK_ONLY_LOG(ret == 0, "fcntl failed %{public}d,%{public}d", ret, errno);
881         }
882         AppSpawnPreforkMsg *preforkMsg = (AppSpawnPreforkMsg *)calloc(1, sizeof(AppSpawnPreforkMsg));
883         if (preforkMsg == NULL) {
884             APPSPAWN_LOGE("calloc failed");
885             ClearMMAP(property->client.id, memSize);
886             return NormalSpawnChild(content, client, childPid);
887         }
888 
889         preforkMsg->id = client->id;
890         preforkMsg->flags = client->flags;
891         preforkMsg->msgLen = property->message->msgHeader.msgLen;
892         ssize_t writesize = write(content->parentToChildFd[1], preforkMsg, sizeof(AppSpawnPreforkMsg)) ;
893         APPSPAWN_CHECK(writesize == sizeof(AppSpawnPreforkMsg), kill(*childPid, SIGKILL);
894             *childPid = 0;
895             ret = -1,
896             "write msg to child failed %{public}d", errno);
897         free(preforkMsg);
898     }
899     ProcessPreFork(content, property);
900     return ret;
901 }
902 
IsSupportPrefork(AppSpawnContent * content,AppSpawnClient * client)903 static bool IsSupportPrefork(AppSpawnContent *content, AppSpawnClient *client)
904 {
905 #ifdef APPSPAWN_SUPPORT_PREFORK
906     if (client == NULL || content == NULL) {
907         return false;
908     }
909     if (!content->enablePerfork) {
910         APPSPAWN_LOGV("g_enablePrefork %{public}d", content->enablePerfork);
911         return false;
912     }
913     AppSpawningCtx *property = (AppSpawningCtx *)client;
914 
915     if (content->mode == MODE_FOR_APP_SPAWN && !IsChildColdRun(property)
916         && !CheckAppMsgFlagsSet(property, APP_FLAGS_CHILDPROCESS)) {
917         return true;
918     }
919 #endif
920     return false;
921 }
922 
IsBootFinished(void)923 static bool IsBootFinished(void)
924 {
925     char buffer[32] = {0};  // 32 max
926     int ret = GetParameter("bootevent.boot.completed", "false", buffer, sizeof(buffer));
927     bool isBootCompleted = (ret > 0 && strcmp(buffer, "true") == 0);
928     return isBootCompleted;
929 }
930 
931 
RunAppSpawnProcessMsg(AppSpawnContent * content,AppSpawnClient * client,pid_t * childPid)932 static int RunAppSpawnProcessMsg(AppSpawnContent *content, AppSpawnClient *client, pid_t *childPid)
933 {
934     int ret = 0;
935 
936     if (IsBootFinished() && IsSupportPrefork(content, client)) {
937         ret = AppSpawnProcessMsgForPrefork(content, client, childPid);
938     } else {
939         ret = NormalSpawnChild(content, client, childPid);
940     }
941     return ret;
942 }
943 
ProcessSpawnReqMsg(AppSpawnConnection * connection,AppSpawnMsgNode * message)944 static void ProcessSpawnReqMsg(AppSpawnConnection *connection, AppSpawnMsgNode *message)
945 {
946     int ret = CheckAppSpawnMsg(message);
947     if (ret != 0) {
948         SendResponse(connection, &message->msgHeader, ret, 0);
949         DeleteAppSpawnMsg(&message);
950         return;
951     }
952 
953     if (IsDeveloperModeOpen()) {
954         if (IsSupportRunHnp()) {
955             SetAppSpawnMsgFlag(message, TLV_MSG_FLAGS, APP_FLAGS_DEVELOPER_MODE);
956         } else {
957             APPSPAWN_LOGV("Not support execute hnp file!");
958         }
959     }
960 
961     AppSpawningCtx *property = CreateAppSpawningCtx();
962     if (property == NULL) {
963         SendResponse(connection, &message->msgHeader, APPSPAWN_SYSTEM_ERROR, 0);
964         DeleteAppSpawnMsg(&message);
965         return;
966     }
967 
968     property->state = APP_STATE_SPAWNING;
969     property->message = message;
970     message->connection = connection;
971     // mount el2 dir
972     // getWrapBundleNameValue
973     AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, GetAppSpawnContent(), &property->client);
974     DumpAppSpawnMsg(property->message);
975 
976     clock_gettime(CLOCK_MONOTONIC, &property->spawnStart);
977     ret = RunAppSpawnProcessMsg(GetAppSpawnContent(), &property->client, &property->pid);
978     AppSpawnHookExecute(STAGE_PARENT_POST_FORK, 0, GetAppSpawnContent(), &property->client);
979     if (ret != 0) { // wait child process result
980         SendResponse(connection, &message->msgHeader, ret, 0);
981         DeleteAppSpawningCtx(property);
982         return;
983     }
984     if (AddChildWatcher(property) != 0) { // wait child process result
985         kill(property->pid, SIGKILL);
986         SendResponse(connection, &message->msgHeader, ret, 0);
987         DeleteAppSpawningCtx(property);
988         return;
989     }
990 }
991 
992 static uint32_t g_lastDiedAppId = 0;
993 static uint32_t g_crashTimes = 0;
994 #define MAX_CRASH_TIME 5
WaitChildDied(pid_t pid)995 static void WaitChildDied(pid_t pid)
996 {
997     AppSpawningCtx *property = GetAppSpawningCtxByPid(pid);
998     if (property != NULL && property->message != NULL && property->state == APP_STATE_SPAWNING) {
999         const char *processName = GetProcessName(property);
1000         APPSPAWN_LOGI("Child process %{public}s fail \'child crash \'pid %{public}d appId: %{public}d",
1001             processName, property->pid, property->client.id);
1002 #ifdef APPSPAWN_HISYSEVENT
1003         ReportSpawnChildProcessFail(processName, ERR_APPSPAWN_CHILD_CRASH, APPSPAWN_CHILD_CRASH);
1004 #endif
1005         if (property->client.id == g_lastDiedAppId + 1) {
1006             g_crashTimes++;
1007         } else {
1008             g_crashTimes = 1;
1009         }
1010         g_lastDiedAppId = property->client.id;
1011 
1012         SendResponse(property->message->connection, &property->message->msgHeader, APPSPAWN_CHILD_CRASH, 0);
1013         DeleteAppSpawningCtx(property);
1014 
1015         if (g_crashTimes >= MAX_CRASH_TIME) {
1016             APPSPAWN_LOGW("Continuous failures in spawning the app, restart appspawn");
1017 #ifdef APPSPAWN_HISYSEVENT
1018             ReportKeyEvent(APPSPAWN_MAX_FAILURES_EXCEEDED);
1019 #endif
1020             StopAppSpawn();
1021         }
1022     }
1023 }
1024 
WaitChildTimeout(const TimerHandle taskHandle,void * context)1025 static void WaitChildTimeout(const TimerHandle taskHandle, void *context)
1026 {
1027     AppSpawningCtx *property = (AppSpawningCtx *)context;
1028     APPSPAWN_LOGI("Child process %{public}s fail \'wait child timeout \'pid %{public}d appId: %{public}d",
1029         GetProcessName(property), property->pid, property->client.id);
1030     if (property->pid > 0) {
1031 #if (!defined(CJAPP_SPAWN) && !defined(NATIVE_SPAWN))
1032         DumpSpawnStack(property->pid);
1033 #endif
1034         kill(property->pid, SIGKILL);
1035     }
1036 #ifdef APPSPAWN_HISYSEVENT
1037     ReportSpawnChildProcessFail(GetProcessName(property), ERR_APPSPAWN_SPAWN_TIMEOUT, APPSPAWN_SPAWN_TIMEOUT);
1038 #endif
1039     SendResponse(property->message->connection, &property->message->msgHeader, APPSPAWN_SPAWN_TIMEOUT, 0);
1040     DeleteAppSpawningCtx(property);
1041 }
1042 
ProcessChildFdCheck(int fd,AppSpawningCtx * property)1043 static int ProcessChildFdCheck(int fd, AppSpawningCtx *property)
1044 {
1045     int result = 0;
1046     (void)read(fd, &result, sizeof(result));
1047     APPSPAWN_LOGI("Child process %{public}s success pid %{public}d appId: %{public}d result: %{public}d",
1048         GetProcessName(property), property->pid, property->client.id, result);
1049     APPSPAWN_CHECK(property->message != NULL, return -1, "Invalid message in ctx %{public}d", property->client.id);
1050 
1051     if (result != 0) {
1052 #ifdef APPSPAWN_HISYSEVENT
1053         ReportSpawnChildProcessFail(GetProcessName(property), ERR_APPSPAWN_SPAWN_FAIL, result);
1054 #endif
1055         SendResponse(property->message->connection, &property->message->msgHeader, result, property->pid);
1056         DeleteAppSpawningCtx(property);
1057         return -1;
1058     }
1059 
1060     return 0;
1061 }
1062 
ProcessChildResponse(const WatcherHandle taskHandle,int fd,uint32_t * events,const void * context)1063 static void ProcessChildResponse(const WatcherHandle taskHandle, int fd, uint32_t *events, const void *context)
1064 {
1065     AppSpawningCtx *property = (AppSpawningCtx *)context;
1066     property->forkCtx.watcherHandle = NULL;  // delete watcher
1067     LE_RemoveWatcher(LE_GetDefaultLoop(), (WatcherHandle)taskHandle);
1068 
1069     if (ProcessChildFdCheck(fd, property) != 0) {
1070         return;
1071     }
1072 
1073     // success
1074     bool isDebuggable = CheckAppMsgFlagsSet(property, APP_FLAGS_DEBUGGABLE);
1075     AppSpawnedProcess *appInfo = AddSpawnedProcess(property->pid, GetBundleName(property), isDebuggable);
1076     if (appInfo) {
1077         AppSpawnMsgDacInfo *dacInfo = GetAppProperty(property, TLV_DAC_INFO);
1078         appInfo->uid = dacInfo != NULL ? dacInfo->uid : 0;
1079         appInfo->spawnStart.tv_sec = property->spawnStart.tv_sec;
1080         appInfo->spawnStart.tv_nsec = property->spawnStart.tv_nsec;
1081 #ifdef DEBUG_BEGETCTL_BOOT
1082         if (IsDeveloperModeOpen()) {
1083             appInfo->message = property->message;
1084         }
1085 #endif
1086         clock_gettime(CLOCK_MONOTONIC, &appInfo->spawnEnd);
1087 
1088 #ifdef APPSPAWN_HISYSEVENT
1089         //add process spawn duration into hisysevent,(ms)
1090         uint32_t spawnProcessDuration = (uint32_t)((appInfo->spawnEnd.tv_sec - appInfo->spawnStart.tv_sec) *
1091             (APPSPAWN_USEC_TO_NSEC)) +(uint32_t)((appInfo->spawnEnd.tv_nsec - appInfo->spawnStart.tv_nsec) /
1092             (APPSPAWN_MSEC_TO_NSEC));
1093         AppSpawnMgr *appspawnMgr = GetAppSpawnMgr();
1094         if (appspawnMgr != NULL) {
1095             AddStatisticEventInfo(appspawnMgr->hisyseventInfo, spawnProcessDuration, IsBootFinished());
1096         }
1097 #ifndef ASAN_DETECTOR
1098         uint64_t diff = DiffTime(&appInfo->spawnStart, &appInfo->spawnEnd);
1099         APPSPAWN_CHECK_ONLY_EXPER(diff < (IsChildColdRun(property) ? SPAWN_COLDRUN_DURATION : SPAWN_DURATION),
1100             ReportAbnormalDuration("SPAWNCHILD", diff));
1101 #endif
1102 #endif
1103     }
1104 
1105     WatchChildProcessFd(property);
1106     ProcessMgrHookExecute(STAGE_SERVER_APP_ADD, GetAppSpawnContent(), appInfo);
1107     // response
1108     AppSpawnHookExecute(STAGE_PARENT_PRE_RELY, 0, GetAppSpawnContent(), &property->client);
1109     SendResponse(property->message->connection, &property->message->msgHeader, 0, property->pid);
1110     AppSpawnHookExecute(STAGE_PARENT_POST_RELY, 0, GetAppSpawnContent(), &property->client);
1111 #ifdef DEBUG_BEGETCTL_BOOT
1112     if (IsDeveloperModeOpen()) {
1113         property->message = NULL;
1114     }
1115 #endif
1116     DeleteAppSpawningCtx(property);
1117 }
1118 
NotifyResToParent(AppSpawnContent * content,AppSpawnClient * client,int result)1119 static void NotifyResToParent(AppSpawnContent *content, AppSpawnClient *client, int result)
1120 {
1121     AppSpawningCtx *property = (AppSpawningCtx *)client;
1122     int fd = property->forkCtx.fd[1];
1123     if (fd >= 0) {
1124         (void)write(fd, &result, sizeof(result));
1125         (void)close(fd);
1126         property->forkCtx.fd[1] = -1;
1127     }
1128     APPSPAWN_LOGV("NotifyResToParent client id: %{public}u result: 0x%{public}x", client->id, result);
1129 }
1130 
CreateAppSpawnServer(TaskHandle * server,const char * socketName)1131 static int CreateAppSpawnServer(TaskHandle *server, const char *socketName)
1132 {
1133     char path[128] = {0};  // 128 max path
1134     int ret = snprintf_s(path, sizeof(path), sizeof(path) - 1, "%s%s", APPSPAWN_SOCKET_DIR, socketName);
1135     APPSPAWN_CHECK(ret >= 0, return -1, "Failed to snprintf_s %{public}d", ret);
1136     int socketId = GetControlSocket(socketName);
1137     APPSPAWN_LOGI("get socket form env %{public}s socketId %{public}d", socketName, socketId);
1138 
1139     LE_StreamServerInfo info = {};
1140     info.baseInfo.flags = TASK_STREAM | TASK_PIPE | TASK_SERVER;
1141     info.socketId = socketId;
1142     info.server = path;
1143     info.baseInfo.close = NULL;
1144     info.incommingConnect = OnConnection;
1145 
1146     MakeDirRec(path, 0711, 0);  // 0711 default mask
1147     ret = LE_CreateStreamServer(LE_GetDefaultLoop(), server, &info);
1148     APPSPAWN_CHECK(ret == 0, return -1, "Failed to create socket for %{public}s errno: %{public}d", path, errno);
1149     SetFdCtrl(LE_GetSocketFd(*server), FD_CLOEXEC);
1150 
1151     APPSPAWN_LOGI("CreateAppSpawnServer path %{public}s fd %{public}d", path, LE_GetSocketFd(*server));
1152     return 0;
1153 }
1154 
AppSpawnDestroyContent(AppSpawnContent * content)1155 void AppSpawnDestroyContent(AppSpawnContent *content)
1156 {
1157     if (content == NULL) {
1158         return;
1159     }
1160     if (content->parentToChildFd[0] > 0) {
1161         close(content->parentToChildFd[0]);
1162     }
1163     if (content->parentToChildFd[1] > 0) {
1164         close(content->parentToChildFd[1]);
1165     }
1166     AppSpawnMgr *appSpawnContent = (AppSpawnMgr *)content;
1167     if (appSpawnContent->sigHandler != NULL && appSpawnContent->servicePid == getpid()) {
1168         LE_CloseSignalTask(LE_GetDefaultLoop(), appSpawnContent->sigHandler);
1169     }
1170 
1171     if (appSpawnContent->server != NULL && appSpawnContent->servicePid == getpid()) { // childProcess can't deal socket
1172         LE_CloseStreamTask(LE_GetDefaultLoop(), appSpawnContent->server);
1173         appSpawnContent->server = NULL;
1174     }
1175     DeleteAppSpawnMgr(appSpawnContent);
1176     LE_StopLoop(LE_GetDefaultLoop());
1177     LE_CloseLoop(LE_GetDefaultLoop());
1178 }
1179 
AppSpawnColdStartApp(struct AppSpawnContent * content,AppSpawnClient * client)1180 APPSPAWN_STATIC int AppSpawnColdStartApp(struct AppSpawnContent *content, AppSpawnClient *client)
1181 {
1182     AppSpawningCtx *property = (AppSpawningCtx *)client;
1183 #ifdef CJAPP_SPAWN
1184     char *path = property->forkCtx.coldRunPath != NULL ? property->forkCtx.coldRunPath : "/system/bin/cjappspawn";
1185 #elif NATIVE_SPAWN
1186     char *path = property->forkCtx.coldRunPath != NULL ? property->forkCtx.coldRunPath : "/system/bin/nativespawn";
1187 #else
1188     char *path = property->forkCtx.coldRunPath != NULL ? property->forkCtx.coldRunPath : "/system/bin/appspawn";
1189 #endif
1190     APPSPAWN_LOGI("ColdStartApp::processName: %{public}s path: %{public}s", GetProcessName(property), path);
1191 
1192     // for cold run, use shared memory to exchange message
1193     APPSPAWN_LOGV("Write msg to child %{public}s", GetProcessName(property));
1194     int ret = WriteMsgToChild(property, IsNWebSpawnMode((AppSpawnMgr *)content));
1195     APPSPAWN_CHECK(ret == 0, return APPSPAWN_SYSTEM_ERROR, "Failed to write msg to child");
1196 
1197     char buffer[4][32] = {0};  // 4 32 buffer for fd
1198     int len = sprintf_s(buffer[0], sizeof(buffer[0]), " %d ", property->forkCtx.fd[1]);
1199     APPSPAWN_CHECK(len > 0, return APPSPAWN_SYSTEM_ERROR, "Invalid to format fd");
1200     len = sprintf_s(buffer[1], sizeof(buffer[1]), " %u ", property->client.flags);
1201     APPSPAWN_CHECK(len > 0, return APPSPAWN_SYSTEM_ERROR, "Invalid to format flags");
1202     len = sprintf_s(buffer[2], sizeof(buffer[2]), " %u ", property->forkCtx.msgSize); // 2 2 index for dest path
1203     APPSPAWN_CHECK(len > 0, return APPSPAWN_SYSTEM_ERROR, "Invalid to format shmId ");
1204     len = sprintf_s(buffer[3], sizeof(buffer[3]), " %u ", property->client.id); // 3 3 index for client id
1205     APPSPAWN_CHECK(len > 0, return APPSPAWN_SYSTEM_ERROR, "Invalid to format shmId ");
1206 #ifndef APPSPAWN_TEST
1207     char *mode = IsNWebSpawnMode((AppSpawnMgr *)content) ? "nweb_cold" : "app_cold";
1208     // 2 2 index for dest path
1209     const char *const formatCmds[] = {
1210         path, "-mode", mode, "-fd", buffer[0], buffer[1], buffer[2],
1211         "-param", GetProcessName(property), buffer[3], NULL
1212     };
1213 
1214     ret = execv(path, (char **)formatCmds);
1215     if (ret != 0) {
1216         APPSPAWN_LOGE("Failed to execv, errno: %{public}d", errno);
1217     }
1218 #endif
1219     APPSPAWN_LOGV("ColdStartApp::processName: %{public}s end", GetProcessName(property));
1220     return 0;
1221 }
1222 
GetAppSpawningCtxFromArg(AppSpawnMgr * content,int argc,char * const argv[])1223 static AppSpawningCtx *GetAppSpawningCtxFromArg(AppSpawnMgr *content, int argc, char *const argv[])
1224 {
1225     AppSpawningCtx *property = CreateAppSpawningCtx();
1226     APPSPAWN_CHECK(property != NULL, return NULL, "Create app spawning ctx fail");
1227     property->forkCtx.fd[1] = atoi(argv[FD_VALUE_INDEX]);
1228     property->client.flags = (uint32_t)atoi(argv[FLAGS_VALUE_INDEX]);
1229     property->client.flags &= ~APP_COLD_START;
1230 
1231     int isNweb = IsNWebSpawnMode(content);
1232     uint32_t size = (uint32_t)atoi(argv[SHM_SIZE_INDEX]);
1233     property->client.id = (uint32_t)atoi(argv[CLIENT_ID_INDEX]);
1234     uint8_t *buffer = (uint8_t *)GetMapMem(property->client.id,
1235         argv[PARAM_VALUE_INDEX], size, true, isNweb);
1236     if (buffer == NULL) {
1237         APPSPAWN_LOGE("Failed to map errno %{public}d %{public}s", property->client.id, argv[PARAM_VALUE_INDEX]);
1238         NotifyResToParent(&content->content, &property->client, APPSPAWN_SYSTEM_ERROR);
1239         DeleteAppSpawningCtx(property);
1240         return NULL;
1241     }
1242 
1243     uint32_t msgRecvLen = 0;
1244     uint32_t remainLen = 0;
1245     AppSpawnMsgNode *message = NULL;
1246     int ret = GetAppSpawnMsgFromBuffer(buffer, ((AppSpawnMsg *)buffer)->msgLen, &message, &msgRecvLen, &remainLen);
1247     // release map
1248     munmap((char *)buffer, size);
1249     //unlink
1250     char path[PATH_MAX] = {0};
1251     int len = sprintf_s(path, sizeof(path), APPSPAWN_MSG_DIR "%s/%s_%u",
1252         isNweb ? "nwebspawn" : "appspawn", argv[PARAM_VALUE_INDEX], property->client.id);
1253     if (len > 0) {
1254         unlink(path);
1255     }
1256 
1257     if (ret == 0 && DecodeAppSpawnMsg(message) == 0 && CheckAppSpawnMsg(message) == 0) {
1258         property->message = message;
1259         message = NULL;
1260         return property;
1261     }
1262     NotifyResToParent(&content->content, &property->client, APPSPAWN_MSG_INVALID);
1263     DeleteAppSpawnMsg(&message);
1264     DeleteAppSpawningCtx(property);
1265     return NULL;
1266 }
1267 
AppSpawnColdRun(AppSpawnContent * content,int argc,char * const argv[])1268 static void AppSpawnColdRun(AppSpawnContent *content, int argc, char *const argv[])
1269 {
1270     APPSPAWN_CHECK(argc >= ARG_NULL, return, "Invalid arg for cold start %{public}d", argc);
1271     AppSpawnMgr *appSpawnContent = (AppSpawnMgr *)content;
1272     APPSPAWN_CHECK(appSpawnContent != NULL, return, "Invalid appspawn content");
1273 
1274     AppSpawningCtx *property = GetAppSpawningCtxFromArg(appSpawnContent, argc, argv);
1275     if (property == NULL) {
1276         APPSPAWN_LOGE("Failed to get property from arg");
1277         return;
1278     }
1279     DumpAppSpawnMsg(property->message);
1280 
1281     int ret = AppSpawnExecuteSpawningHook(content, &property->client);
1282     if (ret == 0) {
1283         ret = AppSpawnExecutePreReplyHook(content, &property->client);
1284         // success
1285         NotifyResToParent(content, &property->client, ret);
1286 
1287         (void)AppSpawnExecutePostReplyHook(content, &property->client);
1288 
1289         ret = APPSPAWN_SYSTEM_ERROR;
1290         if (content->runChildProcessor != NULL) {
1291             ret = content->runChildProcessor(content, &property->client);
1292         }
1293     } else {
1294         NotifyResToParent(content, &property->client, ret);
1295     }
1296 
1297     if (ret != 0) {
1298         AppSpawnEnvClear(content, &property->client);
1299     }
1300     APPSPAWN_LOGI("AppSpawnColdRun exit %{public}d.", getpid());
1301 }
1302 
AppSpawnRun(AppSpawnContent * content,int argc,char * const argv[])1303 static void AppSpawnRun(AppSpawnContent *content, int argc, char *const argv[])
1304 {
1305     APPSPAWN_LOGI("AppSpawnRun");
1306     AppSpawnMgr *appSpawnContent = (AppSpawnMgr *)content;
1307     APPSPAWN_CHECK(appSpawnContent != NULL, return, "Invalid appspawn content");
1308 
1309     LE_STATUS status = LE_CreateSignalTask(LE_GetDefaultLoop(), &appSpawnContent->sigHandler, ProcessSignal);
1310     if (status == 0) {
1311         (void)LE_AddSignal(LE_GetDefaultLoop(), appSpawnContent->sigHandler, SIGCHLD);
1312         (void)LE_AddSignal(LE_GetDefaultLoop(), appSpawnContent->sigHandler, SIGTERM);
1313     }
1314 
1315     if (IsAppSpawnMode(appSpawnContent)) {
1316         struct sched_param param = { 0 };
1317         param.sched_priority = 1;
1318         int ret = sched_setscheduler(0, SCHED_FIFO, &param);
1319         APPSPAWN_CHECK_ONLY_LOG(ret == 0, "UpdateSchedPrio failed ret: %{public}d, %{public}d", ret, errno);
1320     }
1321     LE_RunLoop(LE_GetDefaultLoop());
1322     APPSPAWN_LOGI("AppSpawnRun exit mode: %{public}d ", content->mode);
1323 
1324     (void)ServerStageHookExecute(STAGE_SERVER_EXIT, content); // service exit,plugin can deal task
1325     AppSpawnDestroyContent(content);
1326 }
1327 
AppSpawnClearEnv(AppSpawnMgr * content,AppSpawningCtx * property)1328 APPSPAWN_STATIC int AppSpawnClearEnv(AppSpawnMgr *content, AppSpawningCtx *property)
1329 {
1330     APPSPAWN_CHECK(content != NULL, return 0, "Invalid appspawn content");
1331     DeleteAppSpawningCtx(property);
1332     AppSpawnDestroyContent(&content->content);
1333     APPSPAWN_LOGV("clear %{public}d end", getpid());
1334     return 0;
1335 }
1336 
IsEnablePrefork(void)1337 static int IsEnablePrefork(void)
1338 {
1339     char buffer[32] = {0};
1340     int ret = GetParameter("persist.sys.prefork.enable", "true", buffer, sizeof(buffer));
1341     APPSPAWN_LOGV("IsEnablePrefork result %{public}d, %{public}s", ret, buffer);
1342     return strcmp(buffer, "true") == 0;
1343 }
1344 
AppSpawnCreateContent(const char * socketName,char * longProcName,uint32_t nameLen,int mode)1345 AppSpawnContent *AppSpawnCreateContent(const char *socketName, char *longProcName, uint32_t nameLen, int mode)
1346 {
1347     APPSPAWN_CHECK(socketName != NULL && longProcName != NULL, return NULL, "Invalid name");
1348     APPSPAWN_LOGI("AppSpawnCreateContent %{public}s %{public}u mode %{public}d", socketName, nameLen, mode);
1349 
1350     AppSpawnMgr *appSpawnContent = CreateAppSpawnMgr(mode);
1351     APPSPAWN_CHECK(appSpawnContent != NULL, return NULL, "Failed to alloc memory for appspawn");
1352 #ifdef APPSPAWN_HISYSEVENT
1353     appSpawnContent->hisyseventInfo = InitHisyseventTimer();
1354 #endif
1355     appSpawnContent->content.longProcName = longProcName;
1356     appSpawnContent->content.longProcNameLen = nameLen;
1357     appSpawnContent->content.notifyResToParent = NotifyResToParent;
1358     if (IsColdRunMode(appSpawnContent)) {
1359         appSpawnContent->content.runAppSpawn = AppSpawnColdRun;
1360     } else {
1361         appSpawnContent->content.runAppSpawn = AppSpawnRun;
1362         appSpawnContent->content.coldStartApp = AppSpawnColdStartApp;
1363 
1364         int ret = CreateAppSpawnServer(&appSpawnContent->server, socketName);
1365         APPSPAWN_CHECK(ret == 0, AppSpawnDestroyContent(&appSpawnContent->content);
1366             return NULL, "Failed to create server");
1367     }
1368     appSpawnContent->content.enablePerfork = IsEnablePrefork();
1369     return &appSpawnContent->content;
1370 }
1371 
StartSpawnService(const AppSpawnStartArg * startArg,uint32_t argvSize,int argc,char * const argv[])1372 AppSpawnContent *StartSpawnService(const AppSpawnStartArg *startArg, uint32_t argvSize, int argc, char *const argv[])
1373 {
1374     APPSPAWN_CHECK(startArg != NULL && argv != NULL, return NULL, "Invalid start arg");
1375     pid_t pid = 0;
1376     AppSpawnStartArg *arg = (AppSpawnStartArg *)startArg;
1377     APPSPAWN_LOGV("Start appspawn argvSize %{public}d mode %{public}d service %{public}s",
1378         argvSize, arg->mode, arg->serviceName);
1379     if (arg->mode == MODE_FOR_APP_SPAWN) {
1380 #ifndef APPSPAWN_TEST
1381         pid = NWebSpawnLaunch();
1382         if (pid == 0) {
1383             arg->socketName = NWEBSPAWN_SOCKET_NAME;
1384             arg->serviceName = NWEBSPAWN_SERVER_NAME;
1385             arg->moduleType = MODULE_NWEBSPAWN;
1386             arg->mode = MODE_FOR_NWEB_SPAWN;
1387             arg->initArg = 1;
1388         }
1389 #endif
1390     } else if (arg->mode == MODE_FOR_NWEB_SPAWN && getuid() == 0) {
1391         NWebSpawnInit();
1392     }
1393     if (arg->initArg) {
1394         int ret = memset_s(argv[0], argvSize, 0, (size_t)argvSize);
1395         APPSPAWN_CHECK(ret == EOK, return NULL, "Failed to memset argv[0]");
1396         ret = strncpy_s(argv[0], argvSize, arg->serviceName, strlen(arg->serviceName));
1397         APPSPAWN_CHECK(ret == EOK, return NULL, "Failed to copy service name %{public}s", arg->serviceName);
1398     }
1399 
1400     // load module appspawn/common
1401     AppSpawnLoadAutoRunModules(MODULE_COMMON);
1402     AppSpawnModuleMgrInstall(ASAN_MODULE_PATH);
1403 
1404     APPSPAWN_CHECK(LE_GetDefaultLoop() != NULL, return NULL, "Invalid default loop");
1405     AppSpawnContent *content = AppSpawnCreateContent(arg->socketName, argv[0], argvSize, arg->mode);
1406     APPSPAWN_CHECK(content != NULL, return NULL, "Failed to create content for %{public}s", arg->socketName);
1407 
1408     AppSpawnLoadAutoRunModules(arg->moduleType);  // load corresponding plugin according to startup mode
1409     int ret = ServerStageHookExecute(STAGE_SERVER_PRELOAD, content);   // Preload, prase the sandbox
1410     APPSPAWN_CHECK(ret == 0, AppSpawnDestroyContent(content);
1411         return NULL, "Failed to prepare load %{public}s result: %{public}d", arg->serviceName, ret);
1412 #ifndef APPSPAWN_TEST
1413     APPSPAWN_CHECK(content->runChildProcessor != NULL, AppSpawnDestroyContent(content);
1414         return NULL, "No child processor %{public}s result: %{public}d", arg->serviceName, ret);
1415 #endif
1416     AddAppSpawnHook(STAGE_CHILD_PRE_RUN, HOOK_PRIO_LOWEST, AppSpawnClearEnv);
1417     if (arg->mode == MODE_FOR_APP_SPAWN) {
1418         AddSpawnedProcess(pid, NWEBSPAWN_SERVER_NAME, false);
1419         SetParameter("bootevent.appspawn.started", "true");
1420     }
1421     return content;
1422 }
1423 
ProcessSpawnBegetctlMsg(AppSpawnConnection * connection,AppSpawnMsgNode * message)1424 static AppSpawnMsgNode *ProcessSpawnBegetctlMsg(AppSpawnConnection *connection, AppSpawnMsgNode *message)
1425 {
1426     uint32_t len = 0;
1427     const char *cmdMsg = (const char *)GetAppSpawnMsgExtInfo(message, MSG_EXT_NAME_BEGET_PID, &len);
1428     APPSPAWN_CHECK(cmdMsg != NULL, return NULL, "Failed to get extInfo");
1429     AppSpawnedProcess *appInfo = GetSpawnedProcess(atoi(cmdMsg));
1430     APPSPAWN_CHECK(appInfo != NULL, return NULL, "Failed to get app info");
1431     AppSpawnMsgNode *msgNode = RebuildAppSpawnMsgNode(message, appInfo);
1432     APPSPAWN_CHECK(msgNode != NULL, return NULL, "Failed to rebuild app message node");
1433     int ret = DecodeAppSpawnMsg(msgNode);
1434     if (ret != 0) {
1435         DeleteAppSpawnMsg(&msgNode);
1436         return NULL;
1437     }
1438     return msgNode;
1439 }
1440 
ProcessBegetCmdMsg(AppSpawnConnection * connection,AppSpawnMsgNode * message)1441 static void ProcessBegetCmdMsg(AppSpawnConnection *connection, AppSpawnMsgNode *message)
1442 {
1443     AppSpawnMsg *msg = &message->msgHeader;
1444     if (!IsDeveloperModeOpen()) {
1445         SendResponse(connection, msg, APPSPAWN_DEBUG_MODE_NOT_SUPPORT, 0);
1446         DeleteAppSpawnMsg(&message);
1447         return;
1448     }
1449     AppSpawnMsgNode *msgNode = ProcessSpawnBegetctlMsg(connection, message);
1450     if (msgNode == NULL) {
1451         SendResponse(connection, msg, APPSPAWN_DEBUG_MODE_NOT_SUPPORT, 0);
1452         DeleteAppSpawnMsg(&message);
1453         return;
1454     }
1455     ProcessSpawnReqMsg(connection, msgNode);
1456     DeleteAppSpawnMsg(&message);
1457     DeleteAppSpawnMsg(&msgNode);
1458 }
1459 
GetArkWebInstallPath(const char * key,char * value)1460 static int GetArkWebInstallPath(const char *key, char *value)
1461 {
1462     int len = GetParameter(key, "", value, PATH_SIZE);
1463     APPSPAWN_CHECK(len > 0, return -1, "Failed to get arkwebcore install path from param, len %{public}d", len);
1464     for (int i = len - 1; i >= 0; i--) {
1465         if (value[i] == '/') {
1466             value[i] = '\0';
1467             return i;
1468         }
1469         value[i] = '\0';
1470     }
1471     return -1;
1472 }
1473 
CheckAllDigit(char * userId)1474 static bool CheckAllDigit(char *userId)
1475 {
1476     for (int i = 0; userId[i] != '\0'; i++) {
1477         if (!isdigit(userId[i])) {
1478             return false;
1479         }
1480     }
1481     return true;
1482 }
1483 
1484 #ifdef APPSPAWN_SANDBOX_NEW
ProcessSpawnRemountMsg(AppSpawnConnection * connection,AppSpawnMsgNode * message)1485 static int ProcessSpawnRemountMsg(AppSpawnConnection *connection, AppSpawnMsgNode *message)
1486 {
1487     char srcPath[PATH_SIZE] = {0};
1488     int len = GetArkWebInstallPath("persist.arkwebcore.install_path", srcPath);
1489     APPSPAWN_CHECK(len > 0, return -1, "Failed to get arkwebcore install path");
1490 
1491     char *rootPath = "/mnt/sandbox";
1492     DIR *rootDir = opendir(rootPath);
1493     APPSPAWN_CHECK(rootDir != NULL, return -1, "Failed to opendir %{public}s, errno %{public}d", rootPath, errno);
1494 
1495     struct dirent *ent;
1496     while ((ent = readdir(rootDir)) != NULL) {
1497         char *userId = ent->d_name;
1498         if (strcmp(userId, ".") == 0 || strcmp(userId, "..") == 0 || !CheckAllDigit(userId)) {
1499             continue;
1500         }
1501         char destPath[PATH_SIZE] = {0};
1502         int ret = snprintf_s(destPath, sizeof(destPath), sizeof(destPath) - 1,
1503             "%s/%s/app-root/mnt/nweb/tmp", rootPath, userId);
1504         APPSPAWN_CHECK(ret > 0, continue, "Failed to snprintf_s, errno %{public}d", errno);
1505 
1506         ret = umount2(destPath, MNT_DETACH);
1507         if (ret != 0) {
1508             APPSPAWN_LOGW("Umount %{public}s failed, errno %{public}d", destPath, errno);
1509         }
1510 
1511         ret = mount(srcPath, destPath, NULL, MS_BIND | MS_REC, NULL);
1512         if (ret != 0 && errno == EBUSY) {
1513             ret = mount(srcPath, destPath, NULL, MS_BIND | MS_REC, NULL);
1514             APPSPAWN_LOGW("Bind mount again %{public}s to %{public}s, ret %{public}d", srcPath, destPath, ret);
1515         }
1516         APPSPAWN_CHECK(ret == 0, continue,
1517             "Failed to bind mount %{public}s to %{public}s, errno %{public}d", srcPath, destPath, errno);
1518 
1519         ret = mount(NULL, destPath, NULL, MS_SHARED, NULL);
1520         APPSPAWN_CHECK(ret == 0, continue,
1521             "Failed to shared mount %{public}s, errno %{public}d", destPath, errno);
1522 
1523         APPSPAWN_LOGI("Remount %{public}s to %{public}s success", srcPath, destPath);
1524     }
1525     closedir(rootDir);
1526     return 0;
1527 }
1528 #else
ProcessSpawnRemountMsg(AppSpawnConnection * connection,AppSpawnMsgNode * message)1529 static int ProcessSpawnRemountMsg(AppSpawnConnection *connection, AppSpawnMsgNode *message)
1530 {
1531     char srcPath[PATH_SIZE] = {0};
1532     int len = GetArkWebInstallPath("persist.arkwebcore.install_path", srcPath);
1533     APPSPAWN_CHECK(len > 0, return -1, "Failed to get arkwebcore install path");
1534 
1535     char *rootPath = "/mnt/sandbox";
1536     DIR *rootDir = opendir(rootPath);
1537     APPSPAWN_CHECK(rootDir != NULL, return -1, "Failed to opendir %{public}s, errno %{public}d", rootPath, errno);
1538 
1539     struct dirent *ent;
1540     while ((ent = readdir(rootDir)) != NULL) {
1541         char *userId = ent->d_name;
1542         if (strcmp(userId, ".") == 0 || strcmp(userId, "..") == 0 || !CheckAllDigit(userId)) {
1543             continue;
1544         }
1545 
1546         char userIdPath[PATH_SIZE] = {0};
1547         int ret = snprintf_s(userIdPath, sizeof(userIdPath), sizeof(userIdPath) - 1, "%s/%s", rootPath, userId);
1548         APPSPAWN_CHECK(ret > 0, continue, "Failed to snprintf_s, errno %{public}d", errno);
1549 
1550         DIR *userIdDir = opendir(userIdPath);
1551         APPSPAWN_CHECK(userIdDir != NULL, continue, "Failed to open %{public}s, errno %{public}d", userIdPath, errno);
1552 
1553         while ((ent = readdir(userIdDir)) != NULL) {
1554             char *bundleName = ent->d_name;
1555             if (strcmp(bundleName, ".") == 0 || strcmp(bundleName, "..") == 0) {
1556                 continue;
1557             }
1558             char destPath[PATH_SIZE] = {0};
1559             ret = snprintf_s(destPath, sizeof(destPath), sizeof(destPath) - 1,
1560                 "%s/%s/data/storage/el1/bundle/arkwebcore", userIdPath, bundleName);
1561             APPSPAWN_CHECK(ret > 0, continue, "Failed to snprintf_s, errno %{public}d", errno);
1562 
1563             umount2(destPath, MNT_DETACH);
1564             ret = mount(srcPath, destPath, NULL, MS_BIND | MS_REC, NULL);
1565             if (ret != 0 && errno == EBUSY) {
1566                 ret = mount(srcPath, destPath, NULL, MS_BIND | MS_REC, NULL);
1567                 APPSPAWN_LOGV("mount again %{public}s to %{public}s, ret %{public}d", srcPath, destPath, ret);
1568             }
1569             APPSPAWN_CHECK(ret == 0, continue,
1570                 "Failed to bind mount %{public}s to %{public}s, errno %{public}d", srcPath, destPath, errno);
1571 
1572             ret = mount(NULL, destPath, NULL, MS_SHARED, NULL);
1573             APPSPAWN_CHECK(ret == 0, continue,
1574                 "Failed to shared mount %{public}s to %{public}s, errno %{public}d", srcPath, destPath, errno);
1575 
1576             APPSPAWN_LOGV("Remount %{public}s to %{public}s success", srcPath, destPath);
1577         }
1578         closedir(userIdDir);
1579     }
1580     closedir(rootDir);
1581     return 0;
1582 }
1583 #endif
1584 
ProcessSpawnRestartMsg(AppSpawnConnection * connection,AppSpawnMsgNode * message)1585 static void ProcessSpawnRestartMsg(AppSpawnConnection *connection, AppSpawnMsgNode *message)
1586 {
1587     AppSpawnContent *content = GetAppSpawnContent();
1588     if (!IsNWebSpawnMode((AppSpawnMgr *)content)) {
1589         SendResponse(connection, &message->msgHeader, APPSPAWN_MSG_INVALID, 0);
1590         DeleteAppSpawnMsg(&message);
1591         APPSPAWN_LOGE("Restart msg only support nwebspawn");
1592         return;
1593     }
1594 
1595     TraversalSpawnedProcess(AppQueueDestroyProc, NULL);
1596     SendResponse(connection, &message->msgHeader, 0, 0);
1597     DeleteAppSpawnMsg(&message);
1598     (void) ServerStageHookExecute(STAGE_SERVER_EXIT, content);
1599 
1600     errno = 0;
1601     int fd = GetControlSocket(NWEBSPAWN_SOCKET_NAME);
1602     APPSPAWN_CHECK(fd >= 0, return, "Get fd failed %{public}d, errno %{public}d", fd, errno);
1603 
1604     int ret = 0;
1605     int op = fcntl(fd, F_GETFD);
1606     APPSPAWN_CHECK_ONLY_LOG(op >= 0, "fcntl failed %{public}d", op);
1607     if (op > 0) {
1608         ret = fcntl(fd, F_SETFD, (unsigned int)op & ~FD_CLOEXEC);
1609         if (ret < 0) {
1610             APPSPAWN_LOGE("Set fd failed %{public}d, %{public}d, ret %{public}d, errno %{public}d", fd, op, ret, errno);
1611         }
1612     }
1613 
1614     char *path = "/system/bin/appspawn";
1615     char *mode = NWEBSPAWN_RESTART;
1616     const char *const formatCmds[] = {path, "-mode", mode, NULL};
1617     ret = execv(path, (char **)formatCmds);
1618     APPSPAWN_LOGE("Failed to execv, ret %{public}d, errno %{public}d", ret, errno);
1619 }
1620 
ProcessUninstallDebugHap(AppSpawnConnection * connection,AppSpawnMsgNode * message)1621 APPSPAWN_STATIC void ProcessUninstallDebugHap(AppSpawnConnection *connection, AppSpawnMsgNode *message)
1622 {
1623     APPSPAWN_LOGI("ProcessUninstallDebugHap start");
1624     AppSpawningCtx *property = CreateAppSpawningCtx();
1625     if (property == NULL) {
1626         SendResponse(connection, &message->msgHeader, APPSPAWN_SYSTEM_ERROR, 0);
1627         DeleteAppSpawnMsg(&message);
1628         return;
1629     }
1630 
1631     property->message = message;
1632     property->message->connection = connection;
1633     int ret = AppSpawnHookExecute(STAGE_PARENT_UNINSTALL, 0, GetAppSpawnContent(), &property->client);
1634     SendResponse(connection, &message->msgHeader, ret, 0);
1635     DeleteAppSpawningCtx(property);
1636 }
1637 
AppspawpnDevicedebugKill(int pid,cJSON * args)1638 APPSPAWN_STATIC int AppspawpnDevicedebugKill(int pid, cJSON *args)
1639 {
1640     cJSON *signal = cJSON_GetObjectItem(args, "signal");
1641     if (!cJSON_IsNumber(signal)) {
1642         APPSPAWN_LOGE("appspawn devicedebug json get signal fail");
1643         return -1;
1644     }
1645 
1646     AppSpawnedProcess *appInfo = GetSpawnedProcess(pid);
1647     if (appInfo == NULL) {
1648         APPSPAWN_LOGE("appspawn devicedebug get app info unsuccess, pid=%{public}d", pid);
1649         return APPSPAWN_DEVICEDEBUG_ERROR_APP_NOT_EXIST;
1650     }
1651 
1652     if (!appInfo->isDebuggable) {
1653         APPSPAWN_LOGE("appspawn devicedebug process is not debuggable, pid=%{public}d", pid);
1654         return APPSPAWN_DEVICEDEBUG_ERROR_APP_NOT_DEBUGGABLE;
1655     }
1656 
1657     APPSPAWN_LOGI("appspawn devicedebug debugable=%{public}d, pid=%{public}d, signal=%{public}d",
1658         appInfo->isDebuggable, pid, signal->valueint);
1659 
1660     if (kill(pid, signal->valueint) != 0) {
1661         APPSPAWN_LOGE("appspawn devicedebug unable to kill process, pid: %{public}d ret %{public}d", pid, errno);
1662         return -1;
1663     }
1664 
1665     return 0;
1666 }
1667 
AppspawnDevicedebugDeal(const char * op,int pid,cJSON * args)1668 APPSPAWN_STATIC int AppspawnDevicedebugDeal(const char* op, int pid, cJSON *args)
1669 {
1670     if (strcmp(op, "kill") == 0) {
1671         return AppspawpnDevicedebugKill(pid, args);
1672     }
1673     APPSPAWN_LOGE("appspawn devicedebug op:%{public}s invaild", op);
1674 
1675     return -1;
1676 }
1677 
ProcessAppSpawnDeviceDebugMsg(AppSpawnMsgNode * message)1678 APPSPAWN_STATIC int ProcessAppSpawnDeviceDebugMsg(AppSpawnMsgNode *message)
1679 {
1680     APPSPAWN_CHECK_ONLY_EXPER(message != NULL, return -1);
1681     uint32_t len = 0;
1682 
1683     const char* jsonString = (char *)GetAppSpawnMsgExtInfo(message, "devicedebug", &len);
1684     if (jsonString == NULL || len == 0) {
1685         APPSPAWN_LOGE("appspawn devicedebug get devicedebug fail");
1686         return -1;
1687     }
1688 
1689     cJSON *json = cJSON_Parse(jsonString);
1690     if (json == NULL) {
1691         APPSPAWN_LOGE("appspawn devicedebug json parse fail");
1692         return -1;
1693     }
1694 
1695     cJSON *app = cJSON_GetObjectItem(json, "app");
1696     if (!cJSON_IsNumber(app)) {
1697         APPSPAWN_LOGE("appspawn devicedebug json get app fail");
1698         cJSON_Delete(json);
1699         return -1;
1700     }
1701 
1702     cJSON *op = cJSON_GetObjectItem(json, "op");
1703     if (!cJSON_IsString(op) || op->valuestring == NULL) {
1704         APPSPAWN_LOGE("appspawn devicedebug json get op fail");
1705         cJSON_Delete(json);
1706         return -1;
1707     }
1708 
1709     cJSON *args = cJSON_GetObjectItem(json, "args");
1710     if (!cJSON_IsObject(args)) {
1711         APPSPAWN_LOGE("appspawn devicedebug json get args fail");
1712         cJSON_Delete(json);
1713         return -1;
1714     }
1715 
1716     int result = AppspawnDevicedebugDeal(op->valuestring, app->valueint, args);
1717     cJSON_Delete(json);
1718     return result;
1719 }
1720 
ProcessAppSpawnLockStatusMsg(AppSpawnMsgNode * message)1721 static void ProcessAppSpawnLockStatusMsg(AppSpawnMsgNode *message)
1722 {
1723     APPSPAWN_CHECK_ONLY_EXPER(message != NULL, return);
1724     uint32_t len = 0;
1725     char *lockstatus = (char *)GetAppSpawnMsgExtInfo(message, "lockstatus", &len);
1726     APPSPAWN_CHECK(lockstatus != NULL, return, "failed to get lockstatus");
1727     APPSPAWN_LOGI("appspawn get lockstatus %{public}s from storage_manager", lockstatus);
1728     char *userLockStatus = NULL;
1729     // userLockStatus format example:  100:0  100 for userid 0:unlock 1:lock
1730     char *userIdStr = strtok_r(lockstatus, ":", &userLockStatus);
1731     APPSPAWN_CHECK(userIdStr != NULL && userLockStatus != NULL, return,
1732         "lockstatus not satisfied format, failed to get userLockStatus");
1733     int userId = atoi(userIdStr);
1734     if (userId < USER_ID_MIN_VALUE || userId > USER_ID_MAX_VALUE) {
1735         APPSPAWN_LOGE("userId err %{public}s", userIdStr);
1736         return;
1737     }
1738     if (strcmp(userLockStatus, "0") != 0 && strcmp(userLockStatus, "1") != 0) {
1739         APPSPAWN_LOGE("userLockStatus err %{public}s", userLockStatus);
1740         return;
1741     }
1742     char lockStatusParam[LOCK_STATUS_PARAM_SIZE] = {0};
1743     int ret = snprintf_s(lockStatusParam, sizeof(lockStatusParam), sizeof(lockStatusParam) - 1,
1744         "startup.appspawn.lockstatus_%d", userId);
1745     APPSPAWN_CHECK(ret > 0, return, "get lock status param failed, errno %{public}d", errno);
1746     ret = SetParameter(lockStatusParam, userLockStatus);
1747     APPSPAWN_CHECK(ret == 0, return, "failed to set lockstatus param value ret %{public}d", ret);
1748 #ifdef APPSPAWN_HISYSEVENT
1749     ReportKeyEvent(strcmp(userLockStatus, "0") == 0 ? UNLOCK_SUCCESS : LOCK_SUCCESS);
1750 #endif
1751 #ifndef APPSPAWN_SANDBOX_NEW
1752     if (strcmp(userLockStatus, "0") == 0) {
1753         ServerStageHookExecute(STAGE_SERVER_LOCK, GetAppSpawnContent());
1754     }
1755 #endif
1756 }
1757 
AppSpawnReqMsgFdGet(AppSpawnConnection * connection,AppSpawnMsgNode * message,const char * fdName,int * fd)1758 APPSPAWN_STATIC int AppSpawnReqMsgFdGet(AppSpawnConnection *connection, AppSpawnMsgNode *message,
1759     const char *fdName, int *fd)
1760 {
1761     APPSPAWN_CHECK_ONLY_EXPER(message != NULL && message->buffer != NULL && connection != NULL, return -1);
1762     APPSPAWN_CHECK_ONLY_EXPER(message->tlvOffset != NULL, return -1);
1763     int findFdIndex = 0;
1764     AppSpawnMsgReceiverCtx recvCtx = connection->receiverCtx;
1765     APPSPAWN_CHECK(recvCtx.fds != NULL && recvCtx.fdCount > 0, return 0,
1766         "no need get fd info %{public}d, %{public}d", recvCtx.fds != NULL, recvCtx.fdCount);
1767 
1768     for (uint32_t index = TLV_MAX; index < (TLV_MAX + message->tlvCount); index++) {
1769         if (message->tlvOffset[index] == INVALID_OFFSET) {
1770             return APPSPAWN_SYSTEM_ERROR;
1771         }
1772         uint8_t *data = message->buffer + message->tlvOffset[index];
1773         if (((AppSpawnTlv *)data)->tlvType != TLV_MAX) {
1774             continue;
1775         }
1776         AppSpawnTlvExt *tlv = (AppSpawnTlvExt *)data;
1777         if (strcmp(tlv->tlvName, MSG_EXT_NAME_APP_FD) != 0) {
1778             continue;
1779         }
1780         APPSPAWN_CHECK(findFdIndex < recvCtx.fdCount && recvCtx.fds[findFdIndex] > 0, return -1,
1781             "check get fd args failed %{public}d, %{public}d, %{public}d",
1782             findFdIndex, recvCtx.fdCount, recvCtx.fds[findFdIndex]);
1783 
1784         if (strcmp((const char *)(data + sizeof(AppSpawnTlvExt)), fdName) == 0 && recvCtx.fds[findFdIndex] > 0) {
1785             *fd = recvCtx.fds[findFdIndex];
1786             APPSPAWN_LOGI("Spawn Listen fd %{public}s get success %{public}d", fdName, recvCtx.fds[findFdIndex]);
1787             break;
1788         }
1789         findFdIndex++;
1790         if (findFdIndex >= recvCtx.fdCount) {
1791             break;
1792         }
1793     }
1794     return 0;
1795 }
1796 
ProcessObserveProcessSignalMsg(AppSpawnConnection * connection,AppSpawnMsgNode * message)1797 APPSPAWN_STATIC void ProcessObserveProcessSignalMsg(AppSpawnConnection *connection, AppSpawnMsgNode *message)
1798 {
1799     APPSPAWN_CHECK_ONLY_EXPER(message != NULL, return);
1800     int fd = 0;
1801     int ret = AppSpawnReqMsgFdGet(connection, message, SPAWN_LISTEN_FD_NAME, &fd);
1802     if (fd <= 0 || ret != 0) {
1803         APPSPAWN_LOGE("Spawn Listen appspawn signal fd get unsuccess");
1804         SendResponse(connection, &message->msgHeader, APPSPAWN_SYSTEM_ERROR, 0);
1805         DeleteAppSpawnMsg(&message);
1806         return;
1807     }
1808 
1809     AppSpawnContent *content = GetAppSpawnContent();
1810     APPSPAWN_CHECK(content != NULL, return, "Spawn Listen appspawn content is null");
1811     content->signalFd = fd;
1812     connection->receiverCtx.fdCount = 0;
1813     SendResponse(connection, &message->msgHeader, 0, 0);
1814     DeleteAppSpawnMsg(&message);
1815 }
1816 
ProcessRecvMsg(AppSpawnConnection * connection,AppSpawnMsgNode * message)1817 static void ProcessRecvMsg(AppSpawnConnection *connection, AppSpawnMsgNode *message)
1818 {
1819     AppSpawnMsg *msg = &message->msgHeader;
1820     APPSPAWN_LOGI("Recv message header magic 0x%{public}x type %{public}u id %{public}u len %{public}u %{public}s",
1821         msg->magic, msg->msgType, msg->msgId, msg->msgLen, msg->processName);
1822     APPSPAWN_CHECK_ONLY_LOG(connection->receiverCtx.nextMsgId == msg->msgId,
1823         "Invalid msg id %{public}u %{public}u", connection->receiverCtx.nextMsgId, msg->msgId);
1824     connection->receiverCtx.nextMsgId++;
1825 
1826     int ret;
1827     switch (msg->msgType) {
1828         case MSG_GET_RENDER_TERMINATION_STATUS: {  // get status
1829             AppSpawnResult result = {0};
1830             ret = ProcessTerminationStatusMsg(message, &result);
1831             SendResponse(connection, msg, ret == 0 ? result.result : ret, result.pid);
1832             DeleteAppSpawnMsg(&message);
1833             break;
1834         }
1835         case MSG_SPAWN_NATIVE_PROCESS:  // spawn msg
1836         case MSG_APP_SPAWN: {
1837             ProcessSpawnReqMsg(connection, message);
1838             break;
1839         }
1840         case MSG_DUMP:
1841             ProcessAppSpawnDumpMsg(message);
1842             SendResponse(connection, msg, 0, 0);
1843             DeleteAppSpawnMsg(&message);
1844             break;
1845         case MSG_BEGET_CMD: {
1846             ProcessBegetCmdMsg(connection, message);
1847             break;
1848         }
1849         case MSG_BEGET_SPAWNTIME:
1850             SendResponse(connection, msg, GetAppSpawnMgr()->spawnTime.minAppspawnTime,
1851                          GetAppSpawnMgr()->spawnTime.maxAppspawnTime);
1852             DeleteAppSpawnMsg(&message);
1853             break;
1854         case MSG_UPDATE_MOUNT_POINTS:
1855             ret = ProcessSpawnRemountMsg(connection, message);
1856             SendResponse(connection, msg, ret, 0);
1857             break;
1858         case MSG_RESTART_SPAWNER:
1859             ProcessSpawnRestartMsg(connection, message);
1860             break;
1861         case MSG_DEVICE_DEBUG:
1862             ret = ProcessAppSpawnDeviceDebugMsg(message);
1863             SendResponse(connection, msg, ret, 0);
1864             DeleteAppSpawnMsg(&message);
1865             break;
1866         case MSG_UNINSTALL_DEBUG_HAP:
1867             ProcessUninstallDebugHap(connection, message);
1868             break;
1869         case MSG_LOCK_STATUS:
1870             ProcessAppSpawnLockStatusMsg(message);
1871             SendResponse(connection, msg, 0, 0);
1872             DeleteAppSpawnMsg(&message);
1873             break;
1874         case MSG_OBSERVE_PROCESS_SIGNAL_STATUS:
1875             ProcessObserveProcessSignalMsg(connection, message);
1876             break;
1877         default:
1878             SendResponse(connection, msg, APPSPAWN_MSG_INVALID, 0);
1879             DeleteAppSpawnMsg(&message);
1880             break;
1881     }
1882 }
1883