From 0fa4425080542e41cdb2c2b19954817a9d005a1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B5=A9?= Date: Thu, 16 Jan 2025 09:03:07 +0800 Subject: [PATCH 1/2] memSize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 杨浩 --- common/appspawn_server.h | 6 +++ standard/appspawn_service.c | 98 ++++++++++++++++++++----------------- 2 files changed, 59 insertions(+), 45 deletions(-) diff --git a/common/appspawn_server.h b/common/appspawn_server.h index 7ccc93b1..def2c774 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 1764d93c..58c6931c 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)); @@ -814,10 +814,11 @@ static int AppSpawnProcessMsgForPrefork(AppSpawnContent *content, AppSpawnClient APPSPAWN_CHECK(ret == 0, return ret, "init fork context failed"); ret = AppSpawnProcessMsg(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); + 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, return -1, "GetPreforkMem failed"); - ret = WritePreforkMsg(property); + ret = WritePreforkMsg(property, memSize); APPSPAWN_CHECK(ret == 0, return ret, "WritePreforkMsg failed"); *childPid = content->reservedPid; @@ -829,12 +830,19 @@ 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, return APPSPAWN_SYSTEM_ERROR, "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; -- Gitee From f02714849d99ba1b7a0f0bdc9ce3c658e870d8a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B5=A9?= Date: Thu, 16 Jan 2025 19:27:41 +0800 Subject: [PATCH 2/2] modify prefork MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 杨浩 --- appspawn.cfg | 5 ++--- standard/appspawn_service.c | 32 ++++++++++++++++++++------------ util/include/appspawn_utils.h | 4 ++-- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/appspawn.cfg b/appspawn.cfg index 2cd57bb0..a0b61fc7 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/standard/appspawn_service.c b/standard/appspawn_service.c index 58c6931c..305b2b37 100644 --- a/standard/appspawn_service.c +++ b/standard/appspawn_service.c @@ -803,23 +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 { 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, return -1, "GetPreforkMem failed"); + 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, return ret, "WritePreforkMsg failed"); + 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]; @@ -831,7 +840,9 @@ static int AppSpawnProcessMsgForPrefork(AppSpawnContent *content, AppSpawnClient APPSPAWN_CHECK_ONLY_LOG(ret == 0, "fcntl failed %{public}d,%{public}d", ret, errno); } AppSpawnPreforkMsg *preforkMsg = (AppSpawnPreforkMsg *)calloc(1, sizeof(AppSpawnPreforkMsg)); - APPSPAWN_CHECK(preforkMsg != NULL, return APPSPAWN_SYSTEM_ERROR, "malloc failed"); + 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; @@ -881,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 ff220c33..38e96f90 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" -- Gitee