diff --git a/appdata-sandbox-app.json b/appdata-sandbox-app.json index ba54cae42d497579064f9744ce54616e8cb911db..fdf88df3b0d4998c5b1e2f53ca0534391d1bf417 100644 --- a/appdata-sandbox-app.json +++ b/appdata-sandbox-app.json @@ -192,6 +192,10 @@ "mount-paths": [{ "src-path": "/mnt/user//nosharefs/docs", "sandbox-path": "/storage/Users" + }, { + "src-path": "", + "sandbox-path": "", + "dec-paths":[ "/storage/Users//appdata/el2/shareFiles" ] }, { "src-path": "/mnt/data//userExternal", "sandbox-path": "/storage/userExternal" @@ -369,6 +373,10 @@ "src-path": "/dev/fuse", "sandbox-path": "/mnt/data/fuse", "category": "dlp_fuse" + }, { + "src-path": "", + "sandbox-path": "", + "dec-paths": [ "/mnt/data/fuse" ] }], "mount-groups": ["dlpmgr"] }, { @@ -390,6 +398,27 @@ "src-path": "/data/service/el1/public/update/param_service/install/system/etc/", "sandbox-path": "/data/service/el1/public/update/param_service/install/system/etc/" }] + }, { + "name": "ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY", + "mount-paths": [{ + "src-path": "none", + "sandbox-path": "none", + "dec-paths": [ "/storage/Users//Download" ] + }] + },{ + "name": "ohos.permission.READ_WRITE_DESKTOP_DIRECTORY", + "mount-paths": [{ + "src-path": "none", + "sandbox-path": "none", + "dec-paths": [ "/storage/Users//Desktop" ] + }] + },{ + "name": "ohos.permission.READ_WRITE_DOCUMENTS_DIRECTORY", + "mount-paths": [{ + "src-path": "none", + "sandbox-path": "none", + "dec-paths": [ "/storage/Users//Documents" ] + }] }, { "name": "ohos.permission.READ_WRITE_USER_FILE", "gids": ["file_manager"], diff --git a/appdata-sandbox.json b/appdata-sandbox.json index 043b888d59de5fda9ae4924acb38923ca78422b5..f7e6b86c73a070623ccb1a5dbdc4ba1d9037b084 100755 --- a/appdata-sandbox.json +++ b/appdata-sandbox.json @@ -701,6 +701,12 @@ "src-path": "/mnt/data//userExternal", "sandbox-path": "/storage/userExternal", "sandbox-flags": [ "bind", "rec" ] + }, + { + "src-path": "", + "sandbox-path": "", + "sandbox-flags": [], + "dec-paths": [ "/storage/Users//appdata/el2/shareFiles" ] } ] }], @@ -911,6 +917,11 @@ "dac-override-sensitive": "true", "fs-type": "fuse", "check-action-status": "false" + }, { + "src-path": "", + "sandbox-path": "", + "sandbox-flags": [], + "dec-paths": [ "/mnt/data/fuse" ] } ] }], @@ -989,6 +1000,36 @@ } ] }], + "ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY":[{ + "sandbox-switch": "ON", + "mount-paths": [{ + "src-path": "", + "sandbox-path": "", + "sandbox-flags": [], + "dec-paths": [ "/storage/Users//Download" ] + } + ] + }], + "ohos.permission.READ_WRITE_DESKTOP_DIRECTORY":[{ + "sandbox-switch": "ON", + "mount-paths": [{ + "src-path": "", + "sandbox-path": "", + "sandbox-flags": [], + "dec-paths": [ "/storage/Users//Desktop" ] + } + ] + }], + "ohos.permission.READ_WRITE_DOCUMENTS_DIRECTORY":[{ + "sandbox-switch": "ON", + "mount-paths": [{ + "src-path": "", + "sandbox-path": "", + "sandbox-flags": [], + "dec-paths": [ "/storage/Users//Documents" ] + } + ] + }], "ohos.permission.ACCESS_FACTORY_OTA_DIR":[{ "sandbox-switch": "ON", "mount-paths": [{ diff --git a/modules/sandbox/BUILD.gn b/modules/sandbox/BUILD.gn index 194a49573d6fc1b1acd644ad5ce5095d7d1d5be7..5464f7a9e83f882089086abb78695b72fc260a94 100644 --- a/modules/sandbox/BUILD.gn +++ b/modules/sandbox/BUILD.gn @@ -23,6 +23,7 @@ if (defined(appspawn_sandbox_new) && appspawn_sandbox_new) { "sandbox_adapter.cpp", "sandbox_cfgvar.c", "sandbox_debug_mode.c", + "sandbox_dec.c", "sandbox_expand.c", "sandbox_load.c", "sandbox_manager.c", @@ -80,6 +81,7 @@ if (defined(appspawn_sandbox_new) && appspawn_sandbox_new) { sources = [ "${appspawn_innerkits_path}/permission/appspawn_mount_permission.c", "appspawn_permission.c", + "sandbox_dec.c", "sandbox_shared_mount.cpp", "sandbox_utils.cpp", ] diff --git a/modules/sandbox/appspawn_sandbox.c b/modules/sandbox/appspawn_sandbox.c index d2e44616d21aa7c123624c768939a3aca5e7b68c..d8bd7ba34b3c99bff5355e6f61bc8c8b08de2438 100644 --- a/modules/sandbox/appspawn_sandbox.c +++ b/modules/sandbox/appspawn_sandbox.c @@ -38,6 +38,7 @@ #include "init_utils.h" #include "parameter.h" #include "appspawn_permission.h" +#include "sandbox_dec.h" #ifdef WITH_SELINUX #ifdef APPSPAWN_MOUNT_TMPSHM @@ -447,6 +448,98 @@ static int DoSandboxMountByCategory(const SandboxContext *context, const PathMou return ret; } +static void FreeDecPolicyPaths(DecPolicyInfo *decPolicyInfo) +{ + if (decPolicyInfo == NULL) { + return; + } + + for (uint32_t i = 0; i < decPolicyInfo->pathNum; i++) { + if (decPolicyInfo->path[i].path) { + free(decPolicyInfo->path[i].path); + } + } + + decPolicyInfo->pathNum = 0; +} + + +static int32_t SetDecPolicyWithCond(const SandboxContext *context, const PathMountNode *sandboxNode, + VarExtraData *extraData) +{ + if (sandboxNode == NULL || sandboxNode->decPolicyPaths.decPathCount == 0) { + return 0; + } + + AppSpawnMsgAccessToken *tokenInfo = (AppSpawnMsgAccessToken *)GetSandboxCtxMsgInfo(context, TLV_ACCESS_TOKEN_INFO); + APPSPAWN_CHECK(tokenInfo != NULL, return APPSPAWN_MSG_INVALID, "Get token id failed."); + + DecPolicyInfo decPolicyInfo = {0}; + decPolicyInfo.pathNum = sandboxNode->decPolicyPaths.decPathCount; + + for (uint32_t i = 0; i < decPolicyInfo.pathNum; i++) { + const char* realDecPath = GetSandboxRealVar(context, BUFFER_FOR_TARGET, sandboxNode->decPolicyPaths.decPath[i], + NULL, extraData); + if (realDecPath == NULL) { + // Handle the error appropriately if needed + continue; + } + decPolicyInfo.path[i].path = strdup(realDecPath); + if (decPolicyInfo.path[i].path == NULL) { + // Free already allocated paths before returning + FreeDecPolicyPaths(&decPolicyInfo); + return APPSPAWN_ERROR_UTILS_MEM_FAIL; + } + + decPolicyInfo.path[i].pathLen = (uint32_t)strlen(decPolicyInfo.path[i].path); + decPolicyInfo.path[i].mode = SANDBOX_MODE_WRITE | SANDBOX_MODE_READ; + } + + decPolicyInfo.tokenId = tokenInfo->accessTokenIdEx; + decPolicyInfo.flag = true; + SetDecPolicyInfos(&decPolicyInfo); + FreeDecPolicyPaths(&decPolicyInfo); + return 0; +} + +static int SetDecPolicyWithDir(const SandboxContext *context) +{ + AppSpawnMsgAccessToken *tokenInfo = (AppSpawnMsgAccessToken *)GetSandboxCtxMsgInfo(context, TLV_ACCESS_TOKEN_INFO); + AppSpawnMsgBundleInfo *bundleInfo = (AppSpawnMsgBundleInfo *)GetSandboxCtxMsgInfo(context, TLV_BUNDLE_INFO); + APPSPAWN_CHECK(tokenInfo != NULL && bundleInfo != NULL, return APPSPAWN_MSG_INVALID, + "Get token info or bundle info failed."); + + uint32_t flags = CheckAppSpawnMsgFlag(context->message, TLV_MSG_FLAGS, APP_FLAGS_ATOMIC_SERVICE) ? 0x4 : 0; + if (flags == 0) { + flags = (CheckAppSpawnMsgFlag(context->message, TLV_MSG_FLAGS, APP_FLAGS_CLONE_ENABLE) && + bundleInfo->bundleIndex > 0) ? 0x1 : 0; + } + int ret = 0; + char downloadDir[PATH_MAX] = {0}; + if (flags == 1) { + ret = snprintf_s(downloadDir, PATH_MAX, PATH_MAX - 1, "/storage/Users/currentUser/Download/+clone-%d+%s", + bundleInfo->bundleIndex, bundleInfo->bundleName); + } else { + ret = snprintf_s(downloadDir, PATH_MAX, PATH_MAX - 1, "/storage/Users/currentUser/Download/%s", + bundleInfo->bundleName); + } + APPSPAWN_CHECK(ret > 0, return APPSPAWN_ERROR_UTILS_MEM_FAIL, + "snprintf_s download path failed, ret %{public}d, err %{public}d", ret, errno); + + DecPolicyInfo decPolicyInfo = {0}; + decPolicyInfo.pathNum = 1; + PathInfo pathInfo = {0}; + pathInfo.path = downloadDir; + pathInfo.pathLen = (uint32_t)(strlen(pathInfo.path)); + pathInfo.mode = SANDBOX_MODE_WRITE | SANDBOX_MODE_READ; + decPolicyInfo.path[0] = pathInfo; + decPolicyInfo.tokenId = tokenInfo->accessTokenIdEx; + decPolicyInfo.flag = true; + + SetDecPolicyInfos(&decPolicyInfo); + return 0; +} + static int DoSandboxPathNodeMount(const SandboxContext *context, const SandboxSection *section, const PathMountNode *sandboxNode, uint32_t operation) { @@ -494,7 +587,12 @@ static int DoSandboxPathNodeMount(const SandboxContext *context, section->name, ret, category); return ret; } - return 0; + + ret = SetDecPolicyWithCond(context, sandboxNode, extraData); + if (ret != 0) { + APPSPAWN_LOGE("Failed to set dec policy with conditional: %{public}d", ret); + } + return ret; } static int DoSandboxPathSymLink(const SandboxContext *context, @@ -1249,6 +1347,8 @@ int MountSandboxConfigs(AppSpawnSandboxCfg *sandbox, const AppSpawningCtx *prope #endif ret = ChangeCurrentDir(context); APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break); + SetDecPolicyWithDir(context); + SetDecPolicy(); #if defined(APPSPAWN_MOUNT_TMPSHM) && defined(WITH_SELINUX) Restorecon(DEV_SHM_DIR); #endif diff --git a/modules/sandbox/appspawn_sandbox.h b/modules/sandbox/appspawn_sandbox.h index 0cfd55585c1365b556bc79947cee4a1f470f85db..b0065e02b5ba3ab8c48ee9c08615a29ce1795791 100644 --- a/modules/sandbox/appspawn_sandbox.h +++ b/modules/sandbox/appspawn_sandbox.h @@ -122,6 +122,11 @@ typedef struct { uint32_t mode; } PathDemandInfo; +typedef struct { + uint32_t decPathCount; // dec放行目录数量 + char **decPath; // dec放行目录数组 +} DecPolicyPaths; + typedef struct TagPathMountNode { SandboxMountNode sandboxNode; char *source; // source 目录,一般是全局的fs 目录 @@ -134,6 +139,7 @@ typedef struct TagPathMountNode { uint32_t category; char *appAplName; PathDemandInfo demandInfo[0]; + DecPolicyPaths decPolicyPaths; } PathMountNode; typedef struct TagSymbolLinkNode { diff --git a/modules/sandbox/sandbox_dec.c b/modules/sandbox/sandbox_dec.c new file mode 100644 index 0000000000000000000000000000000000000000..7c2cb3e616e6fcc55ef7d07d8037b2208bffd04f --- /dev/null +++ b/modules/sandbox/sandbox_dec.c @@ -0,0 +1,208 @@ +/* + * 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 "sandbox_dec.h" + +#include +#include +#include +#include +#include "appspawn_utils.h" +#include "appspawn_hook.h" + +static const char *g_decConstraintDir[] = { + "/storage/Users", + "/storage/Externel", + "/storage/Share", + "/storage/hmdfs", + "/mnt/data/fuse", + "/mnt/debug", + "/storage/userExternel" +}; + +static const char *g_decForcedPrefix[] = { + "/storage/Users/currentUser/appdata", +}; + +static DecPolicyInfo *g_decPolicyInfos = NULL; + +void DestoryDecPolicyInfos(DecPolicyInfo *decPolicyInfos) +{ + if (decPolicyInfos == NULL) { + return; + } + for (uint32_t i = 0; i < decPolicyInfos->pathNum; i++) { + if (decPolicyInfos->path[i].path) { + free(decPolicyInfos->path[i].path); + decPolicyInfos->path[i].pathLen = 0; + decPolicyInfos->path[i].flag = 0; + decPolicyInfos->path[i].mode = 0; + } + } + decPolicyInfos->pathNum = 0; + decPolicyInfos->tokenId = 0; + decPolicyInfos->flag = 0; + free(decPolicyInfos); +} + +void SetDecPolicyInfos(DecPolicyInfo *decPolicyInfos) +{ + if (decPolicyInfos == NULL || decPolicyInfos->pathNum == 0) { + return; + } + + if (g_decPolicyInfos == NULL) { + g_decPolicyInfos = (DecPolicyInfo *)calloc(1, sizeof(DecPolicyInfo)); + if (g_decPolicyInfos == NULL) { + APPSPAWN_LOGE("calloc failed"); + return; + } + } + + APPSPAWN_CHECK(g_decPolicyInfos->pathNum + decPolicyInfos->pathNum <= MAX_POLICY_NUM, + DestoryDecPolicyInfos(g_decPolicyInfos); + g_decPolicyInfos = NULL; + return, "Out of MAX_POLICY_NUM %{public}d, %{public}d", g_decPolicyInfos->pathNum, decPolicyInfos->pathNum); + for (uint32_t i = 0; i < decPolicyInfos->pathNum; i++) { + PathInfo pathInfo = {0}; + if (decPolicyInfos->path[i].path == NULL) { + DestoryDecPolicyInfos(g_decPolicyInfos); + g_decPolicyInfos = NULL; + return; + } + pathInfo.path = strdup(decPolicyInfos->path[i].path); + if (pathInfo.path == NULL) { + DestoryDecPolicyInfos(g_decPolicyInfos); + g_decPolicyInfos = NULL; + return; + } + pathInfo.pathLen = (uint32_t)strlen(pathInfo.path); + pathInfo.mode = SANDBOX_MODE_WRITE | SANDBOX_MODE_READ; + uint32_t index = g_decPolicyInfos->pathNum + 1; + g_decPolicyInfos->path[index] = pathInfo; + } + g_decPolicyInfos->tokenId = decPolicyInfos->tokenId; + g_decPolicyInfos->tokenId = decPolicyInfos->pathNum; + g_decPolicyInfos->flag = true; + g_decPolicyInfos->userId = 0; +} + +static int SetDecConstraintDirs(AppSpawnMgr* content) +{ + APPSPAWN_LOGI("enter SetDecConstraintDirs sandbox policy success."); + UNUSED(content); + const char *decFilename = "/dev/dec"; + int fd = open(decFilename, O_RDWR); + if (fd < 0) { + APPSPAWN_LOGE("open dec file fail."); + return 0; + } + + uint32_t decDirsSize = ARRAY_LENGTH(g_decConstraintDir); + DecPolicyInfo decPolicyInfos = {0}; + decPolicyInfos.tokenId = 0; + decPolicyInfos.pathNum = decDirsSize; + decPolicyInfos.flag = 0; + + for (uint32_t i = 0; i < decDirsSize; i++) { + PathInfo pathInfo = {(char *)g_decConstraintDir[i], (uint32_t)strlen(g_decConstraintDir[i]), SANDBOX_MODE_READ}; + decPolicyInfos.path[i] = pathInfo; + } + + if (ioctl(fd, CONSTRAINT_DEC_POLICY_CMD, &decPolicyInfos) < 0) { + APPSPAWN_LOGE("set sandbox policy failed."); + } else { + APPSPAWN_LOGI("set CONSTRAINT_DEC_POLICY_CMD sandbox policy success."); + for (uint32_t i = 0; i < decDirsSize; i++) { + APPSPAWN_LOGI("policy info: %{public}s", decPolicyInfos.path[i].path); + } + } + close(fd); + return 0; +} + +static int SetForcedPrefixDirs(AppSpawnMgr* content) +{ + APPSPAWN_LOGI("enter SetForcedPrefixDirs sandbox policy success."); + UNUSED(content); + const char *decFilename = "/dev/dec"; + int fd = open(decFilename, O_RDWR); + if (fd < 0) { + APPSPAWN_LOGE("open dec file fail."); + return 0; + } + + uint32_t decDirsSize = ARRAY_LENGTH(g_decForcedPrefix); + DecPolicyInfo decPolicyInfos = {0}; + decPolicyInfos.tokenId = 0; + decPolicyInfos.pathNum = decDirsSize; + decPolicyInfos.flag = 0; + + for (uint32_t i = 0; i < decDirsSize; i++) { + PathInfo pathInfo = {(char *)g_decForcedPrefix[i], (uint32_t)strlen(g_decForcedPrefix[i]), SANDBOX_MODE_READ}; + decPolicyInfos.path[i] = pathInfo; + } + + if (ioctl(fd, SET_DEC_PREFIX_CMD, &decPolicyInfos) < 0) { + APPSPAWN_LOGE("set sandbox forced prefix failed."); + } else { + APPSPAWN_LOGI("set SET_DEC_PREFIX_CMD sandbox policy success."); + for (uint32_t i = 0; i < decDirsSize; i++) { + APPSPAWN_LOGI("policy info: %{public}s", decPolicyInfos.path[i].path); + } + } + close(fd); + return 0; +} + +void SetDecPolicy(void) +{ + if (g_decPolicyInfos == NULL) { + return; + } + const char *decFilename = "/dev/dec"; + int fd = open(decFilename, O_RDWR); + if (fd < 0) { + APPSPAWN_LOGE("open dec file fail."); + DestoryDecPolicyInfos(g_decPolicyInfos); + g_decPolicyInfos = NULL; + return; + } + + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + uint64_t timestamp = ts.tv_sec * APPSPAWN_SEC_TO_NSEC + ts.tv_nsec; + g_decPolicyInfos->timestamp = timestamp; + + if (ioctl(fd, SET_DEC_POLICY_CMD, g_decPolicyInfos) < 0) { + APPSPAWN_LOGE("set sandbox policy failed."); + } else { + APPSPAWN_LOGI("set SET_DEC_POLICY_CMD sandbox policy success. timestamp:%{public}" PRId64 "", timestamp); + for (uint32_t i = 0; i < g_decPolicyInfos->pathNum; i++) { + APPSPAWN_LOGI("policy info: %{public}s", g_decPolicyInfos->path[i].path); + } + } + close(fd); + DestoryDecPolicyInfos(g_decPolicyInfos); + g_decPolicyInfos = NULL; + return; +} + +MODULE_CONSTRUCTOR(void) +{ + APPSPAWN_LOGI("Load sandbox dec module ..."); + AddPreloadHook(HOOK_PRIO_COMMON, SetDecConstraintDirs); + AddPreloadHook(HOOK_PRIO_COMMON, SetForcedPrefixDirs); +} diff --git a/modules/sandbox/sandbox_dec.h b/modules/sandbox/sandbox_dec.h new file mode 100644 index 0000000000000000000000000000000000000000..3593ad7c4c2869bf2743b049d96b4465b850a041 --- /dev/null +++ b/modules/sandbox/sandbox_dec.h @@ -0,0 +1,83 @@ +/* + * 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_DEC_H +#define SANDBOX_DEC_H + +#include +#include +#include +#include +#include +#include "appspawn_hook.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#define DEV_DEC_MINOR 0x25 +#define HM_DEC_IOCTL_BASE 's' +#define HM_SET_POLICY_ID 1 +#define HM_DEL_POLICY_ID 2 +#define HM_QUERY_POLICY_ID 3 +#define HM_CHECK_POLICY_ID 4 +#define HM_DESTORY_POLICY_ID 5 +#define HM_CONSTRAINT_POLICY_ID 6 +#define HM_DENY_POLICY_ID 7 +#define HM_SET_PREFIX_ID 8 + +#define SET_DEC_POLICY_CMD _IOWR(HM_DEC_IOCTL_BASE, HM_SET_POLICY_ID, DecPolicyInfo) +#define DEL_DEC_POLICY_CMD _IOWR(HM_DEC_IOCTL_BASE, HM_DEL_POLICY_ID, DecPolicyInfo) // 忽略flag和mode +#define CHECK_DEC_POLICY_CMD _IOWR(HM_DEC_IOCTL_BASE, HM_CHECK_POLICY_ID, DecPolicyInfo) // 忽略flag +#define DESTORY_DEC_POLICY_CMD _IOW(HM_DEC_IOCTL_BASE, HM_DESTORY_POLICY_ID, uint64_t) +#define CONSTRAINT_DEC_POLICY_CMD _IOW(HM_DEC_IOCTL_BASE, HM_CONSTRAINT_POLICY_ID, DecPolicyInfo) +#define DENY_DEC_POLICY_CMD _IOWR(HM_DEC_IOCTL_BASE, HM_DENY_POLICY_ID, DecPolicyInfo) // 忽略tokenid/flag/mode +#define SET_DEC_PREFIX_CMD _IOWR(HM_DEC_IOCTL_BASE, HM_SET_PREFIX_ID, DecPolicyInfo) + +#define MAX_POLICY_NUM 8 +#define SANDBOX_MODE_READ 0x00000001 +#define SANDBOX_MODE_WRITE (SANDBOX_MODE_READ << 1) + +#define DEC_POLICY_HEADER_RESERVED 64 + +typedef struct PathInfo { + char *path; + uint32_t pathLen; + uint32_t mode; + bool flag; +} PathInfo; + +typedef struct DecPolicyInfo { + uint64_t tokenId; + uint64_t timestamp; + PathInfo path[MAX_POLICY_NUM]; + uint32_t pathNum; + int32_t userId; + uint64_t reserved[DEC_POLICY_HEADER_RESERVED]; + bool flag; +} DecPolicyInfo; + +void SetDecPolicyInfos(DecPolicyInfo *decPolicyInfos); +void DestoryDecPolicyInfos(DecPolicyInfo *decPolicyInfos); +void SetDecPolicy(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif +#endif diff --git a/modules/sandbox/sandbox_load.c b/modules/sandbox/sandbox_load.c index 8a6741a752d0deadd560f6d4c8716c091551a800..2a95130e127cd27bf01162040825b5410dabf26b 100644 --- a/modules/sandbox/sandbox_load.c +++ b/modules/sandbox/sandbox_load.c @@ -204,6 +204,57 @@ static void FillPathDemandInfo(const cJSON *config, PathMountNode *sandboxNode) sandboxNode->demandInfo->mode = GetIntValueFromJsonObj(config, "ugo", -1); } +static int32_t DecodeDecPolicyPaths(const cJSON *config, PathMountNode *sandboxNode) +{ + if (config == NULL || sandboxNode == NULL) { + return APPSPAWN_MSG_INVALID; + } + + sandboxNode->decPolicyPaths.decPathCount = 0; + sandboxNode->decPolicyPaths.decPath = NULL; + + cJSON *pathArray = cJSON_GetObjectItemCaseSensitive(config, "dec-paths"); + if (pathArray == NULL || !cJSON_IsArray(pathArray)) { + return 0; + } + + int pathCount = cJSON_GetArraySize(pathArray); + if (pathCount == 0) { + return 0; + } + size_t decPathSize = pathCount * sizeof(char *); + sandboxNode->decPolicyPaths.decPath = (char **)malloc(decPathSize); + if (sandboxNode->decPolicyPaths.decPath == NULL) { + return APPSPAWN_ERROR_UTILS_MEM_FAIL; + } + + for (int i = 0; i < pathCount; i++) { + cJSON *pathItem = cJSON_GetArrayItem(pathArray, i); + if (!cJSON_IsString(pathItem)) { + APPSPAWN_LOGE("path parse failed"); + goto ERROR; + } + sandboxNode->decPolicyPaths.decPath[i] = strdup(pathItem->valuestring); + if (sandboxNode->decPolicyPaths.decPath[i] == NULL) { + goto ERROR; + } + sandboxNode->decPolicyPaths.decPathCount++; + } + return 0; + +ERROR: + for (int i = 0; i < pathCount; i++) { + if (sandboxNode->decPolicyPaths.decPath[i] != NULL) { + free(sandboxNode->decPolicyPaths.decPath[i]); + sandboxNode->decPolicyPaths.decPath[i] = NULL; + } + } + sandboxNode->decPolicyPaths.decPathCount = 0; + free(sandboxNode->decPolicyPaths.decPath); + sandboxNode->decPolicyPaths.decPath = NULL; + return -1; +} + static PathMountNode *DecodeMountPathConfig(const SandboxSection *section, const cJSON *config, uint32_t type) { char *srcPath = GetStringFromJsonObj(config, "src-path"); @@ -236,6 +287,11 @@ static PathMountNode *DecodeMountPathConfig(const SandboxSection *section, const } FillPathDemandInfo(demandInfo, sandboxNode); + int ret = DecodeDecPolicyPaths(config, sandboxNode); + if (ret != 0) { + APPSPAWN_LOGE("DecodeDecPolicyPaths failed %{public}d", ret); + } + if (sandboxNode->source == NULL || sandboxNode->target == NULL) { APPSPAWN_LOGE("Failed to get sourc or target path"); DeleteSandboxMountNode((SandboxMountNode *)sandboxNode); diff --git a/modules/sandbox/sandbox_manager.c b/modules/sandbox/sandbox_manager.c index 522046a0837e6c988041addf5e57e7cefe7445a7..c90d5c623f9e7f68c78313d5de3f52ccdfa784f1 100644 --- a/modules/sandbox/sandbox_manager.c +++ b/modules/sandbox/sandbox_manager.c @@ -41,6 +41,15 @@ static void FreePathMountNode(SandboxMountNode *node) free(sandboxNode->appAplName); sandboxNode->appAplName = NULL; } + for (uint32_t i = 0; i < sandboxNode->decPolicyPaths.decPathCount; i++) { + if (sandboxNode->decPolicyPaths.decPath[i] != NULL) { + free(sandboxNode->decPolicyPaths.decPath[i]); + sandboxNode->decPolicyPaths.decPath[i] = NULL; + } + } + sandboxNode->decPolicyPaths.decPathCount = 0; + free(sandboxNode->decPolicyPaths.decPath); + sandboxNode->decPolicyPaths.decPath = NULL; free(sandboxNode); } diff --git a/modules/sandbox/sandbox_utils.cpp b/modules/sandbox/sandbox_utils.cpp index 777da7a5c3c4827652fa5ee5cf20fd3edd3c5cd7..a805e604540f975681edfedf7187506012bd04ad 100644 --- a/modules/sandbox/sandbox_utils.cpp +++ b/modules/sandbox/sandbox_utils.cpp @@ -42,6 +42,7 @@ #include "init_utils.h" #include "parameter.h" #include "parameters.h" +#include "sandbox_dec.h" #include "securec.h" #ifdef APPSPAWN_HISYSEVENT #include "hisysevent_adapter.h" @@ -122,6 +123,7 @@ namespace { const char *g_dacOverrideSensitive = "dac-override-sensitive"; const char *g_sandBoxShared = "sandbox-shared"; const char *g_sandBoxSwitchPrefix = "sandbox-switch"; + const char *g_sandBoxDecPath = "dec-paths"; const char *g_symlinkPrefix = "symbol-links"; const char *g_sandboxRootPrefix = "sandbox-root"; const char *g_topSandBoxSwitchPrefix = "top-sandbox-switch"; @@ -863,15 +865,34 @@ std::string SandboxUtils::GetSandboxOptions(const AppSpawningCtx *appProperty, n return options; } +std::vector SandboxUtils::GetSandboxDecPath(const AppSpawningCtx *appProperty, nlohmann::json &config) +{ + AppSpawnMsgDacInfo *dacInfo = reinterpret_cast(GetAppProperty(appProperty, TLV_DAC_INFO)); + if (dacInfo == nullptr) { + return {}; + } + + std::vector decPaths = {}; + if (config.find(g_sandBoxDecPath) != config.end()) { + for (auto decPath : config[g_sandBoxDecPath].get>()) { + decPath = ConvertToRealPathWithPermission(appProperty, decPath); + decPaths.push_back(decPath); + } + } + return decPaths; +} + void SandboxUtils::GetSandboxMountConfig(const AppSpawningCtx *appProperty, const std::string §ion, nlohmann::json &mntPoint, SandboxMountConfig &mountConfig) { if (section.compare(g_permissionPrefix) == 0) { mountConfig.optionsPoint = GetSandboxOptions(appProperty, mntPoint); mountConfig.fsType = GetSandboxFsType(mntPoint); + mountConfig.decPaths = GetSandboxDecPath(appProperty, mntPoint); } else { mountConfig.fsType = (mntPoint.find(g_fsType) != mntPoint.end()) ? mntPoint[g_fsType].get() : ""; mountConfig.optionsPoint = ""; + mountConfig.decPaths = {}; } return; } @@ -889,6 +910,88 @@ std::string SandboxUtils::GetSandboxPath(const AppSpawningCtx *appProperty, nloh return sandboxPath; } +int32_t SandboxUtils::SetDecWithDir(const AppSpawningCtx *appProperty, uint32_t userId) +{ + AppSpawnMsgAccessToken *tokenInfo = + reinterpret_cast(GetAppProperty(appProperty, TLV_ACCESS_TOKEN_INFO)); + APPSPAWN_CHECK(tokenInfo != NULL, return APPSPAWN_MSG_INVALID, "Get token id failed."); + + AppSpawnMsgBundleInfo *bundleInfo = + reinterpret_cast(GetAppProperty(appProperty, TLV_BUNDLE_INFO)); + APPSPAWN_CHECK(bundleInfo != NULL, return APPSPAWN_MSG_INVALID, "No bundle info in msg %{public}s", + GetBundleName(appProperty)); + + uint32_t flags = CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_ATOMIC_SERVICE) ? 0x4 : 0; + if (flags == 0) { + flags = (CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_CLONE_ENABLE) && + bundleInfo->bundleIndex > 0) ? 0x1 : 0; + } + std::ostringstream clonePackageName; + if (flags == 1) { + clonePackageName << "+clone-" << bundleInfo->bundleIndex << "+" << bundleInfo->bundleName; + } else { + clonePackageName << bundleInfo->bundleName; + } + std::string dir = "/storage/Users/currentUser/Download/" + clonePackageName.str(); + DecPolicyInfo decPolicyInfo = {0}; + decPolicyInfo.pathNum = 1; + PathInfo pathInfo = {0}; + pathInfo.path = strdup(dir.c_str()); + if (pathInfo.path == nullptr) { + APPSPAWN_LOGE("strdup %{public}s failed, err %{public}d", dir.c_str(), errno); + return APPSPAWN_MSG_INVALID; + } + pathInfo.pathLen = static_cast(strlen(pathInfo.path)); + pathInfo.mode = SANDBOX_MODE_WRITE | SANDBOX_MODE_READ; + decPolicyInfo.path[0] = pathInfo; + decPolicyInfo.tokenId = tokenInfo->accessTokenIdEx; + decPolicyInfo.flag = true; + SetDecPolicyInfos(&decPolicyInfo); + + if (decPolicyInfo.path[0].path) { + free(decPolicyInfo.path[0].path); + decPolicyInfo.path[0].path = nullptr; + } + return 0; +} + +int32_t SandboxUtils::SetDecPolicyWithPermission(const AppSpawningCtx *appProperty, SandboxMountConfig &mountConfig) +{ + if (mountConfig.decPaths.size() == 0) { + return 0; + } + AppSpawnMsgAccessToken *tokenInfo = + reinterpret_cast(GetAppProperty(appProperty, TLV_ACCESS_TOKEN_INFO)); + APPSPAWN_CHECK(tokenInfo != NULL, return APPSPAWN_MSG_INVALID, "Get token id failed."); + + DecPolicyInfo decPolicyInfo = {0}; + decPolicyInfo.pathNum = mountConfig.decPaths.size(); + int ret = 0; + for (uint32_t i = 0; i < decPolicyInfo.pathNum; i++) { + PathInfo pathInfo = {0}; + pathInfo.path = strdup(mountConfig.decPaths[i].c_str()); + if (pathInfo.path == nullptr) { + APPSPAWN_LOGE("strdup %{public}s failed, err %{public}d", mountConfig.decPaths[i].c_str(), errno); + ret = APPSPAWN_ERROR_UTILS_MEM_FAIL; + goto EXIT; + } + pathInfo.pathLen = static_cast(strlen(pathInfo.path)); + pathInfo.mode = SANDBOX_MODE_WRITE | SANDBOX_MODE_READ; + decPolicyInfo.path[0] = pathInfo; + } + decPolicyInfo.tokenId = tokenInfo->accessTokenIdEx; + decPolicyInfo.flag = true; + SetDecPolicyInfos(&decPolicyInfo); +EXIT: + for (uint32_t i = 0; i < decPolicyInfo.pathNum; i++) { + if (decPolicyInfo.path[0].path) { + free(decPolicyInfo.path[0].path); + decPolicyInfo.path[0].path = nullptr; + } + } + return ret; +} + static bool CheckMountFlag(const AppSpawningCtx *appProperty, const std::string bundleName, nlohmann::json &appConfig) { if (appConfig.find(g_flags) != appConfig.end()) { @@ -967,6 +1070,7 @@ int SandboxUtils::DoAllMntPointsMount(const AppSpawningCtx *appProperty, #endif return ret, "DoAppSandboxMountOnce section %{public}s failed, %{public}s", section.c_str(), arg.destPath); + SetDecPolicyWithPermission(appProperty, mountConfig); DoSandboxChmod(mntPoint, sandboxRoot); } return 0; @@ -1858,10 +1962,12 @@ int32_t SandboxUtils::SetAppSandboxProperty(AppSpawningCtx *appProperty, uint32_ rc = ChangeCurrentDir(sandboxPackagePath, bundleName, sandboxSharedStatus); APPSPAWN_CHECK(rc == 0, return rc, "change current dir failed"); APPSPAWN_LOGV("Change root dir success"); +#endif + SetDecWithDir(appProperty, dacInfo->uid / UID_BASE); + SetDecPolicy(); #if defined(APPSPAWN_MOUNT_TMPSHM) && defined(WITH_SELINUX) Restorecon(DEV_SHM_DIR); -#endif // APPSPAWN_MOUNT_TMPSHM && WITH_SELINUX -#endif // APPSPAWN_TEST +#endif return 0; } diff --git a/modules/sandbox/sandbox_utils.h b/modules/sandbox/sandbox_utils.h index e4cc70b4b9e8eae420e24e5915eca69f67bbc706..145e75337c93f64728c97e6398f3c55b426d3dba 100755 --- a/modules/sandbox/sandbox_utils.h +++ b/modules/sandbox/sandbox_utils.h @@ -47,6 +47,7 @@ public: std::string optionsPoint; std::string fsType; std::string sandboxPath; + std::vector decPaths; } SandboxMountConfig; #ifndef APPSPAWN_TEST @@ -73,6 +74,8 @@ private: static int32_t DoSandboxRootFolderCreateAdapt(std::string &sandboxPackagePath); static int32_t DoSandboxRootFolderCreate(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath); + static int32_t SetDecPolicyWithPermission(const AppSpawningCtx *appProperty, SandboxMountConfig &mountConfig); + static int32_t SetDecWithDir(const AppSpawningCtx *appProperty, uint32_t userId); static void DoSandboxChmod(nlohmann::json jsonConfig, std::string &sandboxRoot); static int DoAllMntPointsMount(const AppSpawningCtx *appProperty, nlohmann::json &appConfig, const char *typeName, const std::string §ion = "app-base"); @@ -115,6 +118,7 @@ private: static unsigned long GetSandboxMountFlags(nlohmann::json &config); static std::string GetSandboxFsType(nlohmann::json &config); static std::string GetSandboxOptions(const AppSpawningCtx *appProperty, nlohmann::json &config); + static std::vector GetSandboxDecPath(const AppSpawningCtx *appProperty, nlohmann::json &config); static std::string GetSandboxPath(const AppSpawningCtx *appProperty, nlohmann::json &mntPoint, const std::string §ion, std::string sandboxRoot); static void GetSandboxMountConfig(const AppSpawningCtx *appProperty, const std::string §ion, diff --git a/test/unittest/app_spawn_standard_test/BUILD.gn b/test/unittest/app_spawn_standard_test/BUILD.gn index 92ece3b5cff4a02fbd1fa9e02dca15096dda55ba..d18adc97e635da592c7cefc2c416c6c60edd1d8b 100644 --- a/test/unittest/app_spawn_standard_test/BUILD.gn +++ b/test/unittest/app_spawn_standard_test/BUILD.gn @@ -109,6 +109,7 @@ ohos_unittest("AppSpawn_ut") { "${appspawn_path}/modules/sandbox/appspawn_sandbox.c", "${appspawn_path}/modules/sandbox/sandbox_adapter.cpp", "${appspawn_path}/modules/sandbox/sandbox_cfgvar.c", + "${appspawn_path}/modules/sandbox/sandbox_dec.c", "${appspawn_path}/modules/sandbox/sandbox_expand.c", "${appspawn_path}/modules/sandbox/sandbox_load.c", "${appspawn_path}/modules/sandbox/sandbox_manager.c", @@ -309,6 +310,7 @@ ohos_unittest("AppSpawn_coldrun_ut") { "${appspawn_path}/modules/sandbox/appspawn_sandbox.c", "${appspawn_path}/modules/sandbox/sandbox_adapter.cpp", "${appspawn_path}/modules/sandbox/sandbox_cfgvar.c", + "${appspawn_path}/modules/sandbox/sandbox_dec.c", "${appspawn_path}/modules/sandbox/sandbox_expand.c", "${appspawn_path}/modules/sandbox/sandbox_load.c", "${appspawn_path}/modules/sandbox/sandbox_manager.c", @@ -500,6 +502,7 @@ ohos_unittest("AppSpawn_common_ut") { "${appspawn_path}/modules/sandbox/appspawn_sandbox.c", "${appspawn_path}/modules/sandbox/sandbox_adapter.cpp", "${appspawn_path}/modules/sandbox/sandbox_cfgvar.c", + "${appspawn_path}/modules/sandbox/sandbox_dec.c", "${appspawn_path}/modules/sandbox/sandbox_expand.c", "${appspawn_path}/modules/sandbox/sandbox_load.c", "${appspawn_path}/modules/sandbox/sandbox_manager.c", diff --git a/test/unittest/app_spawn_standard_test/app_spawn_sandbox_test.cpp b/test/unittest/app_spawn_standard_test/app_spawn_sandbox_test.cpp index 85a6f01e2ff0490c6c4be91354dba7d848b0b803..b4abd5953c7e658fb31a2b1efad603ff3c38e3a0 100644 --- a/test/unittest/app_spawn_standard_test/app_spawn_sandbox_test.cpp +++ b/test/unittest/app_spawn_standard_test/app_spawn_sandbox_test.cpp @@ -28,6 +28,7 @@ #include "app_spawn_stub.h" #include "app_spawn_test_helper.h" +#include "sandbox_dec.h" #include "sandbox_shared_mount.h" using namespace testing; @@ -1552,6 +1553,173 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_AppExtension_009, TestSize.Level AppSpawnClientDestroy(clientHandle); } +/** + * @tc.name: App_Spawn_Sandbox_dec_01 + * @tc.desc: parse config file for dec paths. + * @tc.type: FUNC + * @tc.author: + */ +#define DEC_PATH_SIZE 3 +HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_dec_01, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "App_Spawn_Sandbox_dec_01 start"; + std::string mJsconfig = "{ \ + \"mount-paths\": [{ \ + \"src-path\": \"\", \ + \"sandbox-path\": \"\", \ + \"sandbox-flags-customized\": [ \"MS_NODEV\", \"MS_RDONLY\" ], \ + \"dec-paths\": [ \"/storage/Users\", \"/storage/External\", \"/storage/test\"] \ + }] \ + }"; + nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); + const char *mountPath = "mount-paths"; + nlohmann::json j_secondConfig = j_config[mountPath][0]; + std::string section = "permission"; + OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); + OHOS::AppSpawn::SandboxUtils::SandboxMountConfig mountConfig; + AppSpawningCtx *appProperty = GetTestAppProperty(); + OHOS::AppSpawn::SandboxUtils::GetSandboxMountConfig(appProperty, section, j_secondConfig, mountConfig); + int decPathSize = mountConfig.decPaths.size(); + EXPECT_EQ(decPathSize, DEC_PATH_SIZE); + int ret = strcmp(mountConfig.decPaths[0].c_str(), "/storage/Users"); + EXPECT_EQ(ret, 0); + ret = strcmp(mountConfig.decPaths[1].c_str(), "/storage/External"); + EXPECT_EQ(ret, 0); + ret = strcmp(mountConfig.decPaths[2].c_str(), "/storage/test"); + EXPECT_EQ(ret, 0); + GTEST_LOG_(INFO) << "App_Spawn_Sandbox_dec_01 end"; +} + +/** + * @tc.name: App_Spawn_Sandbox_dec_02 + * @tc.desc: parse config file for dec paths. + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_dec_02, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "App_Spawn_Sandbox_dec_02 start"; + std::string mJsconfig = "{ \ + \"mount-paths\": [{ \ + \"src-path\": \"\", \ + \"sandbox-path\": \"\", \ + \"sandbox-flags-customized\": [ \"MS_NODEV\", \"MS_RDONLY\" ], \ + \"dec-paths\": [ ] \ + }] \ + }"; + nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); + const char *mountPath = "mount-paths"; + nlohmann::json j_secondConfig = j_config[mountPath][0]; + std::string section = "permission"; + OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); + OHOS::AppSpawn::SandboxUtils::SandboxMountConfig mountConfig; + AppSpawningCtx *appProperty = GetTestAppProperty(); + OHOS::AppSpawn::SandboxUtils::GetSandboxMountConfig(appProperty, section, j_secondConfig, mountConfig); + int decPathSize = mountConfig.decPaths.size(); + EXPECT_EQ(decPathSize, 0); + + GTEST_LOG_(INFO) << "App_Spawn_Sandbox_dec_02 end"; +} + +/** + * @tc.name: App_Spawn_Sandbox_dec_03 + * @tc.desc: parse config file for set policy. + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_dec_03, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "App_Spawn_Sandbox_dec_03 start"; + std::string mJsconfig = "{ \ + \"mount-paths\": [{ \ + \"src-path\": \"\", \ + \"sandbox-path\": \"\", \ + \"sandbox-flags-customized\": [ \"MS_NODEV\", \"MS_RDONLY\" ], \ + \"dec-paths\": [ \"/storage/Users\", \"/storage/External\", \"/storage/test\"] \ + }] \ + }"; + nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); + const char *mountPath = "mount-paths"; + nlohmann::json j_secondConfig = j_config[mountPath][0]; + std::string section = "permission"; + OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); + OHOS::AppSpawn::SandboxUtils::SandboxMountConfig mountConfig; + AppSpawningCtx *appProperty = GetTestAppProperty(); + OHOS::AppSpawn::SandboxUtils::GetSandboxMountConfig(appProperty, section, j_secondConfig, mountConfig); + int decPathSize = mountConfig.decPaths.size(); + EXPECT_EQ(decPathSize, DEC_PATH_SIZE); + OHOS::AppSpawn::SandboxUtils::SetDecPolicyWithPermission(appProperty, mountConfig); + GTEST_LOG_(INFO) << "App_Spawn_Sandbox_dec_03 end"; +} + +/** + * @tc.name: App_Spawn_Sandbox_dec_04 + * @tc.desc: parse config file for mount. + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_dec_04, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "App_Spawn_Sandbox_dec_04 start"; + std::string mJsconfig = "{ \ + \"mount-paths\": [{ \ + \"src-path\": \"\", \ + \"sandbox-path\": \"\", \ + \"sandbox-flags-customized\": [ \"MS_NODEV\", \"MS_RDONLY\" ], \ + \"dec-paths\": [ \"/storage/Users\", \"/storage/External\", \"/storage/test\"] \ + }] \ + }"; + nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); + const char *mountPath = "mount-paths"; + nlohmann::json j_secondConfig = j_config[mountPath][0]; + std::string section = "permission"; + OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); + OHOS::AppSpawn::SandboxUtils::SandboxMountConfig mountConfig; + AppSpawningCtx *appProperty = GetTestAppProperty(); + OHOS::AppSpawn::SandboxUtils::GetSandboxMountConfig(appProperty, section, j_secondConfig, mountConfig); + int decPathSize = mountConfig.decPaths.size(); + EXPECT_EQ(decPathSize, DEC_PATH_SIZE); + + int ret = OHOS::AppSpawn::SandboxUtils::DoAllMntPointsMount(appProperty, j_config, nullptr, "permission"); + EXPECT_EQ(ret, 0); + + GTEST_LOG_(INFO) << "App_Spawn_Sandbox_dec_04 end"; +} + +/** + * @tc.name: App_Spawn_Sandbox_dec_05 + * @tc.desc: parse config file for READ_WRITE_DOWNLOAD_DIRECTORY. + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_dec_05, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "App_Spawn_Sandbox_dec_05 start"; + std::string mJsconfig = "{ \ + \"mount-paths\": [{ \ + \"src-path\": \"\", \ + \"sandbox-path\": \"\", \ + \"sandbox-flags-customized\": [ \"MS_NODEV\", \"MS_RDONLY\" ], \ + \"dec-paths\": [ \"/storage/Users//Download\" ] \ + }] \ + }"; + nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); + const char *mountPath = "mount-paths"; + nlohmann::json j_secondConfig = j_config[mountPath][0]; + std::string section = "permission"; + OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); + OHOS::AppSpawn::SandboxUtils::SandboxMountConfig mountConfig; + AppSpawningCtx *appProperty = GetTestAppProperty(); + OHOS::AppSpawn::SandboxUtils::GetSandboxMountConfig(appProperty, section, j_secondConfig, mountConfig); + int decPathSize = mountConfig.decPaths.size(); + EXPECT_EQ(decPathSize, 1); + + int ret = OHOS::AppSpawn::SandboxUtils::DoAllMntPointsMount(appProperty, j_config, nullptr, "permission"); + EXPECT_EQ(ret, 0); + + GTEST_LOG_(INFO) << "App_Spawn_Sandbox_dec_05 end"; +} + /** * @tc.name: App_Spawn_Sandbox_Shared_Mount_01 * @tc.desc: [IsValidDataGroupItem] input valid param