sync appspawn code

Signed-off-by: nianyuu <zhouwenqiang12@huawei.com>
This commit is contained in:
nianyuu 2024-11-08 17:49:02 +08:00
parent 8748ca49e9
commit 3068880eb4
8 changed files with 51 additions and 28 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 20214 Huawei Device Co., Ltd.
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@ -84,7 +84,6 @@ int AppSpawnChild(AppSpawnContent *content, AppSpawnClient *client)
}
APPSPAWN_LOGW("AppSpawnChild cold start fail %{public}u", client->id);
}
StartAppspawnTrace("AppSpawnExecuteSpawningHook");
ret = AppSpawnExecuteSpawningHook(content, client);
FinishAppspawnTrace();

View File

@ -392,6 +392,7 @@ APPSPAWN_STATIC const char *GetRealSrcPath(const SandboxContext *context, const
// 设置挂载参数options
static int32_t SetMountArgsOption(const SandboxContext *context, uint32_t category, uint32_t operation, MountArg *args)
{
args->options = "";
if ((category != MOUNT_TMP_DAC_OVERRIDE) && (category != MOUNT_TMP_DAC_OVERRIDE_DELETE)) {
return 0;
}
@ -412,7 +413,7 @@ static int32_t SetMountArgsOption(const SandboxContext *context, uint32_t catego
return 0;
}
// 根据沙盒配置文件中挂载类别进行挂载挂载
// 根据沙盒配置文件中挂载类别进行挂载
static int DoSandboxMountByCategory(const SandboxContext *context, const PathMountNode *sandboxNode,
MountArg *args, uint32_t operation)
{
@ -465,6 +466,7 @@ static int DoSandboxPathNodeMount(const SandboxContext *context,
CreateSandboxDir(args.destinationPath, FILE_MODE);
}
}
CreateDemandSrc(context, sandboxNode, &args);
int ret = 0;
@ -546,7 +548,7 @@ static bool IsUnlockStatus(uint32_t uid, const char *bundleName, size_t bundleNa
{
const int userIdBase = UID_BASE;
uid = uid / userIdBase;
if (uid == 0) {
if (uid == 0) { // uid = 0 不涉及加密目录的挂载
return true;
}
@ -554,6 +556,7 @@ static bool IsUnlockStatus(uint32_t uid, const char *bundleName, size_t bundleNa
const char basePath[] = "/base/";
size_t allPathSize = strlen(rootPath) + strlen(basePath) + 1 + USER_ID_SIZE + bundleNameLen;
char *path = (char *)malloc(sizeof(char) * allPathSize);
(void)memset_s(path, allPathSize, 0, allPathSize);
APPSPAWN_CHECK(path != NULL, return true, "Failed to malloc path");
int len = sprintf_s(path, allPathSize, "%s%u%s%s", rootPath, uid, basePath, bundleName);
APPSPAWN_CHECK(len > 0 && ((size_t)len < allPathSize), free(path); return true, "Failed to get base path");
@ -578,6 +581,7 @@ static void MountDir(AppSpawnMsgDacInfo *info, const char *bundleName, const cha
size_t allPathSize = strlen(rootPath) + strlen(targetPath) + strlen(bundleName) + 2;
allPathSize += USER_ID_SIZE;
char *path = (char *)malloc(sizeof(char) * (allPathSize));
(void)memset_s(path, allPathSize, 0, allPathSize);
APPSPAWN_CHECK(path != NULL, return, "Failed to malloc path");
int len = sprintf_s(path, allPathSize, "%s%u/%s%s", rootPath, info->uid / userIdBase, bundleName, targetPath);
APPSPAWN_CHECK(len > 0 && ((size_t)len < allPathSize), free(path);
@ -596,12 +600,11 @@ static void MountDir(AppSpawnMsgDacInfo *info, const char *bundleName, const cha
}
if (mount(NULL, path, NULL, MS_SHARED, NULL) != 0) {
APPSPAWN_LOGI("mount path %{public}s to shared failed, errno %{public}d", path, errno);
free(path);
return;
} else {
APPSPAWN_LOGI("mount path %{public}s to shared success", path);
}
APPSPAWN_LOGI("mount path %{public}s to shared success", path);
free(path);
return;
}
static const MountSharedTemplate MOUNT_SHARED_MAP[] = {
@ -756,7 +759,7 @@ static int SetExpandSandboxConfig(const SandboxContext *context, const AppSpawnS
AppSpawnMsgDomainInfo *msgDomainInfo = (AppSpawnMsgDomainInfo *)GetSpawningMsgInfo(context, TLV_DOMAIN_INFO);
if (msgDomainInfo != NULL) {
mountDestBundlePath = (strcmp(msgDomainInfo->apl, APL_SYSTEM_BASIC) == 0) ||
(strcmp(msgDomainInfo->apl, APL_SYSTEM_CORE) == 0);
(strcmp(msgDomainInfo->apl, APL_SYSTEM_CORE) == 0);
}
if (mountDestBundlePath || (CheckSpawningMsgFlagSet(context, APP_FLAGS_ACCESS_BUNDLE_DIR) != 0)) {
// need permission check for system app here
@ -1009,7 +1012,6 @@ static bool IsADFPermission(AppSpawnSandboxCfg *sandbox, const AppSpawningCtx *p
if (index > 0 && CheckAppPermissionFlagSet(property, index)) {
return true;
}
if (GetBundleName(property) != NULL && strstr(GetBundleName(property), "com.ohos.dlpmanager") != NULL) {
return true;
}

View File

@ -166,7 +166,9 @@ static int SetOverlayAppPath(const char *hapPath, void *context)
APPSPAWN_LOGV("SetOverlayAppPath path: '%{public}s' => '%{public}s'",
sandboxContext->buffer[0].buffer, sandboxContext->buffer[1].buffer);
(void)MakeDirRec(sandboxContext->buffer[1].buffer, FILE_MODE, 1);
ret = MakeDirRec(sandboxContext->buffer[1].buffer, FILE_MODE, 1);
APPSPAWN_CHECK(ret == 0, return ret, "Fail to mkdir dir %{public}s, ret :%{public}d",
sandboxContext->buffer[1].buffer, ret);
MountArg mountArg = {
sandboxContext->buffer[0].buffer, sandboxContext->buffer[1].buffer, NULL, MS_REC | MS_BIND, NULL, MS_SHARED
};

View File

@ -1599,7 +1599,7 @@ int32_t SandboxUtils::SetPermissionWithParam(AppSpawningCtx *appProperty)
}
if (index > 0 && (fileMgrIndex > 0 && userFileIndex > 0) &&
(CheckAppPermissionFlagSet(appProperty, static_cast<uint32_t>(userFileIndex)) == 0) &&
(CheckAppPermissionFlagSet(appProperty, static_cast<uint32_t>(fileMgrIndex))== 0)) {
(CheckAppPermissionFlagSet(appProperty, static_cast<uint32_t>(fileMgrIndex)) == 0)) {
return SetAppPermissionFlags(appProperty, index);
}
return 0;

View File

@ -586,9 +586,10 @@ static char *HnpNeedUnInstallHnpVersionGet(cJSON *hnpItemArr, const char *name)
cJSON *nameItem = cJSON_GetObjectItem(hnpItem, "name");
cJSON *currentItem = cJSON_GetObjectItem(hnpItem, "current_version");
cJSON *installItem = cJSON_GetObjectItem(hnpItem, "install_version");
if ((nameItem != NULL) && (currentItem != NULL) && (installItem != NULL) && (cJSON_IsString(nameItem)) &&
(cJSON_IsString(currentItem)) && (cJSON_IsString(installItem)) &&
(strcmp(nameItem->valuestring, name) == 0) &&
if ((nameItem != NULL) && (currentItem != NULL) && (installItem != NULL) &&
(cJSON_IsString(nameItem)) && (cJSON_IsString(currentItem)) && (cJSON_IsString(installItem)) &&
(nameItem->valuestring != NULL) && (strcmp(nameItem->valuestring, name) == 0) &&
(currentItem->valuestring != NULL) && (installItem->valuestring != NULL) &&
(strcmp(currentItem->valuestring, installItem->valuestring) == 0)) {
version = strdup(currentItem->valuestring);
return version;
@ -600,6 +601,9 @@ static char *HnpNeedUnInstallHnpVersionGet(cJSON *hnpItemArr, const char *name)
char *HnpCurrentVersionGet(const char *name)
{
if (name == NULL) {
return NULL;
}
char *infoStream;
int size;
cJSON *hapItem = NULL;
@ -630,7 +634,8 @@ char *HnpCurrentVersionGet(const char *name)
cJSON *nameItem = cJSON_GetObjectItem(hnpItem, "name");
cJSON *versionItem = cJSON_GetObjectItem(hnpItem, "current_version");
if ((nameItem != NULL) && (versionItem != NULL) && (cJSON_IsString(nameItem)) &&
(cJSON_IsString(versionItem)) && (strcmp(nameItem->valuestring, name) == 0)) {
(cJSON_IsString(versionItem)) && (versionItem->valuestring != NULL) &&
(nameItem->valuestring != NULL) && (strcmp(nameItem->valuestring, name) == 0)) {
version = strdup(versionItem->valuestring);
cJSON_Delete(json);
return version;
@ -644,6 +649,9 @@ char *HnpCurrentVersionGet(const char *name)
char *HnpCurrentVersionUninstallCheck(const char *name)
{
if (name == NULL) {
return NULL;
}
char *infoStream;
int size;
cJSON *hapItem = NULL;

View File

@ -395,6 +395,7 @@ static int HnpPublicDealAfterInstall(HnpInstallInfo *hnpInfo, HnpCfgInfo *hnpCfg
}
if (version != NULL) {
free(version);
version = NULL;
}
hnpCfg->isInstall = true;
@ -863,4 +864,4 @@ int HnpCmdUnInstall(int argc, char *argv[])
#ifdef __cplusplus
}
#endif
#endif

View File

@ -226,8 +226,10 @@ int KillAndWaitStatus(pid_t pid, int sig, int *exitStatus)
APPSPAWN_LOGE("unable to kill process, pid: %{public}d ret %{public}d", pid, errno);
return -1;
}
pid_t exitPid = 0;
int retry = 0;
pid_t exitPid = 0;
while (retry * SLEEP_DURATION < EXIT_APP_TIMEOUT) {
exitPid = waitpid(pid, exitStatus, WNOHANG);
if (exitPid == pid) {
@ -399,10 +401,11 @@ void ProcessAppSpawnDumpMsg(const AppSpawnMsgNode *message)
char *ptyName = GetAppSpawnMsgExtInfo(message, "pty-name", &len);
if (ptyName != NULL) {
APPSPAWN_LOGI("Dump info to file '%{public}s'", ptyName);
char canonicalPtyPath[PATH_MAX] = {0};
char canonicalPtyPath[PATH_MAX] = { 0 };
if (realpath(ptyName, canonicalPtyPath) == NULL) {
return;
}
stream = fopen(canonicalPtyPath, "w");
SetDumpToStream(stream);
} else {

View File

@ -66,6 +66,7 @@ static void ProcessRecvMsg(AppSpawnConnection *connection, AppSpawnMsgNode *mess
static inline void SetFdCtrl(int fd, int opt)
{
int option = fcntl(fd, F_GETFD);
APPSPAWN_CHECK(option >= 0, return, "SetFdCtrl fcntl failed %{public}d, %{public}d", option, errno);
int ret = fcntl(fd, F_SETFD, (unsigned int)option | (unsigned int)opt);
if (ret < 0) {
APPSPAWN_LOGI("Set fd %{public}d option %{public}d %{public}d result: %{public}d", fd, option, opt, errno);
@ -609,6 +610,7 @@ static int AddChildWatcher(AppSpawningCtx *property)
{
uint32_t defTimeout = IsChildColdRun(property) ? COLD_CHILD_RESPONSE_TIMEOUT : WAIT_CHILD_RESPONSE_TIMEOUT;
uint32_t timeout = GetSpawnTimeout(defTimeout);
APPSPAWN_LOGI("Get Spawn timeout %{public}u", timeout);
LE_WatchInfo watchInfo = {};
watchInfo.fd = property->forkCtx.fd[0];
watchInfo.flags = WATCHER_ONCE;
@ -760,6 +762,7 @@ static void ProcessPreFork(AppSpawnContent *content, AppSpawningCtx *property)
ProcessExit(0);
return;
}
property->client.id = client.id;
property->client.flags = client.flags;
property->isPrefork = true;
@ -826,6 +829,7 @@ static bool IsSupportPrefork(AppSpawnContent *content, AppSpawnClient *client)
return false;
}
if (!content->enablePerfork) {
APPSPAWN_LOGV("g_enablePrefork %{public}d", content->enablePerfork);
return false;
}
AppSpawningCtx *property = (AppSpawningCtx *)client;
@ -838,7 +842,7 @@ static bool IsSupportPrefork(AppSpawnContent *content, AppSpawnClient *client)
return false;
}
static bool IsBootFinished()
static bool IsBootFinished(void)
{
char buffer[32] = {0}; // 32 max
int ret = GetParameter("bootevent.boot.completed", "false", buffer, sizeof(buffer));
@ -846,6 +850,7 @@ static bool IsBootFinished()
return isBootCompleted;
}
static int RunAppSpawnProcessMsg(AppSpawnContent *content, AppSpawnClient *client, pid_t *childPid)
{
int ret = 0;
@ -1094,7 +1099,6 @@ APPSPAWN_STATIC int AppSpawnColdStartApp(struct AppSpawnContent *content, AppSpa
APPSPAWN_CHECK(len > 0, return APPSPAWN_SYSTEM_ERROR, "Invalid to format shmId ");
len = sprintf_s(buffer[3], sizeof(buffer[3]), " %u ", property->client.id); // 3 3 index for client id
APPSPAWN_CHECK(len > 0, return APPSPAWN_SYSTEM_ERROR, "Invalid to format shmId ");
#ifndef APPSPAWN_TEST
char *mode = IsNWebSpawnMode((AppSpawnMgr *)content) ? "nweb_cold" : "app_cold";
// 2 2 index for dest path
@ -1226,11 +1230,11 @@ APPSPAWN_STATIC int AppSpawnClearEnv(AppSpawnMgr *content, AppSpawningCtx *prope
return 0;
}
static int IsEnablePerfork()
static int IsEnablePrefork(void)
{
char buffer[32] = {0};
int ret = GetParameter("persist.sys.prefork.enable", "true", buffer, sizeof(buffer));
APPSPAWN_LOGV("IsEnablePerfork result %{public}d, %{public}s", ret, buffer);
APPSPAWN_LOGV("IsEnablePrefork result %{public}d, %{public}s", ret, buffer);
return strcmp(buffer, "true") == 0;
}
@ -1254,7 +1258,7 @@ AppSpawnContent *AppSpawnCreateContent(const char *socketName, char *longProcNam
APPSPAWN_CHECK(ret == 0, AppSpawnDestroyContent(&appSpawnContent->content);
return NULL, "Failed to create server");
}
appSpawnContent->content.enablePerfork = IsEnablePerfork();
appSpawnContent->content.enablePerfork = IsEnablePrefork();
return &appSpawnContent->content;
}
@ -1490,10 +1494,14 @@ static void ProcessSpawnRestartMsg(AppSpawnConnection *connection, AppSpawnMsgNo
int fd = GetControlSocket(NWEBSPAWN_SOCKET_NAME);
APPSPAWN_CHECK(fd >= 0, return, "Get fd failed %{public}d, errno %{public}d", fd, errno);
int ret = 0;
int op = fcntl(fd, F_GETFD);
int ret = fcntl(fd, F_SETFD, (unsigned int)op & ~FD_CLOEXEC);
if (ret < 0) {
APPSPAWN_LOGE("Set fd failed %{public}d, %{public}d, ret %{public}d, errno %{public}d", fd, op, ret, errno);
APPSPAWN_CHECK_ONLY_LOG(op >= 0, "fcntl failed %{public}d", op);
if (op > 0) {
ret = fcntl(fd, F_SETFD, (unsigned int)op & ~FD_CLOEXEC);
if (ret < 0) {
APPSPAWN_LOGE("Set fd failed %{public}d, %{public}d, ret %{public}d, errno %{public}d", fd, op, ret, errno);
}
}
char *path = "/system/bin/appspawn";
@ -1641,4 +1649,4 @@ static void ProcessRecvMsg(AppSpawnConnection *connection, AppSpawnMsgNode *mess
DeleteAppSpawnMsg(message);
break;
}
}
}