diff --git a/appspawn.cfg b/appspawn.cfg index 2cd57bb05f6b0a0d31ec70c9e66f161d235ce1d8..a0b61fc7f963b3dccf91b7615c558780de372fb8 100644 --- a/appspawn.cfg +++ b/appspawn.cfg @@ -4,9 +4,8 @@ "cmds" : [ "mkdir /mnt/sandbox", "mkdir /mnt/sandbox/com.ohos.render/ 0711 nwebspawn nwebspawn", - "mkdir /mnt/startup", - "mkdir /mnt/startup/appspawn 0700 root root", - "mkdir /mnt/startup/nwebspawn/ 0700 nwebspawn nwebspawn" + "mkdir /data/service/el1/startup/appspawn 0700 root root", + "mkdir /data/service/el1/startup/nwebspawn/ 0700 nwebspawn nwebspawn" ] }, { diff --git a/common/appspawn_server.h b/common/appspawn_server.h index 7ccc93b1d1ffa25c8ac6e703d4f8aa9616aef815..def2c774d2d74a9c30b0b69b38017ca3cb860c92 100644 --- a/common/appspawn_server.h +++ b/common/appspawn_server.h @@ -56,6 +56,12 @@ typedef struct AppSpawnClient { uint32_t flags; // Save negotiated flags } AppSpawnClient; +typedef struct AppSpawnPreforkMsg { + uint32_t id; + uint32_t flags; // Save negotiated flags + uint32_t msgLen; +} AppSpawnPreforkMsg; + typedef struct AppSpawnContent { char *longProcName; uint32_t longProcNameLen; diff --git a/standard/appspawn_service.c b/standard/appspawn_service.c index 1764d93c5eef9cb6a16f8e16224524401cf8a8d9..305b2b3717003336d833d5cc929cfed10b267a80 100644 --- a/standard/appspawn_service.c +++ b/standard/appspawn_service.c @@ -51,7 +51,6 @@ #define PARAM_BUFFER_SIZE 10 #define PATH_SIZE 256 #define FD_PATH_SIZE 128 -#define MAX_MEM_SIZE (4 * 1024) #define APPSPAWN_MSG_USER_CHECK_COUNT 4 #define PREFORK_PROCESS "apppool" #define USER_ID_MIN_VALUE 100 @@ -670,7 +669,25 @@ static bool IsSupportRunHnp() return false; } -static int WritePreforkMsg(AppSpawningCtx *property) +static void ClearMMAP(int clientId, uint32_t memSize) +{ + char path[PATH_MAX] = {0}; + int ret = snprintf_s(path, sizeof(path), sizeof(path) - 1, APPSPAWN_MSG_DIR "appspawn/prefork_%d", clientId); + APPSPAWN_LOGV("prefork unlink %{public}s ret :%{public}d", path, ret); + if (ret > 0 && access(path, F_OK) == 0) { + ret = unlink(path); + APPSPAWN_CHECK_ONLY_LOG(ret == 0, "prefork unlink result %{public}d %{public}d", ret, errno); + } + + AppSpawnContent *content = GetAppSpawnContent(); + if (content != NULL && content->propertyBuffer != NULL) { + ret = munmap(content->propertyBuffer, memSize); + APPSPAWN_CHECK_ONLY_LOG(ret == 0, "munmap failed %{public}d", ret); + content->propertyBuffer = NULL; + } +} + +static int WritePreforkMsg(AppSpawningCtx *property, uint32_t memSize) { AppSpawnContent *content = GetAppSpawnContent(); if (content == NULL || content->propertyBuffer == NULL) { @@ -678,22 +695,22 @@ static int WritePreforkMsg(AppSpawningCtx *property) return -1; } - int ret = memcpy_s(content->propertyBuffer, MAX_MEM_SIZE, &property->message->msgHeader, sizeof(AppSpawnMsg)); - APPSPAWN_CHECK(ret == 0, goto fail, "memcpys_s msgHeader failed"); - ret = memcpy_s((char *)content->propertyBuffer + sizeof(AppSpawnMsg), MAX_MEM_SIZE - sizeof(AppSpawnMsg), + int ret = memcpy_s(content->propertyBuffer, memSize, &property->message->msgHeader, sizeof(AppSpawnMsg)); + APPSPAWN_CHECK(ret == 0, ClearMMAP(property->client.id, memSize); + return ret, "memcpys_s msgHeader failed"); + ret = memcpy_s((char *)content->propertyBuffer + sizeof(AppSpawnMsg), memSize - sizeof(AppSpawnMsg), property->message->buffer, property->message->msgHeader.msgLen - sizeof(AppSpawnMsg)); - APPSPAWN_CHECK(ret == 0, goto fail, "memcpys_s AppSpawnMsg failed"); - return ret; + APPSPAWN_CHECK(ret == 0, ClearMMAP(property->client.id, memSize); + return ret, "memcpys_s AppSpawnMsg failed"); -fail: - munmap((char *)content->propertyBuffer, MAX_MEM_SIZE); + munmap((char *)content->propertyBuffer, memSize); content->propertyBuffer = NULL; return ret; } -static int GetAppSpawnMsg(AppSpawningCtx *property) +static int GetAppSpawnMsg(AppSpawningCtx *property, uint32_t memSize) { - uint8_t *buffer = (uint8_t *)GetMapMem(property->client.id, "prefork", MAX_MEM_SIZE, true, false); + uint8_t *buffer = (uint8_t *)GetMapMem(property->client.id, "prefork", memSize, true, false); if (buffer == NULL) { APPSPAWN_LOGE("prefork buffer is null can not write propery"); return -1; @@ -701,7 +718,7 @@ static int GetAppSpawnMsg(AppSpawningCtx *property) uint32_t msgRecvLen = 0; uint32_t remainLen = 0; property->forkCtx.childMsg = (char *)buffer; - property->forkCtx.msgSize = MAX_MEM_SIZE; + property->forkCtx.msgSize = memSize; AppSpawnMsgNode *message = NULL; int ret = GetAppSpawnMsgFromBuffer(buffer, ((AppSpawnMsg *)buffer)->msgLen, &message, &msgRecvLen, &remainLen); // release map @@ -714,25 +731,6 @@ static int GetAppSpawnMsg(AppSpawningCtx *property) return -1; } -static void ClearMMAP(int clientId) -{ - char path[PATH_MAX] = {0}; - int ret = snprintf_s(path, sizeof(path), sizeof(path) - 1, APPSPAWN_MSG_DIR "appspawn/prefork_%d", clientId); - APPSPAWN_LOGV("prefork unlink %{public}s ret :%{public}d", path, ret); - if (ret > 0) { - errno = 0; - ret = unlink(path); - APPSPAWN_LOGV("prefork unlink result %{public}d %{public}d", ret, errno); - } - - AppSpawnContent *content = GetAppSpawnContent(); - if (content != NULL && content->propertyBuffer != NULL) { - ret = munmap(content->propertyBuffer, MAX_MEM_SIZE); - APPSPAWN_CHECK_ONLY_LOG(ret == 0, "munmap failed %{public}d", ret); - content->propertyBuffer = NULL; - } -} - static int SetPreforkProcessName(AppSpawnContent *content) { int ret = prctl(PR_SET_NAME, PREFORK_PROCESS); @@ -773,28 +771,30 @@ static void ProcessPreFork(AppSpawnContent *content, AppSpawningCtx *property) (void)close(property->forkCtx.fd[1]); int isRet = SetPreforkProcessName(content); APPSPAWN_LOGV("prefork process start wait read msg with set processname %{public}d", isRet); - AppSpawnClient client = {0, 0}; - int infoSize = read(content->parentToChildFd[0], &client, sizeof(AppSpawnClient)); - if (infoSize != sizeof(AppSpawnClient)) { + AppSpawnPreforkMsg preforkMsg = {0, 0, 0}; + int infoSize = read(content->parentToChildFd[0], &preforkMsg, sizeof(AppSpawnPreforkMsg)); + if (infoSize != sizeof(AppSpawnPreforkMsg) || preforkMsg.msgLen > MAX_MSG_TOTAL_LENGTH || + preforkMsg.msgLen < sizeof(AppSpawnMsg)) { APPSPAWN_LOGE("prefork process read msg failed %{public}d,%{public}d", infoSize, errno); ProcessExit(0); return; } - property->client.id = client.id; - property->client.flags = client.flags; + property->client.id = preforkMsg.id; + property->client.flags = preforkMsg.flags; property->isPrefork = true; property->forkCtx.fd[0] = content->preforkFd[0]; property->forkCtx.fd[1] = content->preforkFd[1]; property->state = APP_STATE_SPAWNING; - if (GetAppSpawnMsg(property) == -1) { + const uint32_t memSize = (preforkMsg.msgLen / MAX_MSG_BLOCK_LEN + 1) * MAX_MSG_BLOCK_LEN; + if (GetAppSpawnMsg(property, memSize) == -1) { APPSPAWN_LOGE("prefork child read GetAppSpawnMsg failed"); - ClearMMAP(property->client.id); + ClearMMAP(property->client.id, memSize); content->notifyResToParent(content, &property->client, APPSPAWN_MSG_INVALID); ProcessExit(0); return; } - ClearMMAP(property->client.id); + ClearMMAP(property->client.id, memSize); // Inherit the error level of the original process (void)fdsan_set_error_level(errorLevel); ProcessExit(AppSpawnChild(content, &property->client)); @@ -803,22 +803,32 @@ static void ProcessPreFork(AppSpawnContent *content, AppSpawningCtx *property) } } +static int NormalSpawnChild(AppSpawnContent *content, AppSpawnClient *client, pid_t *childPid) +{ + APPSPAWN_CHECK(client != NULL, return APPSPAWN_ARG_INVALID, "client is null"); + int ret = InitForkContext((AppSpawningCtx *)client); + APPSPAWN_CHECK(ret == 0, return ret, "init fork context failed"); + return AppSpawnProcessMsg(content, client, childPid); +} + static int AppSpawnProcessMsgForPrefork(AppSpawnContent *content, AppSpawnClient *client, pid_t *childPid) { int ret = 0; AppSpawningCtx *property = (AppSpawningCtx *)client; if (content->reservedPid <= 0) { - APPSPAWN_CHECK(client != NULL, return ret, "client is null"); - ret = InitForkContext((AppSpawningCtx *)client); - APPSPAWN_CHECK(ret == 0, return ret, "init fork context failed"); - ret = AppSpawnProcessMsg(content, client, childPid); + ret = NormalSpawnChild(content, client, childPid); } else { - APPSPAWN_CHECK_ONLY_EXPER(content->propertyBuffer == NULL, ClearMMAP(client->id)); - content->propertyBuffer = GetMapMem(property->client.id, "prefork", MAX_MEM_SIZE, false, false); - APPSPAWN_CHECK(content->propertyBuffer != NULL, return -1, "GetPreforkMem failed"); - ret = WritePreforkMsg(property); - APPSPAWN_CHECK(ret == 0, return ret, "WritePreforkMsg failed"); + const uint32_t memSize = (property->message->msgHeader.msgLen / MAX_MSG_BLOCK_LEN + 1) * + MAX_MSG_BLOCK_LEN; + content->propertyBuffer = GetMapMem(property->client.id, "prefork", memSize, false, false); + APPSPAWN_CHECK(content->propertyBuffer != NULL, clearMMAP(property->client.id, memSize); + return NormalSpawnChild(content, client, childPid), + "GetPreforkMem failed"); + ret = WritePreforkMsg(property, memSize); + APPSPAWN_CHECK(ret == 0, clearMMAP(property->client.id, memSize); + return NormalSpawnChild(content, client, childPid), + "WritePreforkMsg failed"); *childPid = content->reservedPid; property->forkCtx.fd[0] = content->preforkFd[0]; @@ -829,12 +839,21 @@ static int AppSpawnProcessMsgForPrefork(AppSpawnContent *content, AppSpawnClient ret = fcntl(property->forkCtx.fd[0], F_SETFD, (unsigned int)option | O_NONBLOCK); APPSPAWN_CHECK_ONLY_LOG(ret == 0, "fcntl failed %{public}d,%{public}d", ret, errno); } - - ssize_t writesize = write(content->parentToChildFd[1], client, sizeof(AppSpawnClient)) ; - APPSPAWN_CHECK(writesize == sizeof(AppSpawnClient), kill(*childPid, SIGKILL); + AppSpawnPreforkMsg *preforkMsg = (AppSpawnPreforkMsg *)calloc(1, sizeof(AppSpawnPreforkMsg)); + APPSPAWN_CHECK(preforkMsg != NULL, clearMMAP(property->client.id, memSize); + return NormalSpawnChild(content, client, childPid), + "malloc failed"); + preforkMsg->id = client->id; + preforkMsg->flags = client->flags; + preforkMsg->msgLen = property->message->msgHeader.msgLen; + + ssize_t writesize = write(content->parentToChildFd[1], preforkMsg, sizeof(AppSpawnPreforkMsg)) ; + APPSPAWN_CHECK(writesize == sizeof(AppSpawnPreforkMsg), kill(*childPid, SIGKILL); *childPid = 0; ret = -1, "write msg to child failed %{public}d", errno); + free(preforkMsg); + preforkMsg = NULL; } ProcessPreFork(content, property); return ret; @@ -873,13 +892,10 @@ static int RunAppSpawnProcessMsg(AppSpawnContent *content, AppSpawnClient *clien { int ret = 0; - if (IsBootFinished() && IsSupportPrefork(content, client)) { + if (IsBootFinished() && IsSupportPrefork(content, client) && ) { ret = AppSpawnProcessMsgForPrefork(content, client, childPid); } else { - APPSPAWN_CHECK(client != NULL, return ret, "client is null"); - ret = InitForkContext((AppSpawningCtx *)client); - APPSPAWN_CHECK(ret == 0, return ret, "init fork context failed"); - ret = AppSpawnProcessMsg(content, client, childPid); + ret = NormalSpawnChild(content, client, childPid); } return ret; } diff --git a/util/include/appspawn_utils.h b/util/include/appspawn_utils.h index ff220c3335109b87251a7b33a4936c6d64dfd911..38e96f90d8f82c87d9e2218dcb57ad5393f3d04f 100755 --- a/util/include/appspawn_utils.h +++ b/util/include/appspawn_utils.h @@ -45,10 +45,10 @@ extern "C" { #endif #if defined(__MUSL__) #define APPSPAWN_SOCKET_DIR APPSPAWN_BASE_DIR "/dev/unix/socket/" -#define APPSPAWN_MSG_DIR APPSPAWN_BASE_DIR "/mnt/startup/" +#define APPSPAWN_MSG_DIR APPSPAWN_BASE_DIR "/data/service/el1/startup/" #else #define APPSPAWN_SOCKET_DIR APPSPAWN_BASE_DIR "/dev/socket/" -#define APPSPAWN_MSG_DIR APPSPAWN_BASE_DIR "/mnt/startup/" +#define APPSPAWN_MSG_DIR APPSPAWN_BASE_DIR "/data/service/el1/startup/" #endif #define DEVICE_VIRTUAL_NET_IO_FLAGS "/sys/devices/virtual/net/lo/flags"