sync:new sandbox and old sandbox module

Signed-off-by: wangfeng <wangfeng277@huawei.com>
This commit is contained in:
wangfeng 2024-08-12 14:33:26 +08:00
parent f8a9451d03
commit 409215f530
6 changed files with 188 additions and 37 deletions

View File

@ -1,7 +1,7 @@
{
"global": {
"sandbox-root": "/mnt/sandbox/<currentUserId>/app-root",
"sandbox-ns-flags": [ "pid" ]
"sandbox-ns-flags": [ "net" ]
},
"required": {
"system-const": {
@ -27,8 +27,11 @@
"src-path" : "/system/fonts",
"sandbox-path" : "/system/fonts"
}, {
"src-path" : "/system/<lib>",
"sandbox-path" : "/system/<lib>"
"src-path" : "/system/lib",
"sandbox-path" : "/system/lib"
}, {
"src-path" : "/system/lib64",
"sandbox-path" : "/system/lib64"
}, {
"src-path" : "/system/<lib>/platformsdk",
"sandbox-path" : "/system/<lib>/platformsdk"
@ -191,7 +194,7 @@
"src-path": "/storage/media/<currentUserId>/local/files/.Recent",
"sandbox-path": "/storage/Users/<currentUserId>/.Recent"
}],
"mount-groups": [ "user-public" ]
"mount-groups": [ "user-public", "Users" ]
}, {
"name": "ohos.permission.READ_IMAGEVIDEO",
"sandbox-switch": "ON",
@ -297,6 +300,21 @@
"src-path": "/data/hwbackup",
"sandbox-path": "/data/hwbackup"
}]
}, {
"name": "ohos.permission.ACCESS_DLP_FILE",
"sandbox-switch": "ON",
"sandbox-shared" : "true",
"mount-paths": [{
"src-path": "/mnt/data/<currentUserId>",
"sandbox-path": "/mnt/data",
"category": "shared",
"check-action-status": "true"
}, {
"src-path": "/mnt/data/<currentUserId>",
"sandbox-path": "/mnt/data",
"category": "dlp_fuse"
}],
"mount-groups": ["dlpmgr"]
}],
"spawn-flag": [{
"name": "START_FLAGS_BACKUP",
@ -368,21 +386,6 @@
"check-action-status": "true"
}],
"symbol-links" : []
}, {
"name": "com.ohos.dlpmanager",
"sandbox-switch": "ON",
"sandbox-shared" : "true",
"mount-paths" :[{
"src-path" : "/mnt/data/<currentUserId>",
"sandbox-path" : "/mnt/data",
"category": "shared",
"check-action-status": "true"
}, {
"src-path" : "/dev/fuse",
"sandbox-path" : "/mnt/data/fuse",
"category": "dlp_fuse"
}],
"mount-groups": ["dlpmgr"]
}, {
"name" : "com.ohos.permissionmanager",
"sandbox-switch": "ON",
@ -405,12 +408,25 @@
"src-path": "/mnt/data/external",
"sandbox-path": "/storage/External"
}]
}, {
"name": "Users",
"type": "app-variable",
"deps-mode": "not-exists",
"mount-paths-deps": {
"src-path": "/mnt/sandbox/<currentUserId>/<PackageName>/storage/Users",
"sandbox-path": "/storage/Users",
"category": "shared"
},
"mount-paths": [{
"src-path": "/storage/media/<currentUserId>/local/files/Docs",
"sandbox-path": "<deps-path>/currentUser"
}]
}, {
"name": "el2",
"type": "app-variable",
"deps-mode": "not-exists",
"mount-paths-deps": {
"src-path": "/data/app/el2/<currentUserId>/base",
"src-path": "/mnt/sandbox/<currentUserId>/<PackageName>/data/storage/el2",
"sandbox-path": "/data/storage/el2",
"category": "shared"
},

View File

@ -27,12 +27,16 @@
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include "securec.h"
#include "appspawn_msg.h"
#include "appspawn_utils.h"
#include "init_utils.h"
#include "parameter.h"
#include "securec.h"
#include "appspawn_permission.h"
#define USER_ID_SIZE 16
#define DIR_MODE 0711
static inline void SetMountPathOperation(uint32_t *operation, uint32_t index)
{
@ -199,6 +203,16 @@ static int InitSandboxContext(SandboxContext *context,
context->sandboxNsFlags |= sandbox->sandboxNsFlags & CLONE_NEWNET ? CLONE_NEWNET : 0;
}
ListNode *node = sandbox->permissionQueue.front.next;
while (node != &sandbox->permissionQueue.front) {
SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node);
if (permissionNode == NULL) {
return -1;
}
context->sandboxShared = packageNode->section.sandboxShared;
node = node->next;
}
// root path
const char *rootPath = GetSandboxRealVar(context, BUFFER_FOR_SOURCE, sandbox->rootPath, NULL, NULL);
if (rootPath) {
@ -234,9 +248,9 @@ static uint32_t GetMountArgs(const SandboxContext *context,
args->fsType = tmp->fsType;
args->options = tmp->options;
args->mountFlags = tmp->mountFlags;
if (CHECK_FLAGS_BY_INDEX(operation, SANDBOX_TAG_PERMISSION)) {
if (CHECK_FLAGS_BY_INDEX(operation, SANDBOX_TAG_PERMISSION) ||
CHECK_FLAGS_BY_INDEX(operation, SANDBOX_TAG_SPAWN_FLAGS)) {
if (!((category == MOUNT_TMP_DAC_OVERRIDE) && context->appFullMountEnable)) {
args->fsType = "";
args->options = "";
}
}
@ -496,6 +510,98 @@ static int DoSandboxNodeMount(const SandboxContext *context, const SandboxSectio
return 0;
}
static bool IsUnlockStatus(uint32_t uid)
{
const int userIdBase = UID_BASE;
uid = uid / userIdBase;
if (uid == 0) {
return true;
}
const char rootPath[] = "/data/app/el2/";
const char basePath[] = "/base";
size_t allPathSize = strlen(rootPath) + strlen(basePath) + 1 + USER_ID_SIZE;
char *path = (char *)malloc(sizeof(char) * allPathSize);
APPSPAWN_CHECK(path != NULL, return true, "Failed to malloc path");
int len = sprintf_s(path, allPathSize, "%s%u%s", rootPath, uid, basePath);
APPSPAWN_CHECK(len > 0 && ((size_t)len < allPathSize), return true, "Failed to get base path");
if (access(path, F_OK) == 0) {
APPSPAWN_LOGI("this is unlock status");
free(path);
return true;
}
free(path);
APPSPAWN_LOGI("this is lock status");
return false;
}
static void MountDir(AppSpawnMsgDacInfo *info, const char *bundleName, const char *rootPath, const char *targetPath)
{
if (info == NULL || bundleName == NULL || rootPath == NULL || targetPath == NULL) {
return;
}
const int userIdBase = UID_BASE;
size_t allPathSize = strlen(rootPath) + strlen(targetPath) + strlen(bundleName) + 2;
allPathSize += USER_ID_SIZE;
char *path = (char *)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 (access(path, F_OK) == 0) {
free(path);
return;
}
MakeDirRec(path, DIR_MODE, 1);
if (mount(path, path, NULL, MS_BIND | MS_REC, NULL) != 0) {
APPSPAWN_LOGI("bind mount %{public}s failed, error %{public}d", path, errno);
free(path);
return;
}
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;
}
APPSPAWN_LOGI("mount path %{public}s to shared success", path);
free(path);
return;
}
static const MountSharedTemplate MOUNT_SHARED_MAP[] = {
{"/data/storage/el2", NULL},
{"/data/storage/el3", NULL},
{"/data/storage/el4", NULL},
{"/data/storage/el5", "ohos.permission.PROTECT_SCREEN_LOCK_DATA"},
{"/storage/Users", "ohos.permission.FILE_ACCESS_MANAGER"},
};
static void MountDirToShared(const SandboxContext *context, AppSpawnSandboxCfg *sandbox)
{
const char rootPath[] = "/mnt/sandbox/";
AppSpawnMsgDacInfo *info = (AppSpawnMsgDacInfo *)GetSpawningMsgInfo(context, TLV_DAC_INFO);
if (info == NULL || IsUnlockStatus(info->uid)) {
return;
}
int length = sizeof(MOUNT_SHARED_MAP) / sizeof(MOUNT_SHARED_MAP[0]);
for (int i = 0; i < length; i++) {
if (MOUNT_SHARED_MAP[i].permission == NULL) {
MountDir(info, context->bundleName, rootPath, MOUNT_SHARED_MAP[i].sandboxPath);
} else {
int index = GetPermissionIndexInQueue(&sandbox->permissionQueue, MOUNT_SHARED_MAP[i].permission);
APPSPAWN_LOGV("mount dir on lock mountPermissionFlags %{public}d", index);
if (CheckSpawningPermissionFlagSet(context, index)) {
MountDir(info, context->bundleName, rootPath, MOUNT_SHARED_MAP[i].sandboxPath);
}
}
}
}
static int UpdateMountPathDepsPath(const SandboxContext *context, SandboxNameGroupNode *groupNode)
{
PathMountNode *depNode = groupNode->depNode;
@ -837,7 +943,20 @@ int UnmountSandboxConfigs(const AppSpawnSandboxCfg *sandbox, uid_t uid, const ch
return 0;
}
int StagedMountSystemConst(const AppSpawnSandboxCfg *sandbox, const AppSpawningCtx *property, int nwebspawn)
// Check whether the process incubation contains the ohos.permission.ACCESS_DLP_FILE permission
static bool IsADFPermision(AppSpawnSandboxCfg *sandbox, const AppSpawningCtx *property)
{
int index = GetPermissionIndexInQueue(&sandbox->permissionQueue, ACCESS_DLP_FILE_MODE);
if (index > 0 && CheckAppPermissionFlagSet(property, index)) {
return true;
}
if (strstr(GetBundleName(property), "ohos.permission.dlpmanager") != NULL) {
return true;
}
return false;
}
int StagedMountSystemConst(AppSpawnSandboxCfg *sandbox, const AppSpawningCtx *property, int nwebspawn)
{
APPSPAWN_CHECK(sandbox != NULL, return -1, "Failed to get sandbox for %{public}s", GetProcessName(property));
/**
@ -861,7 +980,7 @@ int StagedMountSystemConst(const AppSpawnSandboxCfg *sandbox, const AppSpawningC
int ret = InitSandboxContext(context, sandbox, property, nwebspawn);
APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
if (IsSandboxMounted(sandbox, "system-const", context->rootPath)) {
if (IsSandboxMounted(sandbox, "system-const", context->rootPath) && IsADFPermision(sandbox, property) != true) {
APPSPAWN_LOGV("Sandbox system-const %{public}s has been mount", context->rootPath);
DeleteSandboxContext(context);
return 0;
@ -879,21 +998,22 @@ int StagedMountSystemConst(const AppSpawnSandboxCfg *sandbox, const AppSpawningC
return ret;
}
int StagedMountPreUnShare(const SandboxContext *context, const AppSpawnSandboxCfg *sandbox)
int StagedMountPreUnShare(const SandboxContext *context, AppSpawnSandboxCfg *sandbox)
{
APPSPAWN_CHECK(sandbox != NULL && context != NULL, return -1, "Invalid sandbox or context");
APPSPAWN_LOGV("Set sandbox config before unshare group count %{public}d", sandbox->depNodeCount);
MountDirToShared(context, sandbox);
/**
* unshare前处理mount-paths-deps
* root-dir global.sandbox-root
* src-dir "/mnt/sandbox/app-common/<currentUserId>"
* mount-paths-depsmount-paths-deps
* mount-paths-deps,mount-paths-deps
* src = mount-paths-deps.src-path
* dst = root-dir + mount-paths-deps.sandbox-path
* no-existmount-paths src
mount-paths-deps.src-path shared方式挂载mount-paths-deps
* alwaysshared方式挂载mount-paths-deps
* no-exist,mount-paths src()
mount-paths-deps.src-path .shared方式挂载mount-paths-deps
* always,shared方式挂载mount-paths-deps
* always
*
*/
@ -977,7 +1097,7 @@ int StagedMountPostUnshare(const SandboxContext *context, const AppSpawnSandboxC
return ret;
}
int MountSandboxConfigs(const AppSpawnSandboxCfg *sandbox, const AppSpawningCtx *property, int nwebspawn)
int MountSandboxConfigs(AppSpawnSandboxCfg *sandbox, const AppSpawningCtx *property, int nwebspawn)
{
APPSPAWN_CHECK_ONLY_EXPER(property != NULL, return -1);
APPSPAWN_CHECK(sandbox != NULL, return -1, "Failed to get sandbox for %{public}s", GetProcessName(property));

View File

@ -67,6 +67,9 @@ extern "C" {
#define MOUNT_PATH_OP_REPLACE_BY_SANDBOX (SANDBOX_TAG_INVALID + 3)
#define MOUNT_PATH_OP_REPLACE_BY_SRC (SANDBOX_TAG_INVALID + 4)
#define FILE_CROSS_APP_MODE "ohos.permission.FILE_CROSS_APP"
#define FILE_ACCESS_COMMON_DIR_MODE "ohos.permission.FILE_ACCESS_COMMON_DIR"
#define ACCESS_DLP_FILE_MODE "ohos.permission.ACCESS_DLP_FILE"
#define FILE_ACCESS_MANAGER_MODE "ohos.permission.FILE_ACCESS_MANAGER"
typedef enum SandboxTag {
SANDBOX_TAG_MOUNT_PATH = 0,
@ -208,6 +211,11 @@ typedef struct TagSandboxContext {
char *rootPath;
} SandboxContext;
typedef struct {
const char *sandboxPath;
const char *permission;
} MountSharedTemplate;
/**
* @brief AppSpawnSandboxCfg op
*
@ -247,9 +255,9 @@ SymbolLinkNode *GetSymbolLinkNode(const SandboxSection *section, const char *tar
* @brief sandbox mount interface
*
*/
int MountSandboxConfigs(const AppSpawnSandboxCfg *sandbox, const AppSpawningCtx *property, int nwebspawn);
int StagedMountSystemConst(const AppSpawnSandboxCfg *sandbox, const AppSpawningCtx *property, int nwebspawn);
int StagedMountPreUnShare(const SandboxContext *context, const AppSpawnSandboxCfg *sandbox);
int MountSandboxConfigs(AppSpawnSandboxCfg *sandbox, const AppSpawningCtx *property, int nwebspawn);
int StagedMountSystemConst(AppSpawnSandboxCfg *sandbox, const AppSpawningCtx *property, int nwebspawn);
int StagedMountPreUnShare(const SandboxContext *context, AppSpawnSandboxCfg *sandbox);
int StagedMountPostUnshare(const SandboxContext *context, const AppSpawnSandboxCfg *sandbox);
// 在子进程退出时由父进程发起unmount操作
int UnmountDepPaths(const AppSpawnSandboxCfg *sandbox, uid_t uid);

View File

@ -25,7 +25,7 @@
#include "securec.h"
#define SANDBOX_GROUP_PATH "/data/storage/el2/group/"
#define SANDBOX_INSTALL_PATH "/data/storage/el2/group/"
#define SANDBOX_INSTALL_PATH "/data/storage/el1/bundle/"
#define SANDBOX_OVERLAY_PATH "/data/storage/overlay/"
static inline bool CheckPath(const char *name)
@ -164,6 +164,7 @@ 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);
MountArg mountArg = {
sandboxContext->buffer[0].buffer, sandboxContext->buffer[1].buffer, NULL, MS_REC | MS_BIND, NULL, MS_SHARED
};

View File

@ -209,6 +209,7 @@ static PathMountNode *DecodeMountPathConfig(const SandboxSection *section, const
if (srcPath == NULL || dstPath == NULL) {
return NULL;
}
PathMountNode *tmp = GetPathMountNode(section, type, srcPath, dstPath);
if (tmp != NULL) { // 删除老的节点,保存新的节点
DeleteSandboxMountNode((SandboxMountNode *)tmp);
@ -401,6 +402,7 @@ static int ParseBaseConfig(AppSpawnSandboxCfg *sandbox, SandboxSection *section,
APPSPAWN_CHECK(cJSON_IsObject(configs),
return APPSPAWN_SANDBOX_INVALID, "Invalid config %{public}s", section->name);
APPSPAWN_LOGV("Parse sandbox %{public}s", section->name);
// "sandbox-switch": "ON", default sandbox switch is on
section->sandboxSwitch = GetBoolValueFromJsonObj(configs, "sandbox-switch", true);
// "sandbox-shared"
@ -412,21 +414,25 @@ static int ParseBaseConfig(AppSpawnSandboxCfg *sandbox, SandboxSection *section,
ret = ParseGidTableConfig(sandbox, gidTabJson, section);
APPSPAWN_CHECK(ret == 0, return ret, "Parse gids for %{public}s", section->name);
}
cJSON *pathConfigs = cJSON_GetObjectItemCaseSensitive(configs, "mount-paths");
if (pathConfigs != NULL) { // mount-paths
ret = ParseMountPathsConfig(sandbox, pathConfigs, section, SANDBOX_TAG_MOUNT_PATH);
APPSPAWN_CHECK(ret == 0, return ret, "Parse mount-paths for %{public}s", section->name);
}
pathConfigs = cJSON_GetObjectItemCaseSensitive(configs, "mount-files");
if (pathConfigs != NULL) { // mount-files
ret = ParseMountPathsConfig(sandbox, pathConfigs, section, SANDBOX_TAG_MOUNT_FILE);
APPSPAWN_CHECK(ret == 0, return ret, "Parse mount-paths for %{public}s", section->name);
}
pathConfigs = cJSON_GetObjectItemCaseSensitive(configs, "symbol-links");
if (pathConfigs != NULL) { // symbol-links
ret = ParseSymbolLinksConfig(sandbox, pathConfigs, section);
APPSPAWN_CHECK(ret == 0, return ret, "Parse symbol-links for %{public}s", section->name);
}
cJSON *groupConfig = cJSON_GetObjectItemCaseSensitive(configs, "mount-groups");
if (groupConfig != NULL) {
ret = ParseMountGroupsConfig(sandbox, groupConfig, section);

View File

@ -486,7 +486,7 @@ HWTEST_F(AppSpawnSandboxMgrTest, App_Spawn_Mount_001, TestSize.Level0)
// 只做异常测试,正常流程需要基于业务流进行测试
const AppSpawningCtx *inputAppSpawningCtx[2] = {property, nullptr};
const AppSpawnSandboxCfg *inputAppSpawnSandboxCfg[2] = {sandbox, nullptr};
AppSpawnSandboxCfg *inputAppSpawnSandboxCfg[2] = {sandbox, nullptr};
uint32_t inputSpawn[3] = {0, 1, 2};
int ret = 0;
for (uint32_t i = 0; i < 2; i++) { // 2
@ -524,7 +524,7 @@ HWTEST_F(AppSpawnSandboxMgrTest, App_Spawn_Mount_002, TestSize.Level0)
SandboxContext context = {};
// 只做异常测试,正常流程需要基于业务流进行测试
const SandboxContext *inputContext[2] = {&context, nullptr};
const AppSpawnSandboxCfg *inputAppSpawnSandboxCfg[2] = {sandbox, nullptr};
AppSpawnSandboxCfg *inputAppSpawnSandboxCfg[2] = {sandbox, nullptr};
int ret = 0;
for (uint32_t i = 0; i < 2; i++) { // 2