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, ¶m);
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