169570cc8Sopenharmony_ci/* 269570cc8Sopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd. 369570cc8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 469570cc8Sopenharmony_ci * you may not use this file except in compliance with the License. 569570cc8Sopenharmony_ci * You may obtain a copy of the License at 669570cc8Sopenharmony_ci * 769570cc8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 869570cc8Sopenharmony_ci * 969570cc8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1069570cc8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1169570cc8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1269570cc8Sopenharmony_ci * See the License for the specific language governing permissions and 1369570cc8Sopenharmony_ci * limitations under the License. 1469570cc8Sopenharmony_ci */ 1569570cc8Sopenharmony_ci#include <ctype.h> 1669570cc8Sopenharmony_ci#include <stdbool.h> 1769570cc8Sopenharmony_ci#include <stdlib.h> 1869570cc8Sopenharmony_ci#ifndef _GNU_SOURCE 1969570cc8Sopenharmony_ci#define _GNU_SOURCE 2069570cc8Sopenharmony_ci#endif 2169570cc8Sopenharmony_ci#include <errno.h> 2269570cc8Sopenharmony_ci#include <fcntl.h> 2369570cc8Sopenharmony_ci#include <sched.h> 2469570cc8Sopenharmony_ci#include <stdio.h> 2569570cc8Sopenharmony_ci#include <unistd.h> 2669570cc8Sopenharmony_ci 2769570cc8Sopenharmony_ci#include <sys/mount.h> 2869570cc8Sopenharmony_ci#include <sys/types.h> 2969570cc8Sopenharmony_ci 3069570cc8Sopenharmony_ci#include "appspawn_msg.h" 3169570cc8Sopenharmony_ci#include "appspawn_permission.h" 3269570cc8Sopenharmony_ci#include "appspawn_sandbox.h" 3369570cc8Sopenharmony_ci#include "appspawn_utils.h" 3469570cc8Sopenharmony_ci#include "cJSON.h" 3569570cc8Sopenharmony_ci#include "init_utils.h" 3669570cc8Sopenharmony_ci#include "json_utils.h" 3769570cc8Sopenharmony_ci#include "parameter.h" 3869570cc8Sopenharmony_ci#include "securec.h" 3969570cc8Sopenharmony_ci 4069570cc8Sopenharmony_cistatic const SandboxFlagInfo NAMESPACE_FLAGS_MAP[] = { 4169570cc8Sopenharmony_ci {"pid", CLONE_NEWPID}, {"net", CLONE_NEWNET} 4269570cc8Sopenharmony_ci}; 4369570cc8Sopenharmony_ci 4469570cc8Sopenharmony_cistatic const SandboxFlagInfo FLAGE_POINT_MAP[] = { 4569570cc8Sopenharmony_ci {"0", 0}, 4669570cc8Sopenharmony_ci {"START_FLAGS_BACKUP", (unsigned long)APP_FLAGS_BACKUP_EXTENSION}, 4769570cc8Sopenharmony_ci {"DLP_MANAGER", (unsigned long)APP_FLAGS_DLP_MANAGER}, 4869570cc8Sopenharmony_ci {"DEVELOPER_MODE", (unsigned long)APP_FLAGS_DEVELOPER_MODE} 4969570cc8Sopenharmony_ci}; 5069570cc8Sopenharmony_ci 5169570cc8Sopenharmony_cistatic const SandboxFlagInfo MOUNT_MODE_MAP[] = { 5269570cc8Sopenharmony_ci {"not-exists", (unsigned long)MOUNT_MODE_NOT_EXIST}, 5369570cc8Sopenharmony_ci {"always", (unsigned long)MOUNT_MODE_ALWAYS} 5469570cc8Sopenharmony_ci}; 5569570cc8Sopenharmony_ci 5669570cc8Sopenharmony_cistatic const SandboxFlagInfo NAME_GROUP_TYPE_MAP[] = { 5769570cc8Sopenharmony_ci {"system-const", (unsigned long)SANDBOX_TAG_SYSTEM_CONST}, 5869570cc8Sopenharmony_ci {"app-variable", (unsigned long)SANDBOX_TAG_APP_VARIABLE} 5969570cc8Sopenharmony_ci}; 6069570cc8Sopenharmony_ci 6169570cc8Sopenharmony_cistatic inline PathMountNode *CreatePathMountNode(uint32_t type, uint32_t hasDemandInfo) 6269570cc8Sopenharmony_ci{ 6369570cc8Sopenharmony_ci uint32_t len = hasDemandInfo ? sizeof(PathDemandInfo) : 0; 6469570cc8Sopenharmony_ci return (PathMountNode *)CreateSandboxMountNode(sizeof(PathMountNode) + len, type); 6569570cc8Sopenharmony_ci} 6669570cc8Sopenharmony_ci 6769570cc8Sopenharmony_cistatic inline SymbolLinkNode *CreateSymbolLinkNode(void) 6869570cc8Sopenharmony_ci{ 6969570cc8Sopenharmony_ci return (SymbolLinkNode *)CreateSandboxMountNode(sizeof(SymbolLinkNode), SANDBOX_TAG_SYMLINK); 7069570cc8Sopenharmony_ci} 7169570cc8Sopenharmony_ci 7269570cc8Sopenharmony_cistatic inline SandboxPackageNameNode *CreateSandboxPackageNameNode(const char *name) 7369570cc8Sopenharmony_ci{ 7469570cc8Sopenharmony_ci return (SandboxPackageNameNode *)CreateSandboxSection(name, 7569570cc8Sopenharmony_ci sizeof(SandboxPackageNameNode), SANDBOX_TAG_PACKAGE_NAME); 7669570cc8Sopenharmony_ci} 7769570cc8Sopenharmony_ci 7869570cc8Sopenharmony_cistatic inline SandboxFlagsNode *CreateSandboxFlagsNode(const char *name) 7969570cc8Sopenharmony_ci{ 8069570cc8Sopenharmony_ci return (SandboxFlagsNode *)CreateSandboxSection(name, sizeof(SandboxFlagsNode), SANDBOX_TAG_SPAWN_FLAGS); 8169570cc8Sopenharmony_ci} 8269570cc8Sopenharmony_ci 8369570cc8Sopenharmony_cistatic inline SandboxNameGroupNode *CreateSandboxNameGroupNode(const char *name) 8469570cc8Sopenharmony_ci{ 8569570cc8Sopenharmony_ci return (SandboxNameGroupNode *)CreateSandboxSection(name, sizeof(SandboxNameGroupNode), SANDBOX_TAG_NAME_GROUP); 8669570cc8Sopenharmony_ci} 8769570cc8Sopenharmony_ci 8869570cc8Sopenharmony_cistatic inline SandboxPermissionNode *CreateSandboxPermissionNode(const char *name) 8969570cc8Sopenharmony_ci{ 9069570cc8Sopenharmony_ci size_t len = sizeof(SandboxPermissionNode); 9169570cc8Sopenharmony_ci SandboxPermissionNode *node = (SandboxPermissionNode *)CreateSandboxSection(name, len, SANDBOX_TAG_PERMISSION); 9269570cc8Sopenharmony_ci APPSPAWN_CHECK(node != NULL, return NULL, "Failed to create permission node"); 9369570cc8Sopenharmony_ci node->permissionIndex = 0; 9469570cc8Sopenharmony_ci return node; 9569570cc8Sopenharmony_ci} 9669570cc8Sopenharmony_ci 9769570cc8Sopenharmony_cistatic inline bool GetBoolParameter(const char *param, bool value) 9869570cc8Sopenharmony_ci{ 9969570cc8Sopenharmony_ci char tmp[32] = {0}; // 32 max 10069570cc8Sopenharmony_ci int ret = GetParameter(param, "", tmp, sizeof(tmp)); 10169570cc8Sopenharmony_ci APPSPAWN_LOGV("GetBoolParameter key %{public}s ret %{public}d result: %{public}s", param, ret, tmp); 10269570cc8Sopenharmony_ci if (ret > 0 && strcmp(tmp, "false") == 0) { 10369570cc8Sopenharmony_ci return false; 10469570cc8Sopenharmony_ci } 10569570cc8Sopenharmony_ci if (ret > 0 && strcmp(tmp, "true") == 0) { 10669570cc8Sopenharmony_ci return true; 10769570cc8Sopenharmony_ci } 10869570cc8Sopenharmony_ci return value; 10969570cc8Sopenharmony_ci} 11069570cc8Sopenharmony_ci 11169570cc8Sopenharmony_cistatic inline bool AppSandboxPidNsIsSupport(void) 11269570cc8Sopenharmony_ci{ 11369570cc8Sopenharmony_ci // only set false, return false 11469570cc8Sopenharmony_ci return GetBoolParameter("const.sandbox.pidns.support", true); 11569570cc8Sopenharmony_ci} 11669570cc8Sopenharmony_ci 11769570cc8Sopenharmony_cistatic inline bool CheckAppFullMountEnable(void) 11869570cc8Sopenharmony_ci{ 11969570cc8Sopenharmony_ci return GetBoolParameter("const.filemanager.full_mount.enable", false); 12069570cc8Sopenharmony_ci} 12169570cc8Sopenharmony_ci 12269570cc8Sopenharmony_ciAPPSPAWN_STATIC unsigned long GetMountModeFromConfig(const cJSON *config, const char *key, unsigned long def) 12369570cc8Sopenharmony_ci{ 12469570cc8Sopenharmony_ci char *value = cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(config, key)); 12569570cc8Sopenharmony_ci if (value == NULL) { 12669570cc8Sopenharmony_ci return def; 12769570cc8Sopenharmony_ci } 12869570cc8Sopenharmony_ci const SandboxFlagInfo *info = GetSandboxFlagInfo(value, MOUNT_MODE_MAP, ARRAY_LENGTH(MOUNT_MODE_MAP)); 12969570cc8Sopenharmony_ci if (info != NULL) { 13069570cc8Sopenharmony_ci return info->flags; 13169570cc8Sopenharmony_ci } 13269570cc8Sopenharmony_ci return def; 13369570cc8Sopenharmony_ci} 13469570cc8Sopenharmony_ci 13569570cc8Sopenharmony_cistatic uint32_t GetNameGroupTypeFromConfig(const cJSON *config, const char *key, unsigned long def) 13669570cc8Sopenharmony_ci{ 13769570cc8Sopenharmony_ci char *value = cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(config, key)); 13869570cc8Sopenharmony_ci if (value == NULL) { 13969570cc8Sopenharmony_ci return def; 14069570cc8Sopenharmony_ci } 14169570cc8Sopenharmony_ci const SandboxFlagInfo *info = GetSandboxFlagInfo(value, NAME_GROUP_TYPE_MAP, ARRAY_LENGTH(NAME_GROUP_TYPE_MAP)); 14269570cc8Sopenharmony_ci if (info != NULL) { 14369570cc8Sopenharmony_ci return (uint32_t)info->flags; 14469570cc8Sopenharmony_ci } 14569570cc8Sopenharmony_ci return def; 14669570cc8Sopenharmony_ci} 14769570cc8Sopenharmony_ci 14869570cc8Sopenharmony_cistatic uint32_t GetSandboxNsFlags(const cJSON *appConfig) 14969570cc8Sopenharmony_ci{ 15069570cc8Sopenharmony_ci uint32_t nsFlags = 0; 15169570cc8Sopenharmony_ci cJSON *obj = cJSON_GetObjectItemCaseSensitive(appConfig, "sandbox-ns-flags"); 15269570cc8Sopenharmony_ci if (obj == NULL || !cJSON_IsArray(obj)) { 15369570cc8Sopenharmony_ci return nsFlags; 15469570cc8Sopenharmony_ci } 15569570cc8Sopenharmony_ci int count = cJSON_GetArraySize(obj); 15669570cc8Sopenharmony_ci for (int i = 0; i < count; i++) { 15769570cc8Sopenharmony_ci char *value = cJSON_GetStringValue(cJSON_GetArrayItem(obj, i)); 15869570cc8Sopenharmony_ci const SandboxFlagInfo *info = GetSandboxFlagInfo(value, NAMESPACE_FLAGS_MAP, ARRAY_LENGTH(NAMESPACE_FLAGS_MAP)); 15969570cc8Sopenharmony_ci if (info != NULL) { 16069570cc8Sopenharmony_ci nsFlags |= info->flags; 16169570cc8Sopenharmony_ci } 16269570cc8Sopenharmony_ci } 16369570cc8Sopenharmony_ci return nsFlags; 16469570cc8Sopenharmony_ci} 16569570cc8Sopenharmony_ci 16669570cc8Sopenharmony_cistatic int SetMode(const char *str, void *context) 16769570cc8Sopenharmony_ci{ 16869570cc8Sopenharmony_ci mode_t *mode = (mode_t *)context; 16969570cc8Sopenharmony_ci *mode |= GetPathMode(str); 17069570cc8Sopenharmony_ci return 0; 17169570cc8Sopenharmony_ci} 17269570cc8Sopenharmony_ci 17369570cc8Sopenharmony_cistatic mode_t GetChmodFromJson(const cJSON *config) 17469570cc8Sopenharmony_ci{ 17569570cc8Sopenharmony_ci mode_t mode = 0; 17669570cc8Sopenharmony_ci char *modeStrs = GetStringFromJsonObj(config, "dest-mode"); 17769570cc8Sopenharmony_ci if (modeStrs == NULL) { 17869570cc8Sopenharmony_ci return mode; 17969570cc8Sopenharmony_ci } 18069570cc8Sopenharmony_ci (void)StringSplit(modeStrs, "|", (void *)&mode, SetMode); 18169570cc8Sopenharmony_ci return mode; 18269570cc8Sopenharmony_ci} 18369570cc8Sopenharmony_ci 18469570cc8Sopenharmony_ciAPPSPAWN_STATIC uint32_t GetFlagIndexFromJson(const cJSON *config) 18569570cc8Sopenharmony_ci{ 18669570cc8Sopenharmony_ci char *flagStr = GetStringFromJsonObj(config, "name"); 18769570cc8Sopenharmony_ci if (flagStr == NULL) { 18869570cc8Sopenharmony_ci return 0; 18969570cc8Sopenharmony_ci } 19069570cc8Sopenharmony_ci const SandboxFlagInfo *info = GetSandboxFlagInfo(flagStr, FLAGE_POINT_MAP, ARRAY_LENGTH(FLAGE_POINT_MAP)); 19169570cc8Sopenharmony_ci if (info != NULL) { 19269570cc8Sopenharmony_ci return info->flags; 19369570cc8Sopenharmony_ci } 19469570cc8Sopenharmony_ci return 0; 19569570cc8Sopenharmony_ci} 19669570cc8Sopenharmony_ci 19769570cc8Sopenharmony_cistatic void FillPathDemandInfo(const cJSON *config, PathMountNode *sandboxNode) 19869570cc8Sopenharmony_ci{ 19969570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(config != NULL, return); 20069570cc8Sopenharmony_ci sandboxNode->demandInfo->uid = GetIntValueFromJsonObj(config, "uid", -1); 20169570cc8Sopenharmony_ci sandboxNode->demandInfo->gid = GetIntValueFromJsonObj(config, "gid", -1); 20269570cc8Sopenharmony_ci sandboxNode->demandInfo->mode = GetIntValueFromJsonObj(config, "ugo", -1); 20369570cc8Sopenharmony_ci} 20469570cc8Sopenharmony_ci 20569570cc8Sopenharmony_cistatic PathMountNode *DecodeMountPathConfig(const SandboxSection *section, const cJSON *config, uint32_t type) 20669570cc8Sopenharmony_ci{ 20769570cc8Sopenharmony_ci char *srcPath = GetStringFromJsonObj(config, "src-path"); 20869570cc8Sopenharmony_ci char *dstPath = GetStringFromJsonObj(config, "sandbox-path"); 20969570cc8Sopenharmony_ci if (srcPath == NULL || dstPath == NULL) { 21069570cc8Sopenharmony_ci return NULL; 21169570cc8Sopenharmony_ci } 21269570cc8Sopenharmony_ci 21369570cc8Sopenharmony_ci PathMountNode *tmp = GetPathMountNode(section, type, srcPath, dstPath); 21469570cc8Sopenharmony_ci if (tmp != NULL) { // 删除老的节点,保存新的节点 21569570cc8Sopenharmony_ci DeleteSandboxMountNode((SandboxMountNode *)tmp); 21669570cc8Sopenharmony_ci APPSPAWN_LOGW("path %{public}s %{public}s repeat config, delete old", srcPath, dstPath); 21769570cc8Sopenharmony_ci } 21869570cc8Sopenharmony_ci 21969570cc8Sopenharmony_ci cJSON *demandInfo = cJSON_GetObjectItemCaseSensitive(config, "create-on-demand"); 22069570cc8Sopenharmony_ci PathMountNode *sandboxNode = CreatePathMountNode(type, demandInfo != NULL); 22169570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(sandboxNode != NULL, return NULL); 22269570cc8Sopenharmony_ci sandboxNode->createDemand = demandInfo != NULL; 22369570cc8Sopenharmony_ci sandboxNode->source = strdup(srcPath); 22469570cc8Sopenharmony_ci sandboxNode->target = strdup(dstPath); 22569570cc8Sopenharmony_ci 22669570cc8Sopenharmony_ci sandboxNode->destMode = GetChmodFromJson(config); 22769570cc8Sopenharmony_ci sandboxNode->mountSharedFlag = GetBoolValueFromJsonObj(config, "mount-shared-flag", false); 22869570cc8Sopenharmony_ci sandboxNode->checkErrorFlag = GetBoolValueFromJsonObj(config, "check-action-status", false); 22969570cc8Sopenharmony_ci 23069570cc8Sopenharmony_ci sandboxNode->category = GetMountCategory(GetStringFromJsonObj(config, "category")); 23169570cc8Sopenharmony_ci const char *value = GetStringFromJsonObj(config, "app-apl-name"); 23269570cc8Sopenharmony_ci if (value != NULL) { 23369570cc8Sopenharmony_ci sandboxNode->appAplName = strdup(value); 23469570cc8Sopenharmony_ci } 23569570cc8Sopenharmony_ci FillPathDemandInfo(demandInfo, sandboxNode); 23669570cc8Sopenharmony_ci 23769570cc8Sopenharmony_ci if (sandboxNode->source == NULL || sandboxNode->target == NULL) { 23869570cc8Sopenharmony_ci APPSPAWN_LOGE("Failed to get sourc or target path"); 23969570cc8Sopenharmony_ci DeleteSandboxMountNode((SandboxMountNode *)sandboxNode); 24069570cc8Sopenharmony_ci return NULL; 24169570cc8Sopenharmony_ci } 24269570cc8Sopenharmony_ci return sandboxNode; 24369570cc8Sopenharmony_ci} 24469570cc8Sopenharmony_ci 24569570cc8Sopenharmony_ciAPPSPAWN_STATIC int ParseMountPathsConfig(AppSpawnSandboxCfg *sandbox, 24669570cc8Sopenharmony_ci const cJSON *mountConfigs, SandboxSection *section, uint32_t type) 24769570cc8Sopenharmony_ci{ 24869570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(mountConfigs != NULL && cJSON_IsArray(mountConfigs), return -1); 24969570cc8Sopenharmony_ci 25069570cc8Sopenharmony_ci uint32_t mountPointSize = cJSON_GetArraySize(mountConfigs); 25169570cc8Sopenharmony_ci for (uint32_t i = 0; i < mountPointSize; i++) { 25269570cc8Sopenharmony_ci cJSON *mntJson = cJSON_GetArrayItem(mountConfigs, i); 25369570cc8Sopenharmony_ci if (mntJson == NULL) { 25469570cc8Sopenharmony_ci continue; 25569570cc8Sopenharmony_ci } 25669570cc8Sopenharmony_ci PathMountNode *sandboxNode = DecodeMountPathConfig(section, mntJson, type); 25769570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(sandboxNode != NULL, continue); 25869570cc8Sopenharmony_ci AddSandboxMountNode(&sandboxNode->sandboxNode, section); 25969570cc8Sopenharmony_ci } 26069570cc8Sopenharmony_ci return 0; 26169570cc8Sopenharmony_ci} 26269570cc8Sopenharmony_ci 26369570cc8Sopenharmony_cistatic SymbolLinkNode *DecodeSymbolLinksConfig(const SandboxSection *section, const cJSON *config) 26469570cc8Sopenharmony_ci{ 26569570cc8Sopenharmony_ci const char *target = GetStringFromJsonObj(config, "target-name"); 26669570cc8Sopenharmony_ci const char *linkName = GetStringFromJsonObj(config, "link-name"); 26769570cc8Sopenharmony_ci if (target == NULL || linkName == NULL) { 26869570cc8Sopenharmony_ci return NULL; 26969570cc8Sopenharmony_ci } 27069570cc8Sopenharmony_ci 27169570cc8Sopenharmony_ci SymbolLinkNode *tmp = GetSymbolLinkNode(section, target, linkName); 27269570cc8Sopenharmony_ci if (tmp != NULL) { // 删除老的节点,保存新的节点 27369570cc8Sopenharmony_ci DeleteSandboxMountNode((SandboxMountNode *)tmp); 27469570cc8Sopenharmony_ci APPSPAWN_LOGW("SymbolLink %{public}s %{public}s repeat config, delete old", target, linkName); 27569570cc8Sopenharmony_ci } 27669570cc8Sopenharmony_ci 27769570cc8Sopenharmony_ci SymbolLinkNode *node = CreateSymbolLinkNode(); 27869570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(node != NULL, return NULL); 27969570cc8Sopenharmony_ci node->destMode = GetChmodFromJson(config); 28069570cc8Sopenharmony_ci node->checkErrorFlag = GetBoolValueFromJsonObj(config, "check-action-status", false); 28169570cc8Sopenharmony_ci node->target = strdup(target); 28269570cc8Sopenharmony_ci node->linkName = strdup(linkName); 28369570cc8Sopenharmony_ci if (node->target == NULL || node->linkName == NULL) { 28469570cc8Sopenharmony_ci APPSPAWN_LOGE("Failed to get sourc or target path"); 28569570cc8Sopenharmony_ci DeleteSandboxMountNode((SandboxMountNode *)node); 28669570cc8Sopenharmony_ci return NULL; 28769570cc8Sopenharmony_ci } 28869570cc8Sopenharmony_ci return node; 28969570cc8Sopenharmony_ci} 29069570cc8Sopenharmony_ci 29169570cc8Sopenharmony_ciAPPSPAWN_STATIC int ParseSymbolLinksConfig(AppSpawnSandboxCfg *sandbox, const cJSON *symbolLinkConfigs, 29269570cc8Sopenharmony_ci SandboxSection *section) 29369570cc8Sopenharmony_ci{ 29469570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(symbolLinkConfigs != NULL && cJSON_IsArray(symbolLinkConfigs), return -1); 29569570cc8Sopenharmony_ci uint32_t symlinkPointSize = cJSON_GetArraySize(symbolLinkConfigs); 29669570cc8Sopenharmony_ci for (uint32_t i = 0; i < symlinkPointSize; i++) { 29769570cc8Sopenharmony_ci cJSON *symConfig = cJSON_GetArrayItem(symbolLinkConfigs, i); 29869570cc8Sopenharmony_ci if (symConfig == NULL) { 29969570cc8Sopenharmony_ci continue; 30069570cc8Sopenharmony_ci } 30169570cc8Sopenharmony_ci SymbolLinkNode *node = DecodeSymbolLinksConfig(section, symConfig); 30269570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(node != NULL, return -1); 30369570cc8Sopenharmony_ci AddSandboxMountNode(&node->sandboxNode, section); 30469570cc8Sopenharmony_ci } 30569570cc8Sopenharmony_ci return 0; 30669570cc8Sopenharmony_ci} 30769570cc8Sopenharmony_ci 30869570cc8Sopenharmony_ciAPPSPAWN_STATIC int ParseGidTableConfig(AppSpawnSandboxCfg *sandbox, const cJSON *configs, SandboxSection *section) 30969570cc8Sopenharmony_ci{ 31069570cc8Sopenharmony_ci APPSPAWN_CHECK(cJSON_IsArray(configs), return 0, "json is not array."); 31169570cc8Sopenharmony_ci uint32_t arrayLen = (uint32_t)cJSON_GetArraySize(configs); 31269570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(arrayLen > 0, return 0); 31369570cc8Sopenharmony_ci APPSPAWN_CHECK(arrayLen < APP_MAX_GIDS, arrayLen = APP_MAX_GIDS, "More gid in gids json."); 31469570cc8Sopenharmony_ci 31569570cc8Sopenharmony_ci // 配置存在,以后面的配置为准 31669570cc8Sopenharmony_ci if (section->gidTable) { 31769570cc8Sopenharmony_ci free(section->gidTable); 31869570cc8Sopenharmony_ci section->gidTable = NULL; 31969570cc8Sopenharmony_ci section->gidCount = 0; 32069570cc8Sopenharmony_ci } 32169570cc8Sopenharmony_ci section->gidTable = (gid_t *)calloc(1, sizeof(gid_t) * arrayLen); 32269570cc8Sopenharmony_ci APPSPAWN_CHECK(section->gidTable != NULL, return APPSPAWN_SYSTEM_ERROR, "Failed to alloc memory."); 32369570cc8Sopenharmony_ci 32469570cc8Sopenharmony_ci for (uint32_t i = 0; i < arrayLen; i++) { 32569570cc8Sopenharmony_ci cJSON *item = cJSON_GetArrayItem(configs, i); 32669570cc8Sopenharmony_ci gid_t gid = 0; 32769570cc8Sopenharmony_ci if (cJSON_IsNumber(item)) { 32869570cc8Sopenharmony_ci gid = (gid_t)cJSON_GetNumberValue(item); 32969570cc8Sopenharmony_ci } else { 33069570cc8Sopenharmony_ci char *value = cJSON_GetStringValue(item); 33169570cc8Sopenharmony_ci gid = DecodeGid(value); 33269570cc8Sopenharmony_ci } 33369570cc8Sopenharmony_ci if (gid <= 0) { 33469570cc8Sopenharmony_ci continue; 33569570cc8Sopenharmony_ci } 33669570cc8Sopenharmony_ci section->gidTable[section->gidCount++] = gid; 33769570cc8Sopenharmony_ci } 33869570cc8Sopenharmony_ci return 0; 33969570cc8Sopenharmony_ci} 34069570cc8Sopenharmony_ci 34169570cc8Sopenharmony_cistatic int ParseMountGroupsConfig(AppSpawnSandboxCfg *sandbox, const cJSON *groupConfig, SandboxSection *section) 34269570cc8Sopenharmony_ci{ 34369570cc8Sopenharmony_ci APPSPAWN_CHECK(cJSON_IsArray(groupConfig), 34469570cc8Sopenharmony_ci return APPSPAWN_SANDBOX_INVALID, "Invalid mount-groups config %{public}s", section->name); 34569570cc8Sopenharmony_ci 34669570cc8Sopenharmony_ci // 合并name-group 34769570cc8Sopenharmony_ci uint32_t count = (uint32_t)cJSON_GetArraySize(groupConfig); 34869570cc8Sopenharmony_ci APPSPAWN_LOGV("mount-group in section %{public}s %{public}u", section->name, count); 34969570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(count > 0, return 0); 35069570cc8Sopenharmony_ci count += section->number; 35169570cc8Sopenharmony_ci SandboxMountNode **nameGroups = (SandboxMountNode **)calloc(1, sizeof(SandboxMountNode *) * count); 35269570cc8Sopenharmony_ci APPSPAWN_CHECK(nameGroups != NULL, return APPSPAWN_SYSTEM_ERROR, "Failed to alloc memory for group name"); 35369570cc8Sopenharmony_ci 35469570cc8Sopenharmony_ci uint32_t j = 0; 35569570cc8Sopenharmony_ci uint32_t number = 0; 35669570cc8Sopenharmony_ci for (j = 0; j < section->number; j++) { // copy old 35769570cc8Sopenharmony_ci if (section->nameGroups[j] == NULL) { 35869570cc8Sopenharmony_ci continue; 35969570cc8Sopenharmony_ci } 36069570cc8Sopenharmony_ci nameGroups[number++] = section->nameGroups[j]; 36169570cc8Sopenharmony_ci } 36269570cc8Sopenharmony_ci 36369570cc8Sopenharmony_ci SandboxNameGroupNode *mountNode = NULL; 36469570cc8Sopenharmony_ci for (uint32_t i = 0; i < count; i++) { 36569570cc8Sopenharmony_ci nameGroups[number] = NULL; 36669570cc8Sopenharmony_ci 36769570cc8Sopenharmony_ci char *name = cJSON_GetStringValue(cJSON_GetArrayItem(groupConfig, i)); 36869570cc8Sopenharmony_ci mountNode = (SandboxNameGroupNode *)GetSandboxSection(&sandbox->nameGroupsQueue, name); 36969570cc8Sopenharmony_ci if (mountNode == NULL) { 37069570cc8Sopenharmony_ci APPSPAWN_LOGE("Can not find name-group %{public}s", name); 37169570cc8Sopenharmony_ci continue; 37269570cc8Sopenharmony_ci } 37369570cc8Sopenharmony_ci // check type 37469570cc8Sopenharmony_ci if (strcmp(section->name, "system-const") == 0 && mountNode->destType != SANDBOX_TAG_SYSTEM_CONST) { 37569570cc8Sopenharmony_ci APPSPAWN_LOGE("Invalid name-group %{public}s", name); 37669570cc8Sopenharmony_ci continue; 37769570cc8Sopenharmony_ci } 37869570cc8Sopenharmony_ci // 过滤重复的节点 37969570cc8Sopenharmony_ci for (j = 0; j < section->number; j++) { 38069570cc8Sopenharmony_ci if (section->nameGroups[j] != NULL && section->nameGroups[j] == (SandboxMountNode *)mountNode) { 38169570cc8Sopenharmony_ci APPSPAWN_LOGE("Name-group %{public}s bas been set", name); 38269570cc8Sopenharmony_ci break; 38369570cc8Sopenharmony_ci } 38469570cc8Sopenharmony_ci } 38569570cc8Sopenharmony_ci if (j < section->number) { 38669570cc8Sopenharmony_ci continue; 38769570cc8Sopenharmony_ci } 38869570cc8Sopenharmony_ci nameGroups[number++] = (SandboxMountNode *)mountNode; 38969570cc8Sopenharmony_ci APPSPAWN_LOGV("Name-group %{public}d %{public}s set", section->number, name); 39069570cc8Sopenharmony_ci } 39169570cc8Sopenharmony_ci if (section->nameGroups != NULL) { 39269570cc8Sopenharmony_ci free(section->nameGroups); 39369570cc8Sopenharmony_ci } 39469570cc8Sopenharmony_ci section->nameGroups = nameGroups; 39569570cc8Sopenharmony_ci section->number = number; 39669570cc8Sopenharmony_ci APPSPAWN_LOGV("mount-group in section %{public}s %{public}u", section->name, section->number); 39769570cc8Sopenharmony_ci return 0; 39869570cc8Sopenharmony_ci} 39969570cc8Sopenharmony_ci 40069570cc8Sopenharmony_cistatic int ParseBaseConfig(AppSpawnSandboxCfg *sandbox, SandboxSection *section, const cJSON *configs) 40169570cc8Sopenharmony_ci{ 40269570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(configs != NULL, return 0); 40369570cc8Sopenharmony_ci APPSPAWN_CHECK(cJSON_IsObject(configs), 40469570cc8Sopenharmony_ci return APPSPAWN_SANDBOX_INVALID, "Invalid config %{public}s", section->name); 40569570cc8Sopenharmony_ci APPSPAWN_LOGV("Parse sandbox %{public}s", section->name); 40669570cc8Sopenharmony_ci 40769570cc8Sopenharmony_ci // "sandbox-switch": "ON", default sandbox switch is on 40869570cc8Sopenharmony_ci section->sandboxSwitch = GetBoolValueFromJsonObj(configs, "sandbox-switch", true); 40969570cc8Sopenharmony_ci // "sandbox-shared" 41069570cc8Sopenharmony_ci section->sandboxShared = GetBoolValueFromJsonObj(configs, "sandbox-shared", false); 41169570cc8Sopenharmony_ci 41269570cc8Sopenharmony_ci int ret = 0; 41369570cc8Sopenharmony_ci cJSON *gidTabJson = cJSON_GetObjectItemCaseSensitive(configs, "gids"); 41469570cc8Sopenharmony_ci if (gidTabJson) { 41569570cc8Sopenharmony_ci ret = ParseGidTableConfig(sandbox, gidTabJson, section); 41669570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Parse gids for %{public}s", section->name); 41769570cc8Sopenharmony_ci } 41869570cc8Sopenharmony_ci 41969570cc8Sopenharmony_ci cJSON *pathConfigs = cJSON_GetObjectItemCaseSensitive(configs, "mount-paths"); 42069570cc8Sopenharmony_ci if (pathConfigs != NULL) { // mount-paths 42169570cc8Sopenharmony_ci ret = ParseMountPathsConfig(sandbox, pathConfigs, section, SANDBOX_TAG_MOUNT_PATH); 42269570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Parse mount-paths for %{public}s", section->name); 42369570cc8Sopenharmony_ci } 42469570cc8Sopenharmony_ci 42569570cc8Sopenharmony_ci pathConfigs = cJSON_GetObjectItemCaseSensitive(configs, "mount-files"); 42669570cc8Sopenharmony_ci if (pathConfigs != NULL) { // mount-files 42769570cc8Sopenharmony_ci ret = ParseMountPathsConfig(sandbox, pathConfigs, section, SANDBOX_TAG_MOUNT_FILE); 42869570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Parse mount-paths for %{public}s", section->name); 42969570cc8Sopenharmony_ci } 43069570cc8Sopenharmony_ci 43169570cc8Sopenharmony_ci pathConfigs = cJSON_GetObjectItemCaseSensitive(configs, "symbol-links"); 43269570cc8Sopenharmony_ci if (pathConfigs != NULL) { // symbol-links 43369570cc8Sopenharmony_ci ret = ParseSymbolLinksConfig(sandbox, pathConfigs, section); 43469570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Parse symbol-links for %{public}s", section->name); 43569570cc8Sopenharmony_ci } 43669570cc8Sopenharmony_ci 43769570cc8Sopenharmony_ci cJSON *groupConfig = cJSON_GetObjectItemCaseSensitive(configs, "mount-groups"); 43869570cc8Sopenharmony_ci if (groupConfig != NULL) { 43969570cc8Sopenharmony_ci ret = ParseMountGroupsConfig(sandbox, groupConfig, section); 44069570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Parse mount-groups for %{public}s", section->name); 44169570cc8Sopenharmony_ci } 44269570cc8Sopenharmony_ci return 0; 44369570cc8Sopenharmony_ci} 44469570cc8Sopenharmony_ci 44569570cc8Sopenharmony_cistatic int ParsePackageNameConfig(AppSpawnSandboxCfg *sandbox, const char *name, const cJSON *packageNameConfigs) 44669570cc8Sopenharmony_ci{ 44769570cc8Sopenharmony_ci APPSPAWN_LOGV("Parse package-name config %{public}s", name); 44869570cc8Sopenharmony_ci SandboxPackageNameNode *node = (SandboxPackageNameNode *)GetSandboxSection(&sandbox->packageNameQueue, name); 44969570cc8Sopenharmony_ci if (node == NULL) { 45069570cc8Sopenharmony_ci node = CreateSandboxPackageNameNode(name); 45169570cc8Sopenharmony_ci } 45269570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(node != NULL, return -1); 45369570cc8Sopenharmony_ci 45469570cc8Sopenharmony_ci int ret = ParseBaseConfig(sandbox, &node->section, packageNameConfigs); 45569570cc8Sopenharmony_ci if (ret != 0) { 45669570cc8Sopenharmony_ci DeleteSandboxSection((SandboxSection *)node); 45769570cc8Sopenharmony_ci return ret; 45869570cc8Sopenharmony_ci } 45969570cc8Sopenharmony_ci // success, insert section 46069570cc8Sopenharmony_ci AddSandboxSection(&node->section, &sandbox->packageNameQueue); 46169570cc8Sopenharmony_ci return 0; 46269570cc8Sopenharmony_ci} 46369570cc8Sopenharmony_ci 46469570cc8Sopenharmony_cistatic int ParseSpawnFlagsConfig(AppSpawnSandboxCfg *sandbox, const char *name, const cJSON *flagsConfig) 46569570cc8Sopenharmony_ci{ 46669570cc8Sopenharmony_ci uint32_t flagIndex = GetFlagIndexFromJson(flagsConfig); 46769570cc8Sopenharmony_ci APPSPAWN_LOGV("Parse spawn-flags config %{public}s flagIndex %{public}u", name, flagIndex); 46869570cc8Sopenharmony_ci SandboxFlagsNode *node = (SandboxFlagsNode *)GetSandboxSection(&sandbox->spawnFlagsQueue, name); 46969570cc8Sopenharmony_ci if (node == NULL) { 47069570cc8Sopenharmony_ci node = CreateSandboxFlagsNode(name); 47169570cc8Sopenharmony_ci } 47269570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(node != NULL, return -1); 47369570cc8Sopenharmony_ci node->flagIndex = flagIndex; 47469570cc8Sopenharmony_ci 47569570cc8Sopenharmony_ci int ret = ParseBaseConfig(sandbox, &node->section, flagsConfig); 47669570cc8Sopenharmony_ci if (ret != 0) { 47769570cc8Sopenharmony_ci DeleteSandboxSection((SandboxSection *)node); 47869570cc8Sopenharmony_ci return ret; 47969570cc8Sopenharmony_ci } 48069570cc8Sopenharmony_ci // success, insert section 48169570cc8Sopenharmony_ci AddSandboxSection(&node->section, &sandbox->spawnFlagsQueue); 48269570cc8Sopenharmony_ci return 0; 48369570cc8Sopenharmony_ci} 48469570cc8Sopenharmony_ci 48569570cc8Sopenharmony_cistatic int ParsePermissionConfig(AppSpawnSandboxCfg *sandbox, const char *name, const cJSON *permissionConfig) 48669570cc8Sopenharmony_ci{ 48769570cc8Sopenharmony_ci APPSPAWN_LOGV("Parse permission config %{public}s", name); 48869570cc8Sopenharmony_ci SandboxPermissionNode *node = (SandboxPermissionNode *)GetSandboxSection(&sandbox->permissionQueue, name); 48969570cc8Sopenharmony_ci if (node == NULL) { 49069570cc8Sopenharmony_ci node = CreateSandboxPermissionNode(name); 49169570cc8Sopenharmony_ci } 49269570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(node != NULL, return -1); 49369570cc8Sopenharmony_ci 49469570cc8Sopenharmony_ci int ret = ParseBaseConfig(sandbox, &node->section, permissionConfig); 49569570cc8Sopenharmony_ci if (ret != 0) { 49669570cc8Sopenharmony_ci DeleteSandboxSection((SandboxSection *)node); 49769570cc8Sopenharmony_ci return ret; 49869570cc8Sopenharmony_ci } 49969570cc8Sopenharmony_ci // success, insert section 50069570cc8Sopenharmony_ci AddSandboxSection(&node->section, &sandbox->permissionQueue); 50169570cc8Sopenharmony_ci return 0; 50269570cc8Sopenharmony_ci} 50369570cc8Sopenharmony_ci 50469570cc8Sopenharmony_cistatic SandboxNameGroupNode *ParseNameGroup(AppSpawnSandboxCfg *sandbox, const cJSON *groupConfig) 50569570cc8Sopenharmony_ci{ 50669570cc8Sopenharmony_ci char *name = GetStringFromJsonObj(groupConfig, "name"); 50769570cc8Sopenharmony_ci APPSPAWN_CHECK(name != NULL, return NULL, "No name in name group config"); 50869570cc8Sopenharmony_ci APPSPAWN_LOGV("Parse name-group config %{public}s", name); 50969570cc8Sopenharmony_ci SandboxNameGroupNode *node = (SandboxNameGroupNode *)GetSandboxSection(&sandbox->nameGroupsQueue, name); 51069570cc8Sopenharmony_ci if (node == NULL) { 51169570cc8Sopenharmony_ci node = CreateSandboxNameGroupNode(name); 51269570cc8Sopenharmony_ci } 51369570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(node != NULL, return NULL); 51469570cc8Sopenharmony_ci 51569570cc8Sopenharmony_ci cJSON *obj = cJSON_GetObjectItemCaseSensitive(groupConfig, "mount-paths-deps"); 51669570cc8Sopenharmony_ci if (obj) { 51769570cc8Sopenharmony_ci if (node->depNode) { // free repeat 51869570cc8Sopenharmony_ci DeleteSandboxMountNode((SandboxMountNode *)node->depNode); 51969570cc8Sopenharmony_ci } 52069570cc8Sopenharmony_ci node->depNode = DecodeMountPathConfig(NULL, obj, SANDBOX_TAG_MOUNT_PATH); 52169570cc8Sopenharmony_ci if (node->depNode == NULL) { 52269570cc8Sopenharmony_ci DeleteSandboxSection((SandboxSection *)node); 52369570cc8Sopenharmony_ci return NULL; 52469570cc8Sopenharmony_ci } 52569570cc8Sopenharmony_ci // "deps-mode": "not-exists" 52669570cc8Sopenharmony_ci node->depMode = GetMountModeFromConfig(groupConfig, "deps-mode", MOUNT_MODE_ALWAYS); 52769570cc8Sopenharmony_ci } 52869570cc8Sopenharmony_ci 52969570cc8Sopenharmony_ci int ret = ParseBaseConfig(sandbox, &node->section, groupConfig); 53069570cc8Sopenharmony_ci if (ret != 0) { 53169570cc8Sopenharmony_ci DeleteSandboxSection((SandboxSection *)node); 53269570cc8Sopenharmony_ci return NULL; 53369570cc8Sopenharmony_ci } 53469570cc8Sopenharmony_ci // "type": "system-const", 53569570cc8Sopenharmony_ci // "caps": ["shared"], 53669570cc8Sopenharmony_ci node->destType = GetNameGroupTypeFromConfig(groupConfig, "type", SANDBOX_TAG_INVALID); 53769570cc8Sopenharmony_ci node->depMounted = 0; 53869570cc8Sopenharmony_ci // success, insert section 53969570cc8Sopenharmony_ci AddSandboxSection(&node->section, &sandbox->nameGroupsQueue); 54069570cc8Sopenharmony_ci return node; 54169570cc8Sopenharmony_ci} 54269570cc8Sopenharmony_ci 54369570cc8Sopenharmony_cistatic int ParseNameGroupsConfig(AppSpawnSandboxCfg *sandbox, const cJSON *root) 54469570cc8Sopenharmony_ci{ 54569570cc8Sopenharmony_ci APPSPAWN_CHECK(root != NULL, return APPSPAWN_SANDBOX_INVALID, "Invalid config "); 54669570cc8Sopenharmony_ci cJSON *configs = cJSON_GetObjectItemCaseSensitive(root, "name-groups"); 54769570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(configs != NULL, return 0); 54869570cc8Sopenharmony_ci APPSPAWN_CHECK(cJSON_IsArray(configs), return APPSPAWN_SANDBOX_INVALID, "Invalid config "); 54969570cc8Sopenharmony_ci int count = cJSON_GetArraySize(configs); 55069570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(count > 0, return 0); 55169570cc8Sopenharmony_ci 55269570cc8Sopenharmony_ci sandbox->depNodeCount = 0; 55369570cc8Sopenharmony_ci for (int i = 0; i < count; i++) { 55469570cc8Sopenharmony_ci cJSON *json = cJSON_GetArrayItem(configs, i); 55569570cc8Sopenharmony_ci if (json == NULL) { 55669570cc8Sopenharmony_ci continue; 55769570cc8Sopenharmony_ci } 55869570cc8Sopenharmony_ci SandboxNameGroupNode *node = ParseNameGroup(sandbox, json); 55969570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(node != NULL, return APPSPAWN_SANDBOX_INVALID); 56069570cc8Sopenharmony_ci if (node->depNode) { 56169570cc8Sopenharmony_ci sandbox->depNodeCount++; 56269570cc8Sopenharmony_ci } 56369570cc8Sopenharmony_ci } 56469570cc8Sopenharmony_ci APPSPAWN_LOGV("ParseNameGroupsConfig depNodeCount %{public}d", sandbox->depNodeCount); 56569570cc8Sopenharmony_ci return 0; 56669570cc8Sopenharmony_ci} 56769570cc8Sopenharmony_ci 56869570cc8Sopenharmony_cistatic int ParseConditionalConfig(AppSpawnSandboxCfg *sandbox, const cJSON *configs, const char *configName, 56969570cc8Sopenharmony_ci int (*parseConfig)(AppSpawnSandboxCfg *sandbox, const char *name, const cJSON *configs)) 57069570cc8Sopenharmony_ci{ 57169570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(configs != NULL, return 0); 57269570cc8Sopenharmony_ci APPSPAWN_CHECK(cJSON_IsArray(configs), 57369570cc8Sopenharmony_ci return APPSPAWN_SANDBOX_INVALID, "Invalid config %{public}s", configName); 57469570cc8Sopenharmony_ci int ret = 0; 57569570cc8Sopenharmony_ci int count = cJSON_GetArraySize(configs); 57669570cc8Sopenharmony_ci for (int i = 0; i < count; i++) { 57769570cc8Sopenharmony_ci cJSON *json = cJSON_GetArrayItem(configs, i); 57869570cc8Sopenharmony_ci if (json == NULL) { 57969570cc8Sopenharmony_ci continue; 58069570cc8Sopenharmony_ci } 58169570cc8Sopenharmony_ci char *name = GetStringFromJsonObj(json, "name"); 58269570cc8Sopenharmony_ci if (name == NULL) { 58369570cc8Sopenharmony_ci APPSPAWN_LOGE("No name in %{public}s configs", configName); 58469570cc8Sopenharmony_ci continue; 58569570cc8Sopenharmony_ci } 58669570cc8Sopenharmony_ci ret = parseConfig(sandbox, name, json); 58769570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret); 58869570cc8Sopenharmony_ci } 58969570cc8Sopenharmony_ci return 0; 59069570cc8Sopenharmony_ci} 59169570cc8Sopenharmony_ci 59269570cc8Sopenharmony_cistatic int ParseGlobalSandboxConfig(AppSpawnSandboxCfg *sandbox, const cJSON *root) 59369570cc8Sopenharmony_ci{ 59469570cc8Sopenharmony_ci cJSON *json = cJSON_GetObjectItemCaseSensitive(root, "global"); 59569570cc8Sopenharmony_ci if (json) { 59669570cc8Sopenharmony_ci sandbox->sandboxNsFlags = GetSandboxNsFlags(json); 59769570cc8Sopenharmony_ci char *rootPath = GetStringFromJsonObj(json, "sandbox-root"); 59869570cc8Sopenharmony_ci APPSPAWN_CHECK(rootPath != NULL, return APPSPAWN_SYSTEM_ERROR, "No root path in config"); 59969570cc8Sopenharmony_ci if (sandbox->rootPath) { 60069570cc8Sopenharmony_ci free(sandbox->rootPath); 60169570cc8Sopenharmony_ci } 60269570cc8Sopenharmony_ci sandbox->rootPath = strdup(rootPath); 60369570cc8Sopenharmony_ci APPSPAWN_CHECK(sandbox->rootPath != NULL, return APPSPAWN_SYSTEM_ERROR, "Failed to copy root path"); 60469570cc8Sopenharmony_ci sandbox->topSandboxSwitch = GetBoolValueFromJsonObj(json, "top-sandbox-switch", true); 60569570cc8Sopenharmony_ci } 60669570cc8Sopenharmony_ci return 0; 60769570cc8Sopenharmony_ci} 60869570cc8Sopenharmony_ci 60969570cc8Sopenharmony_citypedef struct TagParseJsonContext { 61069570cc8Sopenharmony_ci AppSpawnSandboxCfg *sandboxCfg; 61169570cc8Sopenharmony_ci}ParseJsonContext; 61269570cc8Sopenharmony_ci 61369570cc8Sopenharmony_ciAPPSPAWN_STATIC int ParseAppSandboxConfig(const cJSON *root, ParseJsonContext *context) 61469570cc8Sopenharmony_ci{ 61569570cc8Sopenharmony_ci APPSPAWN_CHECK(root != NULL && context != NULL && context->sandboxCfg != NULL, 61669570cc8Sopenharmony_ci return APPSPAWN_SYSTEM_ERROR, "Invalid json"); 61769570cc8Sopenharmony_ci AppSpawnSandboxCfg *sandbox = context->sandboxCfg; 61869570cc8Sopenharmony_ci int ret = ParseGlobalSandboxConfig(sandbox, root); // "global": 61969570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return APPSPAWN_SANDBOX_INVALID); 62069570cc8Sopenharmony_ci ret = ParseNameGroupsConfig(sandbox, root); // name-groups 62169570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return APPSPAWN_SANDBOX_INVALID); 62269570cc8Sopenharmony_ci 62369570cc8Sopenharmony_ci // "required" 62469570cc8Sopenharmony_ci cJSON *required = cJSON_GetObjectItemCaseSensitive(root, "required"); 62569570cc8Sopenharmony_ci if (required) { 62669570cc8Sopenharmony_ci cJSON *config = NULL; 62769570cc8Sopenharmony_ci cJSON_ArrayForEach(config, required) 62869570cc8Sopenharmony_ci { 62969570cc8Sopenharmony_ci APPSPAWN_LOGI("Sandbox required config: %{public}s", config->string); 63069570cc8Sopenharmony_ci SandboxSection *section = GetSandboxSection(&sandbox->requiredQueue, config->string); 63169570cc8Sopenharmony_ci if (section == NULL) { 63269570cc8Sopenharmony_ci section = CreateSandboxSection(config->string, sizeof(SandboxSection), SANDBOX_TAG_REQUIRED); 63369570cc8Sopenharmony_ci } 63469570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(section != NULL, return -1); 63569570cc8Sopenharmony_ci 63669570cc8Sopenharmony_ci ret = ParseBaseConfig(sandbox, section, config); 63769570cc8Sopenharmony_ci if (ret != 0) { 63869570cc8Sopenharmony_ci DeleteSandboxSection(section); 63969570cc8Sopenharmony_ci return ret; 64069570cc8Sopenharmony_ci } 64169570cc8Sopenharmony_ci // success, insert section 64269570cc8Sopenharmony_ci AddSandboxSection(section, &sandbox->requiredQueue); 64369570cc8Sopenharmony_ci } 64469570cc8Sopenharmony_ci } 64569570cc8Sopenharmony_ci 64669570cc8Sopenharmony_ci // conditional 64769570cc8Sopenharmony_ci cJSON *json = cJSON_GetObjectItemCaseSensitive(root, "conditional"); 64869570cc8Sopenharmony_ci if (json != NULL) { 64969570cc8Sopenharmony_ci // permission 65069570cc8Sopenharmony_ci cJSON *config = cJSON_GetObjectItemCaseSensitive(json, "permission"); 65169570cc8Sopenharmony_ci ret = ParseConditionalConfig(sandbox, config, "permission", ParsePermissionConfig); 65269570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret); 65369570cc8Sopenharmony_ci // spawn-flag 65469570cc8Sopenharmony_ci config = cJSON_GetObjectItemCaseSensitive(json, "spawn-flag"); 65569570cc8Sopenharmony_ci ret = ParseConditionalConfig(sandbox, config, "spawn-flag", ParseSpawnFlagsConfig); 65669570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret); 65769570cc8Sopenharmony_ci // package-name 65869570cc8Sopenharmony_ci config = cJSON_GetObjectItemCaseSensitive(json, "package-name"); 65969570cc8Sopenharmony_ci ret = ParseConditionalConfig(sandbox, config, "package-name", ParsePackageNameConfig); 66069570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret); 66169570cc8Sopenharmony_ci } 66269570cc8Sopenharmony_ci return ret; 66369570cc8Sopenharmony_ci} 66469570cc8Sopenharmony_ci 66569570cc8Sopenharmony_ciAPPSPAWN_STATIC const char *GetSandboxNameByMode(RunMode mode) 66669570cc8Sopenharmony_ci{ 66769570cc8Sopenharmony_ci if (mode == MODE_FOR_NATIVE_SPAWN) { 66869570cc8Sopenharmony_ci return ISOLATED_SANDBOX_FILE_NAME; 66969570cc8Sopenharmony_ci } 67069570cc8Sopenharmony_ci if (mode == MODE_FOR_NWEB_SPAWN || mode == MODE_FOR_NWEB_COLD_RUN) { 67169570cc8Sopenharmony_ci return WEB_SANDBOX_FILE_NAME; 67269570cc8Sopenharmony_ci } 67369570cc8Sopenharmony_ci return APP_SANDBOX_FILE_NAME; 67469570cc8Sopenharmony_ci} 67569570cc8Sopenharmony_ci 67669570cc8Sopenharmony_ciint LoadAppSandboxConfig(AppSpawnSandboxCfg *sandbox, RunMode mode) 67769570cc8Sopenharmony_ci{ 67869570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(sandbox != NULL, return APPSPAWN_ARG_INVALID); 67969570cc8Sopenharmony_ci const char *sandboxName = GetSandboxNameByMode(mode); 68069570cc8Sopenharmony_ci if (sandbox->depGroupNodes != NULL) { 68169570cc8Sopenharmony_ci APPSPAWN_LOGW("Sandbox has been load"); 68269570cc8Sopenharmony_ci return 0; 68369570cc8Sopenharmony_ci } 68469570cc8Sopenharmony_ci ParseJsonContext context = {}; 68569570cc8Sopenharmony_ci context.sandboxCfg = sandbox; 68669570cc8Sopenharmony_ci int ret = ParseJsonConfig("etc/sandbox", sandboxName, ParseAppSandboxConfig, &context); 68769570cc8Sopenharmony_ci if (ret == APPSPAWN_SANDBOX_NONE) { 68869570cc8Sopenharmony_ci APPSPAWN_LOGW("No sandbox config"); 68969570cc8Sopenharmony_ci ret = 0; 69069570cc8Sopenharmony_ci } 69169570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret); 69269570cc8Sopenharmony_ci sandbox->pidNamespaceSupport = AppSandboxPidNsIsSupport(); 69369570cc8Sopenharmony_ci sandbox->appFullMountEnable = CheckAppFullMountEnable(); 69469570cc8Sopenharmony_ci APPSPAWN_LOGI("Sandbox pidNamespaceSupport: %{public}d appFullMountEnable: %{public}d", 69569570cc8Sopenharmony_ci sandbox->pidNamespaceSupport, sandbox->appFullMountEnable); 69669570cc8Sopenharmony_ci 69769570cc8Sopenharmony_ci uint32_t depNodeCount = sandbox->depNodeCount; 69869570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(depNodeCount > 0, return ret); 69969570cc8Sopenharmony_ci 70069570cc8Sopenharmony_ci sandbox->depGroupNodes = (SandboxNameGroupNode **)calloc(1, sizeof(SandboxNameGroupNode *) * depNodeCount); 70169570cc8Sopenharmony_ci APPSPAWN_CHECK(sandbox->depGroupNodes != NULL, return APPSPAWN_SYSTEM_ERROR, "Failed alloc memory "); 70269570cc8Sopenharmony_ci sandbox->depNodeCount = 0; 70369570cc8Sopenharmony_ci ListNode *node = sandbox->nameGroupsQueue.front.next; 70469570cc8Sopenharmony_ci while (node != &sandbox->nameGroupsQueue.front) { 70569570cc8Sopenharmony_ci SandboxNameGroupNode *groupNode = (SandboxNameGroupNode *)ListEntry(node, SandboxMountNode, node); 70669570cc8Sopenharmony_ci if (groupNode->depNode) { 70769570cc8Sopenharmony_ci sandbox->depGroupNodes[sandbox->depNodeCount++] = groupNode; 70869570cc8Sopenharmony_ci } 70969570cc8Sopenharmony_ci node = node->next; 71069570cc8Sopenharmony_ci } 71169570cc8Sopenharmony_ci APPSPAWN_LOGI("LoadAppSandboxConfig depNodeCount %{public}d", sandbox->depNodeCount); 71269570cc8Sopenharmony_ci 71369570cc8Sopenharmony_ci return 0; 71469570cc8Sopenharmony_ci} 715