From 80690b0a3a1636400302527f2bc2cae8b241c898 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Mon, 6 Jan 2025 20:48:07 +0800 Subject: [PATCH] update mount again Signed-off-by: wangfeng --- modules/sandbox/BUILD.gn | 1 + modules/sandbox/appspawn_mount_template.c | 14 +- modules/sandbox/sandbox_manager.c | 64 +-- modules/sandbox/sandbox_shared_mount.cpp | 463 ++++++++++++++++++ modules/sandbox/sandbox_shared_mount.h | 67 +++ modules/sandbox/sandbox_utils.cpp | 285 +---------- modules/sandbox/sandbox_utils.h | 5 - standard/appspawn_appmgr.c | 26 +- standard/appspawn_manager.h | 20 + standard/appspawn_msgmgr.c | 22 +- .../datagroup/test_app_info.json | 38 ++ .../unittest/app_spawn_standard_test/BUILD.gn | 11 +- util/include/appspawn_utils.h | 2 +- 13 files changed, 677 insertions(+), 341 deletions(-) create mode 100644 modules/sandbox/sandbox_shared_mount.cpp create mode 100644 modules/sandbox/sandbox_shared_mount.h create mode 100644 test/test_app_info/datagroup/test_app_info.json diff --git a/modules/sandbox/BUILD.gn b/modules/sandbox/BUILD.gn index 279ffdb0..5a7d2d2c 100644 --- a/modules/sandbox/BUILD.gn +++ b/modules/sandbox/BUILD.gn @@ -78,6 +78,7 @@ if (defined(appspawn_sandbox_new) && appspawn_sandbox_new) { sources = [ "${appspawn_innerkits_path}/permission/appspawn_mount_permission.c", "appspawn_permission.c", + "sandbox_shared_mount.cpp", "sandbox_utils.cpp", ] diff --git a/modules/sandbox/appspawn_mount_template.c b/modules/sandbox/appspawn_mount_template.c index eb889e5f..49c6f2b9 100644 --- a/modules/sandbox/appspawn_mount_template.c +++ b/modules/sandbox/appspawn_mount_template.c @@ -160,7 +160,7 @@ static void DumpMode(const char *info, mode_t mode) APPSPAWN_CHECK_ONLY_EXPER(info != NULL, return); char buffer[64] = {0}; // 64 to show flags DumpSandboxFlags(buffer, sizeof(buffer), mode, PATH_MODE_MAP, ARRAY_LENGTH(PATH_MODE_MAP)); - APPSPAPWN_DUMP("%{public}s[0x%{public}x] %{public}s", info, (uint32_t)(mode), buffer); + APPSPAWN_DUMP("%{public}s[0x%{public}x] %{public}s", info, (uint32_t)(mode), buffer); } static void DumpMountFlags(const char *info, unsigned long mountFlags) @@ -168,7 +168,7 @@ static void DumpMountFlags(const char *info, unsigned long mountFlags) APPSPAWN_CHECK_ONLY_EXPER(info != NULL, return); char buffer[128] = {0}; // 64 to show flags DumpSandboxFlags(buffer, sizeof(buffer), mountFlags, MOUNT_FLAGS_MAP, ARRAY_LENGTH(MOUNT_FLAGS_MAP)); - APPSPAPWN_DUMP("%{public}s[0x%{public}x] %{public}s", info, (uint32_t)(mountFlags), buffer); + APPSPAWN_DUMP("%{public}s[0x%{public}x] %{public}s", info, (uint32_t)(mountFlags), buffer); } void DumpMountPathMountNode(const PathMountNode *pathNode) @@ -177,13 +177,13 @@ void DumpMountPathMountNode(const PathMountNode *pathNode) if (tmp == NULL) { return; } - APPSPAPWN_DUMP(" sandbox node category: %{public}u(%{public}s)", tmp->category, tmp->name); + APPSPAWN_DUMP(" sandbox node category: %{public}u(%{public}s)", tmp->category, tmp->name); DumpMountFlags(" sandbox node mountFlags: ", tmp->mountFlags); - APPSPAPWN_DUMP(" sandbox node mountSharedFlag: %{public}s", + APPSPAWN_DUMP(" sandbox node mountSharedFlag: %{public}s", tmp->mountSharedFlag == MS_SLAVE ? "MS_SLAVE" : "MS_SHARED"); - APPSPAPWN_DUMP(" sandbox node options: %{public}s", tmp->options ? tmp->options : "null"); - APPSPAPWN_DUMP(" sandbox node fsType: %{public}s", tmp->fsType ? tmp->fsType : "null"); + APPSPAWN_DUMP(" sandbox node options: %{public}s", tmp->options ? tmp->options : "null"); + APPSPAWN_DUMP(" sandbox node fsType: %{public}s", tmp->fsType ? tmp->fsType : "null"); DumpMode(" sandbox node destMode: ", pathNode->destMode); - APPSPAPWN_DUMP(" sandbox node config mountSharedFlag: %{public}s", + APPSPAWN_DUMP(" sandbox node config mountSharedFlag: %{public}s", pathNode->mountSharedFlag ? "MS_SHARED" : "MS_SLAVE"); } \ No newline at end of file diff --git a/modules/sandbox/sandbox_manager.c b/modules/sandbox/sandbox_manager.c index bf2f2970..80e0fd1f 100644 --- a/modules/sandbox/sandbox_manager.c +++ b/modules/sandbox/sandbox_manager.c @@ -165,24 +165,24 @@ void DumpSandboxMountNode(const SandboxMountNode *sandboxNode, uint32_t index) case SANDBOX_TAG_MOUNT_PATH: case SANDBOX_TAG_MOUNT_FILE: { PathMountNode *pathNode = (PathMountNode *)sandboxNode; - APPSPAPWN_DUMP(" ****************************** %{public}u", index); - APPSPAPWN_DUMP(" sandbox node source: %{public}s", pathNode->source ? pathNode->source : "null"); - APPSPAPWN_DUMP(" sandbox node target: %{public}s", pathNode->target ? pathNode->target : "null"); + APPSPAWN_DUMP(" ****************************** %{public}u", index); + APPSPAWN_DUMP(" sandbox node source: %{public}s", pathNode->source ? pathNode->source : "null"); + APPSPAWN_DUMP(" sandbox node target: %{public}s", pathNode->target ? pathNode->target : "null"); DumpMountPathMountNode(pathNode); - APPSPAPWN_DUMP(" sandbox node apl: %{public}s", + APPSPAWN_DUMP(" sandbox node apl: %{public}s", pathNode->appAplName ? pathNode->appAplName : "null"); - APPSPAPWN_DUMP(" sandbox node checkErrorFlag: %{public}s", + APPSPAWN_DUMP(" sandbox node checkErrorFlag: %{public}s", pathNode->checkErrorFlag ? "true" : "false"); break; } case SANDBOX_TAG_SYMLINK: { SymbolLinkNode *linkNode = (SymbolLinkNode *)sandboxNode; - APPSPAPWN_DUMP(" ***********************************"); - APPSPAPWN_DUMP(" sandbox node target: %{public}s", linkNode->target ? linkNode->target : "null"); - APPSPAPWN_DUMP(" sandbox node linkName: %{public}s", + APPSPAWN_DUMP(" ***********************************"); + APPSPAWN_DUMP(" sandbox node target: %{public}s", linkNode->target ? linkNode->target : "null"); + APPSPAWN_DUMP(" sandbox node linkName: %{public}s", linkNode->linkName ? linkNode->linkName : "null"); - APPSPAPWN_DUMP(" sandbox node destMode: %{public}x", linkNode->destMode); - APPSPAPWN_DUMP(" sandbox node checkErrorFlag: %{public}s", + APPSPAWN_DUMP(" sandbox node destMode: %{public}x", linkNode->destMode); + APPSPAWN_DUMP(" sandbox node checkErrorFlag: %{public}s", linkNode->checkErrorFlag ? "true" : "false"); break; } @@ -255,20 +255,20 @@ static void DumpSandboxQueue(const ListNode *front, static void DumpSandboxSection(const SandboxSection *section) { - APPSPAPWN_DUMP(" sandboxSwitch %{public}s", section->sandboxSwitch ? "true" : "false"); - APPSPAPWN_DUMP(" sandboxShared %{public}s", section->sandboxShared ? "true" : "false"); - APPSPAPWN_DUMP(" gidCount: %{public}u", section->gidCount); + APPSPAWN_DUMP(" sandboxSwitch %{public}s", section->sandboxSwitch ? "true" : "false"); + APPSPAWN_DUMP(" sandboxShared %{public}s", section->sandboxShared ? "true" : "false"); + APPSPAWN_DUMP(" gidCount: %{public}u", section->gidCount); for (uint32_t index = 0; index < section->gidCount; index++) { - APPSPAPWN_DUMP(" gidTable[%{public}u]: %{public}u", index, section->gidTable[index]); + APPSPAWN_DUMP(" gidTable[%{public}u]: %{public}u", index, section->gidTable[index]); } - APPSPAPWN_DUMP(" mount group count: %{public}u", section->number); + APPSPAWN_DUMP(" mount group count: %{public}u", section->number); for (uint32_t i = 0; i < section->number; i++) { if (section->nameGroups[i]) { SandboxNameGroupNode *groupNode = (SandboxNameGroupNode *)section->nameGroups[i]; - APPSPAPWN_DUMP(" name[%{public}d] %{public}s", i, groupNode->section.name); + APPSPAWN_DUMP(" name[%{public}d] %{public}s", i, groupNode->section.name); } } - APPSPAPWN_DUMP(" mount-paths: "); + APPSPAWN_DUMP(" mount-paths: "); DumpSandboxQueue(§ion->front, DumpSandboxMountNode); } @@ -385,29 +385,29 @@ void DeleteAppSpawnSandbox(AppSpawnSandboxCfg *sandbox) static void DumpSandboxPermission(const SandboxMountNode *node, uint32_t index) { SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)node; - APPSPAPWN_DUMP(" ========================================= "); - APPSPAPWN_DUMP(" Section %{public}s", permissionNode->section.name); - APPSPAPWN_DUMP(" Section permission index %{public}d", permissionNode->permissionIndex); + APPSPAWN_DUMP(" ========================================= "); + APPSPAWN_DUMP(" Section %{public}s", permissionNode->section.name); + APPSPAWN_DUMP(" Section permission index %{public}d", permissionNode->permissionIndex); DumpSandboxSection(&permissionNode->section); } static void DumpSandboxSectionNode(const SandboxMountNode *node, uint32_t index) { SandboxSection *section = (SandboxSection *)node; - APPSPAPWN_DUMP(" ========================================= "); - APPSPAPWN_DUMP(" Section %{public}s", section->name); + APPSPAWN_DUMP(" ========================================= "); + APPSPAWN_DUMP(" Section %{public}s", section->name); DumpSandboxSection(section); } static void DumpSandboxNameGroupNode(const SandboxMountNode *node, uint32_t index) { SandboxNameGroupNode *nameGroupNode = (SandboxNameGroupNode *)node; - APPSPAPWN_DUMP(" ========================================= "); - APPSPAPWN_DUMP(" Section %{public}s", nameGroupNode->section.name); - APPSPAPWN_DUMP(" Section dep mode %{public}s", + APPSPAWN_DUMP(" ========================================= "); + APPSPAWN_DUMP(" Section %{public}s", nameGroupNode->section.name); + APPSPAWN_DUMP(" Section dep mode %{public}s", nameGroupNode->depMode == MOUNT_MODE_ALWAYS ? "always" : "not-exists"); if (nameGroupNode->depNode != NULL) { - APPSPAPWN_DUMP(" mount-paths-deps: "); + APPSPAWN_DUMP(" mount-paths-deps: "); DumpMountPathMountNode(nameGroupNode->depNode); } DumpSandboxSection(&nameGroupNode->section); @@ -469,12 +469,12 @@ AppSpawnSandboxCfg *CreateAppSpawnSandbox(ExtDataType type) void DumpAppSpawnSandboxCfg(AppSpawnSandboxCfg *sandbox) { APPSPAWN_CHECK_ONLY_EXPER(sandbox != NULL, return); - APPSPAPWN_DUMP("Sandbox root path: %{public}s", sandbox->rootPath); - APPSPAPWN_DUMP("Sandbox sandboxNsFlags: %{public}x ", sandbox->sandboxNsFlags); - APPSPAPWN_DUMP("Sandbox topSandboxSwitch: %{public}s", sandbox->topSandboxSwitch ? "true" : "false"); - APPSPAPWN_DUMP("Sandbox appFullMountEnable: %{public}s", sandbox->appFullMountEnable ? "true" : "false"); - APPSPAPWN_DUMP("Sandbox pidNamespaceSupport: %{public}s", sandbox->pidNamespaceSupport ? "true" : "false"); - APPSPAPWN_DUMP("Sandbox common info: "); + APPSPAWN_DUMP("Sandbox root path: %{public}s", sandbox->rootPath); + APPSPAWN_DUMP("Sandbox sandboxNsFlags: %{public}x ", sandbox->sandboxNsFlags); + APPSPAWN_DUMP("Sandbox topSandboxSwitch: %{public}s", sandbox->topSandboxSwitch ? "true" : "false"); + APPSPAWN_DUMP("Sandbox appFullMountEnable: %{public}s", sandbox->appFullMountEnable ? "true" : "false"); + APPSPAWN_DUMP("Sandbox pidNamespaceSupport: %{public}s", sandbox->pidNamespaceSupport ? "true" : "false"); + APPSPAWN_DUMP("Sandbox common info: "); DumpSandboxQueue(&sandbox->requiredQueue.front, DumpSandboxSectionNode); DumpSandboxQueue(&sandbox->packageNameQueue.front, DumpSandboxSectionNode); DumpSandboxQueue(&sandbox->permissionQueue.front, DumpSandboxPermission); diff --git a/modules/sandbox/sandbox_shared_mount.cpp b/modules/sandbox/sandbox_shared_mount.cpp new file mode 100644 index 00000000..f5e3bd85 --- /dev/null +++ b/modules/sandbox/sandbox_shared_mount.cpp @@ -0,0 +1,463 @@ +/* + * Copyright (C) 2025 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include "nlohmann/json.hpp" + +#include "sandbox_shared_mount.h" +#include "appspawn_mount_permission.h" +#include "appspawn_utils.h" +#include "parameter.h" + +#define USER_ID_SIZE 16 +#define DIR_MODE 0711 +#define LOCK_STATUS_SIZE 16 + +#define DATA_GROUP_SOCKET_TYPE "DataGroup" +#define GROUPLIST_KEY_DATAGROUPID "dataGroupId" +#define GROUPLIST_KEY_GID "gid" +#define GROUPLIST_KEY_DIR "dir" +#define GROUPLIST_KEY_UUID "uuid" + +static const MountSharedTemplate MOUNT_SHARED_MAP[] = { + {"/data/storage/el2", nullptr}, + {"/data/storage/el3", nullptr}, + {"/data/storage/el4", nullptr}, + {"/data/storage/el5", "ohos.permission.PROTECT_SCREEN_LOCK_DATA"}, +}; + +static const DataGroupSandboxPathTemplate DATA_GROUP_SANDBOX_PATH_MAP[] = { + {"el2", EL2, "/data/storage/el2/group/", nullptr}, + {"el3", EL3, "/data/storage/el3/group/", nullptr}, + {"el4", EL4, "/data/storage/el4/group/", nullptr}, + {"el5", EL5, "/data/storage/el5/group/", "ohos.permission.PROTECT_SCREEN_LOCK_DATA"}, +}; + +static std::map g_mountInfoMap; + +int GetElxInfoFromDir(const char *path) +{ + int ret = ELX_MAX; + if (path == nullptr) { + return ret; + } + uint32_t count = ARRAY_LENGTH(DATA_GROUP_SANDBOX_PATH_MAP); + for (uint32_t i = 0; i < count; ++i) { + if (strstr(path, DATA_GROUP_SANDBOX_PATH_MAP[i].elxName) != nullptr) { + return DATA_GROUP_SANDBOX_PATH_MAP[i].category; + } + } + if (ret == 0) { + APPSPAWN_LOGE("Get elx info from dir failed, path %{public}s", path); + } + return ret; +} + +const DataGroupSandboxPathTemplate *GetDataGroupArgTemplate(uint32_t category) +{ + uint32_t count = ARRAY_LENGTH(DATA_GROUP_SANDBOX_PATH_MAP); + if (category > count) { + APPSPAWN_LOGE("category %{public}d is out of range", category); + return nullptr; + } + for (uint32_t i = 0; i < count; ++i) { + if (DATA_GROUP_SANDBOX_PATH_MAP[i].category == category) { + return &DATA_GROUP_SANDBOX_PATH_MAP[i]; + } + } + return nullptr; +} + +bool IsValidDataGroupItem(nlohmann::json &item) +{ + // Check if the item contains the specified key and if the value corresponding to the key is a string + if (item.contains(GROUPLIST_KEY_DATAGROUPID) && item[GROUPLIST_KEY_DATAGROUPID].is_string() && + item.contains(GROUPLIST_KEY_GID) && item[GROUPLIST_KEY_GID].is_string() && + item.contains(GROUPLIST_KEY_DIR) && item[GROUPLIST_KEY_DIR].is_string() && + item.contains(GROUPLIST_KEY_UUID) && item[GROUPLIST_KEY_UUID].is_string()) { + return true; + } + return false; +} + +void *GetEl1BundleMountCount(void) +{ + return static_cast(&g_mountInfoMap); +} + +#ifndef APPSPAWN_SANDBOX_NEW +static bool IsUnlockStatus(uint32_t uid) +{ + const int userIdBase = UID_BASE; + uid = uid / userIdBase; + if (uid == 0) { + return true; + } + std::string lockStatusParam = "startup.appspawn.lockstatus_" + std::to_string(uid); + char userLockStatus[LOCK_STATUS_SIZE] = {0}; + int ret = GetParameter(lockStatusParam.c_str(), "1", userLockStatus, sizeof(userLockStatus)); + APPSPAWN_LOGI("get param %{public}s %{public}s", lockStatusParam.c_str(), userLockStatus); + if (ret > 0 && (strcmp(userLockStatus, "0") == 0)) { // 0:unlock status 1:lock status + return true; + } + return false; +} + +static int DoSharedMount(const SharedMountArgs *arg) +{ + if (arg == nullptr || arg->srcPath == nullptr || arg->destPath == nullptr) { + APPSPAWN_LOGE("Invalid arg"); + return APPSPAWN_ARG_INVALID; + } + + APPSPAWN_LOGV("Mount arg: '%{public}s' '%{public}s' %{public}lu '%{public}s' %{public}s => %{public}s", + arg->fsType, arg->mountSharedFlag == MS_SHARED ? "MS_SHARED" : "MS_SLAVE", + arg->mountFlags, arg->options, arg->srcPath, arg->destPath); + + int ret = mount(arg->srcPath, arg->destPath, arg->fsType, arg->mountFlags, arg->options); + if (ret != 0) { + APPSPAWN_LOGE("mount %{public}s to %{public}s failed, errno %{public}d", + arg->srcPath, arg->destPath, errno); + return ret; + } + ret = mount(nullptr, arg->destPath, nullptr, arg->mountSharedFlag, nullptr); + if (ret != 0) { + APPSPAWN_LOGE("mount path %{public}s to shared failed, errno %{public}d", arg->destPath, errno); + return ret; + } + APPSPAWN_LOGI("mount path %{public}s to shared success", arg->destPath); + return 0; +} + +static void GetMountInfo(std::vector &sharedMounts, AppDacInfo *info, const std::string &bundleName) +{ + APPSPAWN_LOGI("Get mountinfo %{public}s start", bundleName.c_str()); + std::ifstream file("/proc/self/mountinfo"); + if (!file.is_open()) { + APPSPAWN_LOGE("Failed to open mountinfo, errno: %{public}d", errno); + return; + } + + std::string line; + while (std::getline(file, line)) { + if ((line.find(info->uid / UID_BASE) != std::string::npos) && (line.find(bundleName) != std::string::npos) && + (line.find("shared:") != std::string::npos)) { + sharedMounts.push_back(line); + } + } + file.close(); + APPSPAWN_LOGW("Get mountinfo %{public}s end", bundleName.c_str()); +} + +static bool IsSandboxPathShared(const std::vector &sharedMounts, const std::string &sandboxPath) +{ + std::regex mountPoint(sandboxPath); + for (const auto &sharedMount : sharedMounts) { + if (std::regex_search(sharedMount, mountPoint)) { + return true; + } + } + return false; +} + +static int MountEl1Bundle(const AppSpawningCtx *property, const AppDacInfo *info, const char *bundleName) +{ + /* /data/app/el1/bundle/public/ */ + char sourcePath[PATH_MAX_LEN] = {0}; + int ret = snprintf_s(sourcePath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "/data/app/el1/bundle/public/%s", bundleName); + if (ret <= 0) { + APPSPAWN_LOGE("snprintf data/app/el1/bundle/public/%{public}s failed, errno %{public}d", bundleName, errno); + return APPSPAWN_ERROR_UTILS_MEM_FAIL; + } + + /* /mnt/sandbox///data/storage/el1/bundle */ + char targetPath[PATH_MAX_LEN] = {0}; + ret = snprintf_s(targetPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "/mnt/sandbox/%d/%s/data/storage/el1/bundle", + info->uid/ UID_BASE, bundleName); + if (ret <= 0) { + APPSPAWN_LOGE("snprintf el1 bundle sandbox path failed, errno %{public}d", errno); + return APPSPAWN_ERROR_UTILS_MEM_FAIL; + } + + ret = MakeDirRec(targetPath, DIR_MODE, 1); + if (ret != 0) { + APPSPAWN_LOGE("mkdir %{public}s failed, errno %{public}d", targetPath, errno); + return APPSPAWN_SANDBOX_ERROR_MKDIR_FAIL; + } + + ret = umount2(targetPath, MNT_DETACH); + if (ret < 0) { + APPSPAWN_LOGE("umount2 %{public}s failed, errno %{public}d", targetPath, errno); + } + + SharedMountArgs arg = { + .srcPath = sourcePath, + .destPath = targetPath, + .fsType = nullptr, + .mountFlags = MS_BIND | MS_REC, + .options = nullptr, + .mountSharedFlag = MS_SHARED + }; + ret = DoSharedMount(&arg); + if (ret != 0) { + APPSPAWN_LOGE("mount %{public}s shared failed, ret %{public}d", targetPath, ret); + } + std::string key = std::to_string(info->uid / UID_BASE) + "-" + std::string(bundleName); + g_mountInfoMap[key]++; + return ret; +} + +static int MountWithFileMgr(const AppSpawningCtx *property, const AppDacInfo *info, const char *bundleName, + std::vector &sharedMounts) +{ + /* /mnt/user//nosharefs/docs */ + char nosharefsDocsDir[PATH_MAX_LEN] = {0}; + int ret = snprintf_s(nosharefsDocsDir, PATH_MAX_LEN, PATH_MAX_LEN - 1, "/mnt/user/%u/nosharefs/docs", + info->uid / UID_BASE); + if (ret <= 0) { + APPSPAWN_LOGE("snprintf nosharefsDocsDir failed, errno %{public}d", errno); + return APPSPAWN_ERROR_UTILS_MEM_FAIL; + } + + /* /mnt/sandbox//storage/Users */ + char storageUserPath[PATH_MAX_LEN] = {0}; + ret = snprintf_s(storageUserPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "/mnt/sandbox/%d/%s/storage/Users", + info->uid / UID_BASE, bundleName); + if (ret <= 0) { + APPSPAWN_LOGE("snprintf nosharefsDocsDir failed, errno %{public}d", errno); + return APPSPAWN_ERROR_UTILS_MEM_FAIL; + } + + // Check whether the directory is a shared mount point + if (IsSandboxPathShared(sharedMounts, storageUserPath)) { + APPSPAWN_LOGI("shared mountpoint is exist"); + return 0; + } + + ret = MakeDirRec(storageUserPath, DIR_MODE, 1); + if (ret != 0) { + APPSPAWN_LOGE("mkdir %{public}s failed, errno %{public}d", storageUserPath, errno); + return APPSPAWN_SANDBOX_ERROR_MKDIR_FAIL; + } + + SharedMountArgs arg = { + .srcPath = nosharefsDocsDir, + .destPath = storageUserPath, + .fsType = nullptr, + .mountFlags = MS_BIND | MS_REC, + .options = nullptr, + .mountSharedFlag = MS_SHARED + }; + ret = DoSharedMount(&arg); + if (ret != 0) { + APPSPAWN_LOGE("mount %{public}s shared failed, ret %{public}d", storageUserPath, ret); + } + return ret; +} + +static int MountWithOther(const AppSpawningCtx *property, const AppDacInfo *info, const char *bundleName, + std::vector &sharedMounts) +{ + /* /mnt/user//sharefs/docs */ + char sharefsDocsDir[PATH_MAX_LEN] = {0}; + int ret = snprintf_s(sharefsDocsDir, PATH_MAX_LEN, PATH_MAX_LEN - 1, "/mnt/user/%u/sharefs/docs", + info->uid / UID_BASE); + if (ret <= 0) { + APPSPAWN_LOGE("snprintf sharefsDocsDir failed, errno %{public}d", errno); + return APPSPAWN_ERROR_UTILS_MEM_FAIL; + } + + /* /mnt/sandbox//storage/Users */ + char storageUserPath[PATH_MAX_LEN] = {0}; + ret = snprintf_s(storageUserPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "/mnt/sandbox/%d/%s/storage/Users", + info->uid / UID_BASE, bundleName); + if (ret <= 0) { + APPSPAWN_LOGE("snprintf nosharefsDocsDir failed, errno %{public}d", errno); + return APPSPAWN_ERROR_UTILS_MEM_FAIL; + } + + // Check whether the directory is a shared mount point + if (IsSandboxPathShared(sharedMounts, storageUserPath)) { + APPSPAWN_LOGI("shared mountpoint is exist"); + return 0; + } + + ret = MakeDirRec(storageUserPath, DIR_MODE, 1); + if (ret != 0) { + APPSPAWN_LOGE("mkdir %{public}s failed, errno %{public}d", storageUserPath, errno); + return APPSPAWN_SANDBOX_ERROR_MKDIR_FAIL; + } + + char options[PATH_MAX_LEN] = {0}; + ret = snprintf_s(options, PATH_MAX_LEN, PATH_MAX_LEN - 1, "override_support_delete,user_id=%u", + info->uid / UID_BASE); + if (ret <= 0) { + APPSPAWN_LOGE("snprintf options failed, errno %{public}d", errno); + return APPSPAWN_ERROR_UTILS_MEM_FAIL; + } + + SharedMountArgs arg = { + .srcPath = sharefsDocsDir, + .destPath = storageUserPath, + .fsType = "sharefs", + .mountFlags = MS_NODEV, + .options = options, + .mountSharedFlag = MS_SHARED + }; + ret = DoSharedMount(&arg); + if (ret != 0) { + APPSPAWN_LOGE("mount %{public}s shared failed, ret %{public}d", storageUserPath, ret); + } + return ret; +} + +static void MountStorageUsers(const AppSpawningCtx *property, const AppDacInfo *info, const char *bundleName, + std::vector &sharedMounts) +{ + int ret = 0; + int index = GetPermissionIndex(nullptr, "ohos.permission.FILE_ACCESS_MANAGER"); + int checkRes = CheckAppPermissionFlagSet(property, static_cast(index)); + if (checkRes == 0) { + /* mount /mnt/user//sharefs/docs to /mnt/sandbox///storage/Users */ + ret = MountWithOther(property, info, bundleName, sharedMounts); + } else { + /* mount /mnt/user//nosharefs/docs to /mnt/sandbox///storage/Users */ + ret = MountWithFileMgr(property, info, bundleName, sharedMounts); + } + if (ret != 0) { + APPSPAWN_LOGE("Update %{public}s storage dir failed, ret %{public}d", + checkRes == 0 ? "sharefs dir" : "no sharefs dir", ret); + } else { + APPSPAWN_LOGI("Update %{public}s storage dir success", checkRes == 0 ? "sharefs dir" : "no sharefs dir"); + } +} + +static int MountSharedMapItem(const AppSpawningCtx *property, const AppDacInfo *info, const char *bundleName, + const char *sandboxPathItem, std::vector &sharedMounts) +{ + /* /mnt/sandbox///data/storage/el */ + char sandboxPath[PATH_MAX_LEN] = {0}; + int ret = snprintf_s(sandboxPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "/mnt/sandbox/%d/%s%s", + info->uid / UID_BASE, bundleName, sandboxPathItem); + if (ret <= 0) { + APPSPAWN_LOGE("snprintf sandboxPath failed, errno %{public}d", errno); + return APPSPAWN_ERROR_UTILS_MEM_FAIL; + } + + // Check whether the directory is a shared mount point + if (IsSandboxPathShared(sharedMounts, sandboxPath)) { + APPSPAWN_LOGI("shared mountpoint is exist"); + return 0; + } + + ret = MakeDirRec(sandboxPath, DIR_MODE, 1); + if (ret != 0) { + APPSPAWN_LOGE("mkdir %{public}s failed, errno %{public}d", sandboxPath, errno); + return APPSPAWN_SANDBOX_ERROR_MKDIR_FAIL; + } + + SharedMountArgs arg = { + .srcPath = sandboxPath, + .destPath = sandboxPath, + .fsType = nullptr, + .mountFlags = MS_BIND | MS_REC, + .options = nullptr, + .mountSharedFlag = MS_SHARED + }; + ret = DoSharedMount(&arg); + if (ret != 0) { + APPSPAWN_LOGE("mount %{public}s shared failed, ret %{public}d", sandboxPath, ret); + } + return ret; +} + +static void MountSharedMap(const AppSpawningCtx *property, const AppDacInfo *info, const char *bundleName, + std::vector &sharedMounts) +{ + int length = sizeof(MOUNT_SHARED_MAP) / sizeof(MOUNT_SHARED_MAP[0]); + for (int i = 0; i < length; i++) { + if (MOUNT_SHARED_MAP[i].permission == nullptr) { + MountSharedMapItem(property, info, bundleName, MOUNT_SHARED_MAP[i].sandboxPath, sharedMounts); + } else { + int index = GetPermissionIndex(nullptr, MOUNT_SHARED_MAP[i].permission); + APPSPAWN_LOGV("mount dir on lock mountPermissionFlags %{public}d", index); + if (CheckAppPermissionFlagSet(property, static_cast(index))) { + MountSharedMapItem(property, info, bundleName, MOUNT_SHARED_MAP[i].sandboxPath, sharedMounts); + } + } + } + APPSPAWN_LOGI("mount shared map success"); +} + +static void MountDirToShared(AppSpawnMgr *content, const AppSpawningCtx *property) +{ + if (property == nullptr) { + return; + } + + AppDacInfo *info = reinterpret_cast(GetAppProperty(property, TLV_DAC_INFO)); + AppSpawnMsgBundleInfo *bundleInfo = + reinterpret_cast(GetAppProperty(property, TLV_BUNDLE_INFO)); + if (info == NULL || bundleInfo == NULL) { + return; + } + + MountEl1Bundle(property, info, bundleInfo->bundleName); + + if (IsUnlockStatus(info->uid)) { + return; + } + + struct timespec checkStart = {0}; + clock_gettime(CLOCK_MONOTONIC, &checkStart); + + std::vector sharedMounts; + GetMountInfo(sharedMounts, info, std::string(bundleInfo->bundleName)); + MountSharedMap(property, info, bundleInfo->bundleName, sharedMounts); + MountStorageUsers(property, info, bundleInfo->bundleName, sharedMounts); + + struct timespec checkEnd = {0}; + clock_gettime(CLOCK_MONOTONIC, &checkEnd); + uint64_t diff = DiffTime(&checkStart, &checkEnd); + APPSPAWN_LOGI("Check %{public}s mount status use time %{public}" PRId64" us", bundleInfo->bundleName, diff); + + std::string lockSbxPathStamp = "/mnt/sandbox/" + std::to_string(info->uid / UID_BASE) + "/"; + lockSbxPathStamp += CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? "isolated/" : ""; + lockSbxPathStamp += bundleInfo->bundleName; + lockSbxPathStamp += "_locked"; + int ret = MakeDirRec(lockSbxPathStamp.c_str(), DIR_MODE, 1); + if (ret != 0) { + APPSPAWN_LOGE("mkdir %{public}s failed, errno %{public}d", lockSbxPathStamp.c_str(), errno); + } +} +#endif + +int MountToShared(AppSpawnMgr *content, const AppSpawningCtx *property) +{ +#ifndef APPSPAWN_SANDBOX_NEW + // mount dynamic directory to shared + MountDirToShared(content, property); +#endif + return 0; +} diff --git a/modules/sandbox/sandbox_shared_mount.h b/modules/sandbox/sandbox_shared_mount.h new file mode 100644 index 00000000..7bdd28de --- /dev/null +++ b/modules/sandbox/sandbox_shared_mount.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2025 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SANDBOX_SHARED_MOUNT_H +#define SANDBOX_SHARED_MOUNT_H + +#include "appspawn.h" +#include "appspawn_hook.h" +#include "appspawn_manager.h" +#include "appspawn_utils.h" +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct MountSharedTemplate { + const char *sandboxPath; + const char *permission; +} MountSharedTemplate; + +enum { + EL2 = 0, + EL3, + EL4, + EL5, + ELX_MAX +}; + +typedef struct DataGroupSandboxPathTemplate { + const char *elxName; + uint32_t category; + const char *sandboxPath;; + const char *permission; +} DataGroupSandboxPathTemplate; + +typedef struct { + const char *srcPath; + const char *destPath; + const char *fsType; + unsigned long mountFlags; + const char *options; + mode_t mountSharedFlag; +} SharedMountArgs; + +bool IsValidDataGroupItem(nlohmann::json &item); +int GetElxInfoFromDir(const char *path); +const DataGroupSandboxPathTemplate *GetDataGroupArgTemplate(uint32_t category); +void *GetEl1BundleMountCount(void); +int MountToShared(AppSpawnMgr *content, const AppSpawningCtx *property); + +#ifdef __cplusplus +} +#endif +#endif // SANDBOX_SHARED_MOUNT_H diff --git a/modules/sandbox/sandbox_utils.cpp b/modules/sandbox/sandbox_utils.cpp index 6d198746..00ecd090 100644 --- a/modules/sandbox/sandbox_utils.cpp +++ b/modules/sandbox/sandbox_utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2024-2025 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 @@ -35,6 +35,7 @@ #include "appspawn_service.h" #include "appspawn_utils.h" #include "config_policy_utils.h" +#include "sandbox_shared_mount.h" #ifdef WITH_DLP #include "dlp_fuse_fd.h" #endif @@ -61,8 +62,6 @@ using namespace std; using namespace OHOS; -static map g_mountInfo; - namespace OHOS { namespace AppSpawn { namespace { @@ -1893,7 +1892,8 @@ int32_t SetAppSandboxProperty(AppSpawnMgr *content, AppSpawningCtx *property) APPSPAWN_CHECK(property != nullptr, return -1, "Invalid appspwn client"); APPSPAWN_CHECK(content != nullptr, return -1, "Invalid appspwn content"); // clear g_mountInfo in the child process - g_mountInfo.clear(); + std::map* mapPtr = static_cast*>(GetEl1BundleMountCount()); + mapPtr->clear(); int ret = 0; // no sandbox if (CheckAppMsgFlagsSet(property, APP_FLAGS_NO_SANDBOX)) { @@ -1929,274 +1929,12 @@ int32_t SetAppSandboxProperty(AppSpawnMgr *content, AppSpawningCtx *property) #define USER_ID_SIZE 16 #define DIR_MODE 0711 -#ifndef APPSPAWN_SANDBOX_NEW -static bool IsUnlockStatus(uint32_t uid) -{ - const int userIdBase = 200000; - uid = uid / userIdBase; - if (uid == 0) { - return true; - } - string lockStatusParam = "startup.appspawn.lockstatus_" + to_string(uid); - char userLockStatus[LOCK_STATUS_SIZE] = {0}; - int ret = GetParameter(lockStatusParam.c_str(), "1", userLockStatus, sizeof(userLockStatus)); - APPSPAWN_LOGI("get param %{public}s %{public}s %{public}d", lockStatusParam.c_str(), userLockStatus, ret); - if (ret > 0 && (strcmp(userLockStatus, "0") == 0)) { // 0:unlock 1:lock - return true; - } - return false; -} - -static string GetMountInfoKey(uint32_t userId, const char *bundleName) -{ - return std::to_string(userId) + "-" + std::string(bundleName); -} - -static void MountDir(const AppSpawningCtx *property, const char *rootPath, const char *srcPath, const char *targetPath) -{ - const int userIdBase = 200000; - AppDacInfo *info = reinterpret_cast(GetAppProperty(property, TLV_DAC_INFO)); - const char *bundleName = GetBundleName(property); - if (info == NULL || bundleName == NULL) { - return; - } - - size_t allPathSize = strlen(rootPath) + strlen(targetPath) + strlen(bundleName) + 2; - allPathSize += USER_ID_SIZE; - char *path = reinterpret_cast(malloc(sizeof(char) * (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); - return, "Failed to get sandbox path"); - if (srcPath != nullptr) { - string key = GetMountInfoKey(info->uid / userIdBase, bundleName); - g_mountInfo[key]++; - } - - if (access(path, F_OK) == 0 && srcPath == nullptr) { - free(path); - return; - } - - MakeDirRec(path, DIR_MODE, 1); - const char *sourcePath = (srcPath == nullptr) ? path : srcPath; - if (srcPath != nullptr) { - int ret = umount2(path, MNT_DETACH); - APPSPAWN_CHECK_ONLY_LOG(ret == 0, "Failed to umount path %{public}s, errno %{public}d", path, errno); - } - - if (mount(sourcePath, path, nullptr, MS_BIND | MS_REC, nullptr) != 0) { - APPSPAWN_LOGI("bind mount %{public}s to %{public}s failed, error %{public}d", sourcePath, path, errno); - free(path); - return; - } - if (mount(nullptr, path, nullptr, MS_SHARED, nullptr) != 0) { - APPSPAWN_LOGI("mount path %{public}s to shared failed, errno %{public}d", path, errno); - free(path); - return; - } - APPSPAWN_LOGI("mount path %{public}s to shared success", path); - free(path); - return; -} - -static const MountSharedTemplate MOUNT_SHARED_MAP[] = { - {"/data/storage/el2", nullptr}, - {"/data/storage/el3", nullptr}, - {"/data/storage/el4", nullptr}, - {"/data/storage/el5", "ohos.permission.PROTECT_SCREEN_LOCK_DATA"}, -}; - -#define PATH_MAX_LEN 256 -static int MountInShared(const AppSpawningCtx *property, const char *rootPath, const char *src, const char *target) -{ - AppDacInfo *info = reinterpret_cast(GetAppProperty(property, TLV_DAC_INFO)); - const char *bundleName = GetBundleName(property); - if (info == NULL || bundleName == NULL) { - return APPSPAWN_ARG_INVALID; - } - - char path[PATH_MAX_LEN] = {0}; - int ret = snprintf_s(path, PATH_MAX_LEN, PATH_MAX_LEN - 1, "%s/%u/%s/%s", rootPath, info->uid / UID_BASE, - bundleName, target); - if (ret <= 0) { - APPSPAWN_LOGE("snprintf_s path failed, errno %{public}d", errno); - return APPSPAWN_ERROR_UTILS_MEM_FAIL; - } - - char currentUserPath[PATH_MAX_LEN] = {0}; - ret = snprintf_s(currentUserPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "%s/currentUser", path); - if (ret <= 0) { - APPSPAWN_LOGE("snprintf_s currentUserPath failed, errno %{public}d", errno); - return APPSPAWN_ERROR_UTILS_MEM_FAIL; - } - - if (access(currentUserPath, F_OK) == 0) { - return 0; - } - - ret = MakeDirRec(path, DIR_MODE, 1); - if (ret != 0) { - return APPSPAWN_SANDBOX_ERROR_MKDIR_FAIL; - } - - if (mount(src, path, nullptr, MS_BIND | MS_REC, nullptr) != 0) { - APPSPAWN_LOGI("bind mount %{public}s to %{public}s failed, error %{public}d", src, path, errno); - return APPSPAWN_SANDBOX_ERROR_MOUNT_FAIL; - } - if (mount(nullptr, path, nullptr, MS_SHARED, nullptr) != 0) { - APPSPAWN_LOGI("mount path %{public}s to shared failed, errno %{public}d", path, errno); - return APPSPAWN_SANDBOX_ERROR_MOUNT_FAIL; - } - - return 0; -} - -static int SharedMountInSharefs(const AppSpawningCtx *property, const char *rootPath, - const char *src, const char *target) -{ - AppDacInfo *info = reinterpret_cast(GetAppProperty(property, TLV_DAC_INFO)); - if (info == NULL) { - return APPSPAWN_ARG_INVALID; - } - - char currentUserPath[PATH_MAX_LEN] = {0}; - int ret = snprintf_s(currentUserPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "%s/currentUser", target); - if (ret <= 0) { - APPSPAWN_LOGE("snprintf_s currentUserPath failed, errno %{public}d", errno); - return APPSPAWN_ERROR_UTILS_MEM_FAIL; - } - - if (access(currentUserPath, F_OK) == 0) { - return 0; - } - - ret = MakeDirRec(target, DIR_MODE, 1); - if (ret != 0) { - return APPSPAWN_SANDBOX_ERROR_MKDIR_FAIL; - } - - char options[PATH_MAX_LEN] = {0}; - ret = snprintf_s(options, PATH_MAX_LEN, PATH_MAX_LEN - 1, "override_support_delete,user_id=%u", - info->uid / UID_BASE); - if (ret <= 0) { - APPSPAWN_LOGE("snprintf_s options failed, errno %{public}d", errno); - return APPSPAWN_ERROR_UTILS_MEM_FAIL; - } - - if (mount(src, target, "sharefs", MS_NODEV, options) != 0) { - APPSPAWN_LOGE("sharefs mount %{public}s to %{public}s failed, error %{public}d", - src, target, errno); - return APPSPAWN_SANDBOX_ERROR_MOUNT_FAIL; - } - if (mount(nullptr, target, nullptr, MS_SHARED, nullptr) != 0) { - APPSPAWN_LOGE("mount path %{public}s to shared failed, errno %{public}d", target, errno); - return APPSPAWN_SANDBOX_ERROR_MOUNT_FAIL; - } - - return 0; -} - -static void UpdateStorageDir(const AppSpawningCtx *property) -{ - const char mntUser[] = "/mnt/user"; - const char nosharefsDocs[] = "nosharefs/docs"; - const char sharefsDocs[] = "sharefs/docs"; - const char rootPath[] = "/mnt/sandbox"; - const char userPath[] = "/storage/Users"; - - AppDacInfo *info = reinterpret_cast(GetAppProperty(property, TLV_DAC_INFO)); - if (info == nullptr) { - return; - } - - /* /mnt/user//nosharefs/Docs */ - char nosharefsDocsDir[PATH_MAX_LEN] = {0}; - int ret = snprintf_s(nosharefsDocsDir, PATH_MAX_LEN, PATH_MAX_LEN - 1, "%s/%u/%s", - mntUser, info->uid / UID_BASE, nosharefsDocs); - if (ret <= 0) { - APPSPAWN_LOGE("snprintf_s nosharefsDocsDir failed, errno %{public}d", errno); - return; - } - - /* /mnt/user//sharefs/Docs */ - char sharefsDocsDir[PATH_MAX_LEN] = {0}; - ret = snprintf_s(sharefsDocsDir, PATH_MAX_LEN, PATH_MAX_LEN - 1, "%s/%u/%s", - mntUser, info->uid / UID_BASE, sharefsDocs); - if (ret <= 0) { - APPSPAWN_LOGE("snprintf_s sharefsDocsDir failed, errno %{public}d", errno); - return; - } - - int index = GetPermissionIndex(nullptr, "ohos.permission.FILE_ACCESS_MANAGER"); - int res = CheckAppPermissionFlagSet(property, static_cast(index)); - if (res == 0) { - char storageUserPath[PATH_MAX_LEN] = {0}; - const char *bundleName = GetBundleName(property); - ret = snprintf_s(storageUserPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "%s/%u/%s/%s", rootPath, info->uid / UID_BASE, - bundleName, userPath); - if (ret <= 0) { - APPSPAWN_LOGE("snprintf_s storageUserPath failed, errno %{public}d", errno); - return; - } - /* mount /mnt/user//sharefs/docs to /mnt/sandbox///storage/Users */ - ret = SharedMountInSharefs(property, rootPath, sharefsDocsDir, storageUserPath); - } else { - /* mount /mnt/user//nosharefs/docs to /mnt/sandbox///storage/Users */ - ret = MountInShared(property, rootPath, nosharefsDocsDir, userPath); - } - if (ret != 0) { - APPSPAWN_LOGE("Update storage dir, ret %{public}d", ret); - } - APPSPAWN_LOGI("Update %{public}s storage dir success", res == 0 ? "sharefs dir" : "no sharefs dir"); -} - -static void MountDirToShared(const AppSpawningCtx *property) -{ - const char rootPath[] = "/mnt/sandbox/"; - const char el1Path[] = "/data/storage/el1/bundle"; - const char lockSuffix[] = "_locked"; - AppDacInfo *info = reinterpret_cast(GetAppProperty(property, TLV_DAC_INFO)); - const char *bundleName = GetBundleName(property); - if (info == NULL || bundleName == NULL) { - return; - } - - string sourcePath = "/data/app/el1/bundle/public/" + string(bundleName); - MountDir(property, rootPath, sourcePath.c_str(), el1Path); - if (IsUnlockStatus(info->uid)) { - return; - } - - UpdateStorageDir(property); - - int length = sizeof(MOUNT_SHARED_MAP) / sizeof(MOUNT_SHARED_MAP[0]); - for (int i = 0; i < length; i++) { - if (MOUNT_SHARED_MAP[i].permission == nullptr) { - MountDir(property, rootPath, nullptr, MOUNT_SHARED_MAP[i].sandboxPath); - } else { - int index = GetPermissionIndex(nullptr, MOUNT_SHARED_MAP[i].permission); - APPSPAWN_LOGV("mount dir on lock mountPermissionFlags %{public}d", index); - if (CheckAppPermissionFlagSet(property, static_cast(index))) { - MountDir(property, rootPath, nullptr, MOUNT_SHARED_MAP[i].sandboxPath); - } - } - } - - std::string lockSbxPathStamp = rootPath + to_string(info->uid / UID_BASE) + "/"; - lockSbxPathStamp += CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? "isolated/" : ""; - lockSbxPathStamp += bundleName; - lockSbxPathStamp += lockSuffix; - OHOS::AppSpawn::MakeDirRecursive(lockSbxPathStamp.c_str(), OHOS::AppSpawn::FILE_MODE); -} -#endif - static int SpawnMountDirToShared(AppSpawnMgr *content, AppSpawningCtx *property) { #ifndef APPSPAWN_SANDBOX_NEW if (!IsNWebSpawnMode(content)) { // mount dynamic directory - MountDirToShared(property); + MountToShared(content, property); } #endif return 0; @@ -2234,18 +1972,19 @@ static int UmountSandboxPath(const AppSpawnMgr *content, const AppSpawnedProcess const char el1Path[] = "/data/storage/el1/bundle"; uint32_t userId = appInfo->uid / UID_BASE; - string key = GetMountInfoKey(userId, appInfo->name); - if (g_mountInfo.find(key) == g_mountInfo.end()) { + std::string key = std::to_string(userId) + "-" + std::string(appInfo->name); + map *el1BundleCountMap = static_cast*>(GetEl1BundleMountCount()); + if (el1BundleCountMap->find(key) == el1BundleCountMap->end()) { return 0; } - g_mountInfo[key]--; - if (g_mountInfo[key] == 0) { + (*el1BundleCountMap)[key]--; + if ((*el1BundleCountMap)[key] == 0) { APPSPAWN_LOGV("no app %{public}s use it in userId %{public}u, need umount", appInfo->name, userId); UmountDir(rootPath, el1Path, appInfo); - g_mountInfo.erase(key); + el1BundleCountMap->erase(key); } else { APPSPAWN_LOGV("app %{public}s use it mount times %{public}d in userId %{public}u, not need umount", - appInfo->name, g_mountInfo[key], userId); + appInfo->name, (*el1BundleCountMap)[key], userId); } return 0; } diff --git a/modules/sandbox/sandbox_utils.h b/modules/sandbox/sandbox_utils.h index 442eba7a..1ad93280 100755 --- a/modules/sandbox/sandbox_utils.h +++ b/modules/sandbox/sandbox_utils.h @@ -137,9 +137,4 @@ public: int LoadAppSandboxConfig(AppSpawnMgr *content); -typedef struct { - const char *sandboxPath; - const char *permission; -} MountSharedTemplate; - #endif // SANDBOX_UTILS_H diff --git a/standard/appspawn_appmgr.c b/standard/appspawn_appmgr.c index f8703828..7866bac8 100644 --- a/standard/appspawn_appmgr.c +++ b/standard/appspawn_appmgr.c @@ -61,6 +61,9 @@ AppSpawnMgr *CreateAppSpawnMgr(int mode) OH_ListInit(&appMgr->appQueue); OH_ListInit(&appMgr->diedQueue); OH_ListInit(&appMgr->appSpawnQueue); +#ifndef APPSPAWN_SANDBOX_NEW + OH_ListInit(&appMgr->dataGroupCtxQueue); +#endif appMgr->diedAppCount = 0; OH_ListInit(&appMgr->extData); g_appSpawnMgr = appMgr; @@ -101,6 +104,9 @@ void DeleteAppSpawnMgr(AppSpawnMgr *mgr) OH_ListRemoveAll(&mgr->diedQueue, NULL); OH_ListRemoveAll(&mgr->appSpawnQueue, SpawningQueueDestroy); OH_ListRemoveAll(&mgr->extData, ExtDataDestroy); +#ifndef APPSPAWN_SANDBOX_NEW + OH_ListRemoveAll(&mgr->dataGroupCtxQueue, NULL); +#endif #ifdef APPSPAWN_HISYSEVENT DeleteHisyseventInfo(mgr->hisyseventInfo); #endif @@ -372,9 +378,9 @@ void AppSpawningCtxTraversal(ProcessTraversal traversal, void *data) static int DumpAppSpawnQueue(ListNode *node, void *data) { AppSpawningCtx *property = ListEntry(node, AppSpawningCtx, node); - APPSPAPWN_DUMP("app property id: %{public}u flags: %{public}x", + APPSPAWN_DUMP("app property id: %{public}u flags: %{public}x", property->client.id, property->client.flags); - APPSPAPWN_DUMP("app property state: %{public}d", property->state); + APPSPAWN_DUMP("app property state: %{public}d", property->state); DumpAppSpawnMsg(property->message); return 0; @@ -384,8 +390,8 @@ static int DumpAppQueue(ListNode *node, void *data) { AppSpawnedProcess *appInfo = ListEntry(node, AppSpawnedProcess, node); uint64_t diff = DiffTime(&appInfo->spawnStart, &appInfo->spawnEnd); - APPSPAPWN_DUMP("App info uid: %{public}u pid: %{public}x", appInfo->uid, appInfo->pid); - APPSPAPWN_DUMP("App info name: %{public}s exitStatus: 0x%{public}x spawn time: %{public}" PRIu64 " us ", + APPSPAWN_DUMP("App info uid: %{public}u pid: %{public}x", appInfo->uid, appInfo->pid); + APPSPAWN_DUMP("App info name: %{public}s exitStatus: 0x%{public}x spawn time: %{public}" PRIu64 " us ", appInfo->name, appInfo->exitStatus, diff); return 0; } @@ -417,16 +423,16 @@ void ProcessAppSpawnDumpMsg(const AppSpawnMsgNode *message) } else { SetDumpToStream(stdout); } - APPSPAPWN_DUMP("Dump appspawn info start ... "); - APPSPAPWN_DUMP("APP spawning queue: "); + APPSPAWN_DUMP("Dump appspawn info start ... "); + APPSPAWN_DUMP("APP spawning queue: "); OH_ListTraversal((ListNode *)&g_appSpawnMgr->appSpawnQueue, NULL, DumpAppSpawnQueue, 0); - APPSPAPWN_DUMP("APP queue: "); + APPSPAWN_DUMP("APP queue: "); OH_ListTraversal((ListNode *)&g_appSpawnMgr->appQueue, "App queue", DumpAppQueue, 0); - APPSPAPWN_DUMP("APP died queue: "); + APPSPAWN_DUMP("APP died queue: "); OH_ListTraversal((ListNode *)&g_appSpawnMgr->diedQueue, "App died queue", DumpAppQueue, 0); - APPSPAPWN_DUMP("Ext data: "); + APPSPAWN_DUMP("Ext data: "); OH_ListTraversal((ListNode *)&g_appSpawnMgr->extData, "Ext data", DumpExtData, 0); - APPSPAPWN_DUMP("Dump appspawn info finish "); + APPSPAWN_DUMP("Dump appspawn info finish "); if (stream != NULL) { (void)fflush(stream); fclose(stream); diff --git a/standard/appspawn_manager.h b/standard/appspawn_manager.h index 5c5280ac..2cca34d8 100644 --- a/standard/appspawn_manager.h +++ b/standard/appspawn_manager.h @@ -53,6 +53,8 @@ extern "C" { #define APP_STATE_IDLE 1 #define APP_STATE_SPAWNING 2 #define APPSPAWN_MAX_TIME 3000000 +#define UUID_MAX_LEN 37 +#define PATH_MAX_LEN 256 #define APPSPAWN_INLINE __attribute__((always_inline)) inline @@ -109,6 +111,21 @@ typedef struct SpawnTime { int maxAppspawnTime; } SpawnTime; +#ifndef APPSPAWN_SANDBOX_NEW +typedef struct TagPathBuffer { + uint32_t pathLen; + char path[PATH_MAX_LEN]; +} PathBuffer; + +typedef struct TagDataGroupCtx { + struct ListNode node; + int gid; + char dataGroupUuid[UUID_MAX_LEN]; + PathBuffer srcPath; + PathBuffer destPath; +} DataGroupCtx; +#endif + typedef struct TagAppSpawnMgr { AppSpawnContent content; TaskHandle server; @@ -123,6 +140,9 @@ typedef struct TagAppSpawnMgr { struct timespec perLoadEnd; struct ListNode extData; struct SpawnTime spawnTime; +#ifndef APPSPAWN_SANDBOX_NEW + struct ListNode dataGroupCtxQueue; +#endif #ifdef APPSPAWN_HISYSEVENT AppSpawnHisyseventInfo *hisyseventInfo; #endif diff --git a/standard/appspawn_msgmgr.c b/standard/appspawn_msgmgr.c index 27bc031e..b7b7b903 100644 --- a/standard/appspawn_msgmgr.c +++ b/standard/appspawn_msgmgr.c @@ -348,29 +348,29 @@ int GetAppSpawnMsgFromBuffer(const uint8_t *buffer, uint32_t bufferLen, static inline void DumpMsgFlags(const char *info, const AppSpawnMsgFlags *msgFlags) { for (uint32_t i = 0; i < msgFlags->count; i++) { - APPSPAPWN_DUMP("%{public}s flags: 0x%{public}x", info, msgFlags->flags[i]); + APPSPAWN_DUMP("%{public}s flags: 0x%{public}x", info, msgFlags->flags[i]); } } static inline void DumpMsgExtInfo(const AppSpawnTlv *tlv) { if (tlv->tlvType != TLV_MAX) { - APPSPAPWN_DUMP("App tlv info: [%{public}d %{public}d]", tlv->tlvType, tlv->tlvLen); + APPSPAWN_DUMP("App tlv info: [%{public}d %{public}d]", tlv->tlvType, tlv->tlvLen); return; } AppSpawnTlvExt *tlvExt = (AppSpawnTlvExt *)(tlv); if (tlvExt->dataType == DATA_TYPE_STRING) { - APPSPAPWN_DUMP("App extend info name: %{public}s len: %{public}u value: '%{public}s'", + APPSPAWN_DUMP("App extend info name: %{public}s len: %{public}u value: '%{public}s'", tlvExt->tlvName, tlvExt->dataLen, (char *)(tlvExt + 1)); } else { - APPSPAPWN_DUMP("App extend info name: %{public}s len: %{public}u", tlvExt->tlvName, tlvExt->dataLen); + APPSPAWN_DUMP("App extend info name: %{public}s len: %{public}u", tlvExt->tlvName, tlvExt->dataLen); } } void DumpAppSpawnMsg(const AppSpawnMsgNode *message) { APPSPAWN_CHECK_ONLY_EXPER(message != NULL, return); - APPSPAPWN_DUMP("App spawn msg msgId: %{public}u msgLen: %{public}u tlvCount: %{public}u processName: %{public}s", + APPSPAWN_DUMP("App spawn msg msgId: %{public}u msgLen: %{public}u tlvCount: %{public}u processName: %{public}s", message->msgHeader.msgId, message->msgHeader.msgLen, message->tlvCount, message->msgHeader.processName); AppSpawnMsgFlags *msgFlags = (AppSpawnMsgFlags *)GetAppSpawnMsgInfo(message, TLV_MSG_FLAGS); @@ -380,20 +380,20 @@ void DumpAppSpawnMsg(const AppSpawnMsgNode *message) AppSpawnMsgDacInfo *dacInfo = (AppSpawnMsgDacInfo *)GetAppSpawnMsgInfo(message, TLV_DAC_INFO); if (dacInfo != NULL) { - APPSPAPWN_DUMP("App dac info uid: %{public}d gid: %{public}d count: %{public}d", + APPSPAWN_DUMP("App dac info uid: %{public}d gid: %{public}d count: %{public}d", dacInfo->uid, dacInfo->gid, dacInfo->gidCount); for (uint32_t i = 0; i < dacInfo->gidCount; i++) { - APPSPAPWN_DUMP("gid group[%{public}d]: %{public}d", i, dacInfo->gidTable[i]); + APPSPAWN_DUMP("gid group[%{public}d]: %{public}d", i, dacInfo->gidTable[i]); } } AppSpawnMsgBundleInfo *bundleInfo = (AppSpawnMsgBundleInfo *)GetAppSpawnMsgInfo(message, TLV_BUNDLE_INFO); APPSPAWN_ONLY_EXPER(bundleInfo != NULL, - APPSPAPWN_DUMP("App bundle info name: \"%{public}s\" index: %{public}d", + APPSPAWN_DUMP("App bundle info name: \"%{public}s\" index: %{public}d", bundleInfo->bundleName, bundleInfo->bundleIndex)); AppSpawnMsgDomainInfo *domainInfo = (AppSpawnMsgDomainInfo *)GetAppSpawnMsgInfo(message, TLV_DOMAIN_INFO); APPSPAWN_ONLY_EXPER(domainInfo != NULL, - APPSPAPWN_DUMP("App domain info hap: 0x%{public}x apl: \"%{public}s\"", domainInfo->hapFlags, domainInfo->apl)); + APPSPAWN_DUMP("App domain info hap: 0x%{public}x apl: \"%{public}s\"", domainInfo->hapFlags, domainInfo->apl)); AppSpawnMgr *mgr = GetAppSpawnMgr(); if (mgr == NULL || ((mgr->flags & APP_DEVELOPER_MODE) != APP_DEVELOPER_MODE)) { @@ -401,11 +401,11 @@ void DumpAppSpawnMsg(const AppSpawnMsgNode *message) } AppSpawnMsgOwnerId *owner = (AppSpawnMsgOwnerId *)GetAppSpawnMsgInfo(message, TLV_OWNER_INFO); - APPSPAWN_ONLY_EXPER(owner != NULL, APPSPAPWN_DUMP("App owner info: \"%{public}s\" ", owner->ownerId)); + APPSPAWN_ONLY_EXPER(owner != NULL, APPSPAWN_DUMP("App owner info: \"%{public}s\" ", owner->ownerId)); AppSpawnMsgInternetInfo *info = (AppSpawnMsgInternetInfo *)GetAppSpawnMsgInfo(message, TLV_INTERNET_INFO); APPSPAWN_ONLY_EXPER(info != NULL, - APPSPAPWN_DUMP("App internet permission info [%{public}d %{public}d]", + APPSPAWN_DUMP("App internet permission info [%{public}d %{public}d]", info->setAllowInternet, info->allowInternet)); for (uint32_t i = TLV_MAX; i < TLV_MAX + message->tlvCount; i++) { diff --git a/test/test_app_info/datagroup/test_app_info.json b/test/test_app_info/datagroup/test_app_info.json new file mode 100644 index 00000000..5be72afa --- /dev/null +++ b/test/test_app_info/datagroup/test_app_info.json @@ -0,0 +1,38 @@ +{ + "msg-type": 0, + "msg-flags": [1, 2, 14], + "process-name" : "ohos.samples.etsclock", + "pid": 328018, + "dac-info" : { + "uid" : 20010043, + "gid" : 20010043, + "gid-table" : [20010043], + "user-name" : "" + }, + "access-token": { + "accessTokenIdEx": 537854093 + }, + "permission": [ + "ohos.permission.PROTECT_SCREEN_LOCK_DATA" + ], + "internet-permission": { + "set-allow-internet": 0, + "allow-internet": 0 + }, + "bundle-info": { + "bundle-index": 0, + "bundle-name": "ohos.samples.etsclock" + }, + "owner-id": "", + "render-cmd": "1234567890", + "domain-info": { + "hap-flags": 0, + "apl": "normal" + }, + "ext-info": [ + { + "name": "DataGroup", + "value": "[{\"gid\": \"1002\", \"dir\": \"data/app/el2/100/group/49c016e6-065a-abd1-5867-b1f91114f840\", \"dataGroupId\": \"43200\", \"uuid\": \"49c016e6-065a-abd1-5867-b1f91114f840\"}, {\"gid\": \"1002\", \"dir\": \"data/app/el2/100/group/49c016e6-065a-abd1-5867-b1f91114f840\", \"dataGroupId\": \"43200\", \"uuid\": \"49c016e6-065a-abd1-5867-b1f91114f840\"}, {\"gid\": \"1002\", \"dir\": \"data/app/el3/100/group/49c016e6-065a-abd1-5867-b1f91114f840\", \"dataGroupId\": \"43200\", \"uuid\": \"49c016e6-065a-abd1-5867-b1f91114f840\"}, {\"gid\": \"1002\", \"dir\": \"data/app/el4/100/group/49c016e6-065a-abd1-5867-b1f91114f840\", \"dataGroupId\": \"43200\", \"uuid\": \"49c016e6-065a-abd1-5867-b1f91114f840\"}, { \"gid\": \"1002\", \"dir\": \"data/app/el5/100/group/49c016e6-065a-abd1-5867-b1f91114f840\", \"dataGroupId\": \"43200\", \"uuid\": \"49c016e6-065a-abd1-5867-b1f91114f840\"}]" + } + ] +} diff --git a/test/unittest/app_spawn_standard_test/BUILD.gn b/test/unittest/app_spawn_standard_test/BUILD.gn index da7ccf3a..7a2e1921 100644 --- a/test/unittest/app_spawn_standard_test/BUILD.gn +++ b/test/unittest/app_spawn_standard_test/BUILD.gn @@ -149,6 +149,7 @@ ohos_unittest("AppSpawn_ut") { defines += [ "APPSPAWN_SANDBOX_NEW" ] } else { sources += [ + "${appspawn_path}/modules/sandbox/sandbox_shared_mount.cpp", "${appspawn_path}/modules/sandbox/sandbox_utils.cpp", "${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_sandbox_test.cpp", ] @@ -337,7 +338,10 @@ ohos_unittest("AppSpawn_coldrun_ut") { if (defined(appspawn_sandbox_new) && appspawn_sandbox_new) { defines += [ "APPSPAWN_SANDBOX_NEW" ] } else { - sources += [ "${appspawn_path}/modules/sandbox/sandbox_utils.cpp" ] + sources += [ + "${appspawn_path}/modules/sandbox/sandbox_shared_mount.cpp", + "${appspawn_path}/modules/sandbox/sandbox_utils.cpp", + ] } configs = [ "${appspawn_path}:appspawn_config" ] @@ -523,7 +527,10 @@ ohos_unittest("AppSpawn_common_ut") { if (defined(appspawn_sandbox_new) && appspawn_sandbox_new) { defines += [ "APPSPAWN_SANDBOX_NEW" ] } else { - sources += [ "${appspawn_path}/modules/sandbox/sandbox_utils.cpp" ] + sources += [ + "${appspawn_path}/modules/sandbox/sandbox_shared_mount.cpp", + "${appspawn_path}/modules/sandbox/sandbox_utils.cpp", + ] } configs = [ "${appspawn_path}:appspawn_config" ] diff --git a/util/include/appspawn_utils.h b/util/include/appspawn_utils.h index dbf2aedb..ff220c33 100755 --- a/util/include/appspawn_utils.h +++ b/util/include/appspawn_utils.h @@ -176,7 +176,7 @@ int EnableNewNetNamespace(void); #define APPSPAWN_LOGF(fmt, ...) \ HILOG_FATAL(LOG_CORE, "[%{public}s:%{public}d]" fmt, (APP_FILE_NAME), (__LINE__), ##__VA_ARGS__) -#define APPSPAPWN_DUMP(fmt, ...) \ +#define APPSPAWN_DUMP(fmt, ...) \ do { \ HILOG_INFO(LOG_CORE, fmt, ##__VA_ARGS__); \ AppSpawnDump(fmt "\n", ##__VA_ARGS__); \ -- Gitee