169570cc8Sopenharmony_ci/* 269570cc8Sopenharmony_ci * Copyright (C) 2022-2023 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 1669570cc8Sopenharmony_ci#include "sandbox_utils.h" 1769570cc8Sopenharmony_ci 1869570cc8Sopenharmony_ci#include <cerrno> 1969570cc8Sopenharmony_ci#include <cstddef> 2069570cc8Sopenharmony_ci#include <fcntl.h> 2169570cc8Sopenharmony_ci#include <fstream> 2269570cc8Sopenharmony_ci#include <sstream> 2369570cc8Sopenharmony_ci#include <cerrno> 2469570cc8Sopenharmony_ci#include <vector> 2569570cc8Sopenharmony_ci#include <unistd.h> 2669570cc8Sopenharmony_ci#include <sys/mount.h> 2769570cc8Sopenharmony_ci#include <sys/stat.h> 2869570cc8Sopenharmony_ci#include <sys/syscall.h> 2969570cc8Sopenharmony_ci#include <sys/types.h> 3069570cc8Sopenharmony_ci 3169570cc8Sopenharmony_ci#include "appspawn_hook.h" 3269570cc8Sopenharmony_ci#include "appspawn_mount_permission.h" 3369570cc8Sopenharmony_ci#include "appspawn_msg.h" 3469570cc8Sopenharmony_ci#include "appspawn_server.h" 3569570cc8Sopenharmony_ci#include "appspawn_service.h" 3669570cc8Sopenharmony_ci#include "appspawn_utils.h" 3769570cc8Sopenharmony_ci#include "config_policy_utils.h" 3869570cc8Sopenharmony_ci#ifdef WITH_DLP 3969570cc8Sopenharmony_ci#include "dlp_fuse_fd.h" 4069570cc8Sopenharmony_ci#endif 4169570cc8Sopenharmony_ci#include "init_param.h" 4269570cc8Sopenharmony_ci#include "parameter.h" 4369570cc8Sopenharmony_ci#include "parameters.h" 4469570cc8Sopenharmony_ci#include "securec.h" 4569570cc8Sopenharmony_ci 4669570cc8Sopenharmony_ci#ifdef WITH_SELINUX 4769570cc8Sopenharmony_ci#include "hap_restorecon.h" 4869570cc8Sopenharmony_ci#ifdef APPSPAWN_MOUNT_TMPSHM 4969570cc8Sopenharmony_ci#include "policycoreutils.h" 5069570cc8Sopenharmony_ci#endif // APPSPAWN_MOUNT_TMPSHM 5169570cc8Sopenharmony_ci#endif // WITH_SELINUX 5269570cc8Sopenharmony_ci 5369570cc8Sopenharmony_ci#define MAX_MOUNT_TIME 500 // 500us 5469570cc8Sopenharmony_ci#define DEV_SHM_DIR "/dev/shm/" 5569570cc8Sopenharmony_ci 5669570cc8Sopenharmony_ciusing namespace std; 5769570cc8Sopenharmony_ciusing namespace OHOS; 5869570cc8Sopenharmony_ci 5969570cc8Sopenharmony_cinamespace OHOS { 6069570cc8Sopenharmony_cinamespace AppSpawn { 6169570cc8Sopenharmony_cinamespace { 6269570cc8Sopenharmony_ci constexpr int32_t OPTIONS_MAX_LEN = 256; 6369570cc8Sopenharmony_ci constexpr int32_t APP_LOG_DIR_GID = 1007; 6469570cc8Sopenharmony_ci constexpr int32_t APP_DATABASE_DIR_GID = 3012; 6569570cc8Sopenharmony_ci constexpr int32_t FILE_ACCESS_COMMON_DIR_STATUS = 0; 6669570cc8Sopenharmony_ci constexpr int32_t FILE_CROSS_APP_STATUS = 1; 6769570cc8Sopenharmony_ci constexpr static mode_t FILE_MODE = 0711; 6869570cc8Sopenharmony_ci constexpr static mode_t BASIC_MOUNT_FLAGS = MS_REC | MS_BIND; 6969570cc8Sopenharmony_ci constexpr std::string_view APL_SYSTEM_CORE("system_core"); 7069570cc8Sopenharmony_ci constexpr std::string_view APL_SYSTEM_BASIC("system_basic"); 7169570cc8Sopenharmony_ci const std::string APP_JSON_CONFIG("/appdata-sandbox.json"); 7269570cc8Sopenharmony_ci const std::string APP_ISOLATED_JSON_CONFIG("/appdata-sandbox-isolated.json"); 7369570cc8Sopenharmony_ci const std::string g_physicalAppInstallPath = "/data/app/el1/bundle/public/"; 7469570cc8Sopenharmony_ci const std::string g_sandboxGroupPath = "/data/storage/el2/group/"; 7569570cc8Sopenharmony_ci const std::string g_sandboxHspInstallPath = "/data/storage/el1/bundle/"; 7669570cc8Sopenharmony_ci const std::string g_sandBoxAppInstallPath = "/data/accounts/account_0/applications/"; 7769570cc8Sopenharmony_ci const std::string g_bundleResourceSrcPath = "/data/service/el1/public/bms/bundle_resources/"; 7869570cc8Sopenharmony_ci const std::string g_bundleResourceDestPath = "/data/storage/bundle_resources/"; 7969570cc8Sopenharmony_ci const std::string g_dataBundles = "/data/bundles/"; 8069570cc8Sopenharmony_ci const std::string g_userId = "<currentUserId>"; 8169570cc8Sopenharmony_ci const std::string g_packageName = "<PackageName>"; 8269570cc8Sopenharmony_ci const std::string g_packageNameIndex = "<PackageName_index>"; 8369570cc8Sopenharmony_ci const std::string g_variablePackageName = "<variablePackageName>"; 8469570cc8Sopenharmony_ci const std::string g_arkWebPackageName = "<arkWebPackageName>"; 8569570cc8Sopenharmony_ci const std::string g_sandBoxDir = "/mnt/sandbox/"; 8669570cc8Sopenharmony_ci const std::string g_statusCheck = "true"; 8769570cc8Sopenharmony_ci const std::string g_sbxSwitchCheck = "ON"; 8869570cc8Sopenharmony_ci const std::string g_dlpBundleName = "com.ohos.dlpmanager"; 8969570cc8Sopenharmony_ci const std::string g_internal = "__internal__"; 9069570cc8Sopenharmony_ci const std::string g_hspList_key_bundles = "bundles"; 9169570cc8Sopenharmony_ci const std::string g_hspList_key_modules = "modules"; 9269570cc8Sopenharmony_ci const std::string g_hspList_key_versions = "versions"; 9369570cc8Sopenharmony_ci const std::string g_overlayPath = "/data/storage/overlay/"; 9469570cc8Sopenharmony_ci const std::string g_groupList_key_dataGroupId = "dataGroupId"; 9569570cc8Sopenharmony_ci const std::string g_groupList_key_gid = "gid"; 9669570cc8Sopenharmony_ci const std::string g_groupList_key_dir = "dir"; 9769570cc8Sopenharmony_ci const std::string HSPLIST_SOCKET_TYPE = "HspList"; 9869570cc8Sopenharmony_ci const std::string OVERLAY_SOCKET_TYPE = "Overlay"; 9969570cc8Sopenharmony_ci const std::string DATA_GROUP_SOCKET_TYPE = "DataGroup"; 10069570cc8Sopenharmony_ci const char *g_actionStatuc = "check-action-status"; 10169570cc8Sopenharmony_ci const char *g_appBase = "app-base"; 10269570cc8Sopenharmony_ci const char *g_appResources = "app-resources"; 10369570cc8Sopenharmony_ci const char *g_appAplName = "app-apl-name"; 10469570cc8Sopenharmony_ci const char *g_commonPrefix = "common"; 10569570cc8Sopenharmony_ci const char *g_destMode = "dest-mode"; 10669570cc8Sopenharmony_ci const char *g_fsType = "fs-type"; 10769570cc8Sopenharmony_ci const char *g_linkName = "link-name"; 10869570cc8Sopenharmony_ci const char *g_mountPrefix = "mount-paths"; 10969570cc8Sopenharmony_ci const char *g_gidPrefix = "gids"; 11069570cc8Sopenharmony_ci const char *g_privatePrefix = "individual"; 11169570cc8Sopenharmony_ci const char *g_permissionPrefix = "permission"; 11269570cc8Sopenharmony_ci const char *g_srcPath = "src-path"; 11369570cc8Sopenharmony_ci const char *g_sandBoxPath = "sandbox-path"; 11469570cc8Sopenharmony_ci const char *g_sandBoxFlags = "sandbox-flags"; 11569570cc8Sopenharmony_ci const char *g_sandBoxFlagsCustomized = "sandbox-flags-customized"; 11669570cc8Sopenharmony_ci const char *g_sandBoxOptions = "options"; 11769570cc8Sopenharmony_ci const char *g_dacOverrideSensitive = "dac-override-sensitive"; 11869570cc8Sopenharmony_ci const char *g_sandBoxShared = "sandbox-shared"; 11969570cc8Sopenharmony_ci const char *g_sandBoxSwitchPrefix = "sandbox-switch"; 12069570cc8Sopenharmony_ci const char *g_symlinkPrefix = "symbol-links"; 12169570cc8Sopenharmony_ci const char *g_sandboxRootPrefix = "sandbox-root"; 12269570cc8Sopenharmony_ci const char *g_topSandBoxSwitchPrefix = "top-sandbox-switch"; 12369570cc8Sopenharmony_ci const char *g_targetName = "target-name"; 12469570cc8Sopenharmony_ci const char *g_flagePoint = "flags-point"; 12569570cc8Sopenharmony_ci const char *g_mountSharedFlag = "mount-shared-flag"; 12669570cc8Sopenharmony_ci const char *g_flags = "flags"; 12769570cc8Sopenharmony_ci const char *g_sandBoxNsFlags = "sandbox-ns-flags"; 12869570cc8Sopenharmony_ci const char* g_fileSeparator = "/"; 12969570cc8Sopenharmony_ci const char* g_overlayDecollator = "|"; 13069570cc8Sopenharmony_ci const std::string g_sandBoxRootDir = "/mnt/sandbox/"; 13169570cc8Sopenharmony_ci const std::string g_ohosRender = "__internal__.com.ohos.render"; 13269570cc8Sopenharmony_ci const std::string g_sandBoxRootDirNweb = "/mnt/sandbox/com.ohos.render/"; 13369570cc8Sopenharmony_ci const std::string FILE_CROSS_APP_MODE = "ohos.permission.FILE_CROSS_APP"; 13469570cc8Sopenharmony_ci const std::string FILE_ACCESS_COMMON_DIR_MODE = "ohos.permission.FILE_ACCESS_COMMON_DIR"; 13569570cc8Sopenharmony_ci const std::string ACCESS_DLP_FILE_MODE = "ohos.permission.ACCESS_DLP_FILE"; 13669570cc8Sopenharmony_ci const std::string FILE_ACCESS_MANAGER_MODE = "ohos.permission.FILE_ACCESS_MANAGER"; 13769570cc8Sopenharmony_ci const std::string ARK_WEB_PERSIST_PACKAGE_NAME = "persist.arkwebcore.package_name"; 13869570cc8Sopenharmony_ci 13969570cc8Sopenharmony_ci const std::string& getArkWebPackageName() 14069570cc8Sopenharmony_ci { 14169570cc8Sopenharmony_ci static std::string arkWebPackageName; 14269570cc8Sopenharmony_ci if (arkWebPackageName.empty()) { 14369570cc8Sopenharmony_ci arkWebPackageName = system::GetParameter(ARK_WEB_PERSIST_PACKAGE_NAME, ""); 14469570cc8Sopenharmony_ci } 14569570cc8Sopenharmony_ci return arkWebPackageName; 14669570cc8Sopenharmony_ci } 14769570cc8Sopenharmony_ci} 14869570cc8Sopenharmony_ci 14969570cc8Sopenharmony_cistatic uint32_t GetAppMsgFlags(const AppSpawningCtx *property) 15069570cc8Sopenharmony_ci{ 15169570cc8Sopenharmony_ci APPSPAWN_CHECK(property != nullptr && property->message != nullptr, 15269570cc8Sopenharmony_ci return 0, "Invalid property for name %{public}u", TLV_MSG_FLAGS); 15369570cc8Sopenharmony_ci AppSpawnMsgFlags *msgFlags = (AppSpawnMsgFlags *)GetAppSpawnMsgInfo(property->message, TLV_MSG_FLAGS); 15469570cc8Sopenharmony_ci APPSPAWN_CHECK(msgFlags != nullptr, 15569570cc8Sopenharmony_ci return 0, "No TLV_MSG_FLAGS in msg %{public}s", property->message->msgHeader.processName); 15669570cc8Sopenharmony_ci return msgFlags->flags[0]; 15769570cc8Sopenharmony_ci} 15869570cc8Sopenharmony_ci 15969570cc8Sopenharmony_cibool JsonUtils::GetJsonObjFromJson(nlohmann::json &jsonObj, const std::string &jsonPath) 16069570cc8Sopenharmony_ci{ 16169570cc8Sopenharmony_ci APPSPAWN_CHECK(jsonPath.length() <= PATH_MAX, return false, "jsonPath is too long"); 16269570cc8Sopenharmony_ci std::ifstream jsonFileStream; 16369570cc8Sopenharmony_ci jsonFileStream.open(jsonPath.c_str(), std::ios::in); 16469570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(jsonFileStream.is_open(), return false); 16569570cc8Sopenharmony_ci std::ostringstream buf; 16669570cc8Sopenharmony_ci char ch; 16769570cc8Sopenharmony_ci while (buf && jsonFileStream.get(ch)) { 16869570cc8Sopenharmony_ci buf.put(ch); 16969570cc8Sopenharmony_ci } 17069570cc8Sopenharmony_ci jsonFileStream.close(); 17169570cc8Sopenharmony_ci jsonObj = nlohmann::json::parse(buf.str(), nullptr, false); 17269570cc8Sopenharmony_ci APPSPAWN_CHECK(!jsonObj.is_discarded() && jsonObj.is_structured(), return false, "Parse json file failed"); 17369570cc8Sopenharmony_ci return true; 17469570cc8Sopenharmony_ci} 17569570cc8Sopenharmony_ci 17669570cc8Sopenharmony_cibool JsonUtils::GetStringFromJson(const nlohmann::json &json, const std::string &key, std::string &value) 17769570cc8Sopenharmony_ci{ 17869570cc8Sopenharmony_ci APPSPAWN_CHECK(json != nullptr && json.is_object(), return false, "json is not object."); 17969570cc8Sopenharmony_ci bool isRet = json.find(key) != json.end() && json.at(key).is_string(); 18069570cc8Sopenharmony_ci if (isRet) { 18169570cc8Sopenharmony_ci value = json.at(key).get<std::string>(); 18269570cc8Sopenharmony_ci APPSPAWN_LOGV("Find key[%{public}s] : %{public}s successful.", key.c_str(), value.c_str()); 18369570cc8Sopenharmony_ci } 18469570cc8Sopenharmony_ci return isRet; 18569570cc8Sopenharmony_ci} 18669570cc8Sopenharmony_ci 18769570cc8Sopenharmony_cistd::map<SandboxConfigType, std::vector<nlohmann::json>> SandboxUtils::appSandboxConfig_ = {}; 18869570cc8Sopenharmony_ciint32_t SandboxUtils::deviceTypeEnable_ = -1; 18969570cc8Sopenharmony_ci 19069570cc8Sopenharmony_civoid SandboxUtils::StoreJsonConfig(nlohmann::json &appSandboxConfig, SandboxConfigType type) 19169570cc8Sopenharmony_ci{ 19269570cc8Sopenharmony_ci SandboxUtils::appSandboxConfig_[type].push_back(appSandboxConfig); 19369570cc8Sopenharmony_ci} 19469570cc8Sopenharmony_ci 19569570cc8Sopenharmony_cistd::vector<nlohmann::json> &SandboxUtils::GetJsonConfig(SandboxConfigType type) 19669570cc8Sopenharmony_ci{ 19769570cc8Sopenharmony_ci return SandboxUtils::appSandboxConfig_[type]; 19869570cc8Sopenharmony_ci} 19969570cc8Sopenharmony_ci 20069570cc8Sopenharmony_cistatic void MakeDirRecursive(const std::string &path, mode_t mode) 20169570cc8Sopenharmony_ci{ 20269570cc8Sopenharmony_ci size_t size = path.size(); 20369570cc8Sopenharmony_ci if (size == 0) { 20469570cc8Sopenharmony_ci return; 20569570cc8Sopenharmony_ci } 20669570cc8Sopenharmony_ci 20769570cc8Sopenharmony_ci size_t index = 0; 20869570cc8Sopenharmony_ci do { 20969570cc8Sopenharmony_ci size_t pathIndex = path.find_first_of('/', index); 21069570cc8Sopenharmony_ci index = pathIndex == std::string::npos ? size : pathIndex + 1; 21169570cc8Sopenharmony_ci std::string dir = path.substr(0, index); 21269570cc8Sopenharmony_ci#ifndef APPSPAWN_TEST 21369570cc8Sopenharmony_ci APPSPAWN_CHECK(!(access(dir.c_str(), F_OK) < 0 && mkdir(dir.c_str(), mode) < 0), 21469570cc8Sopenharmony_ci return, "errno is %{public}d, mkdir %{public}s failed", errno, dir.c_str()); 21569570cc8Sopenharmony_ci#endif 21669570cc8Sopenharmony_ci } while (index < size); 21769570cc8Sopenharmony_ci} 21869570cc8Sopenharmony_ci 21969570cc8Sopenharmony_cistatic bool CheckDirRecursive(const std::string &path) 22069570cc8Sopenharmony_ci{ 22169570cc8Sopenharmony_ci size_t size = path.size(); 22269570cc8Sopenharmony_ci if (size == 0) { 22369570cc8Sopenharmony_ci return false; 22469570cc8Sopenharmony_ci } 22569570cc8Sopenharmony_ci size_t index = 0; 22669570cc8Sopenharmony_ci do { 22769570cc8Sopenharmony_ci size_t pathIndex = path.find_first_of('/', index); 22869570cc8Sopenharmony_ci index = pathIndex == std::string::npos ? size : pathIndex + 1; 22969570cc8Sopenharmony_ci std::string dir = path.substr(0, index); 23069570cc8Sopenharmony_ci#ifndef APPSPAWN_TEST 23169570cc8Sopenharmony_ci APPSPAWN_CHECK(access(dir.c_str(), F_OK) == 0, 23269570cc8Sopenharmony_ci return false, "check dir %{public}s failed, strerror: %{public}s", dir.c_str(), strerror(errno)); 23369570cc8Sopenharmony_ci#endif 23469570cc8Sopenharmony_ci } while (index < size); 23569570cc8Sopenharmony_ci return true; 23669570cc8Sopenharmony_ci} 23769570cc8Sopenharmony_ci 23869570cc8Sopenharmony_cistatic void CheckAndCreatFile(const char *file) 23969570cc8Sopenharmony_ci{ 24069570cc8Sopenharmony_ci if (access(file, F_OK) == 0) { 24169570cc8Sopenharmony_ci APPSPAWN_LOGI("file %{public}s already exist", file); 24269570cc8Sopenharmony_ci return; 24369570cc8Sopenharmony_ci } 24469570cc8Sopenharmony_ci std::string path = file; 24569570cc8Sopenharmony_ci auto pos = path.find_last_of('/'); 24669570cc8Sopenharmony_ci APPSPAWN_CHECK(pos != std::string::npos, return, "file %{public}s error", file); 24769570cc8Sopenharmony_ci std::string dir = path.substr(0, pos); 24869570cc8Sopenharmony_ci MakeDirRecursive(dir, FILE_MODE); 24969570cc8Sopenharmony_ci int fd = open(file, O_CREAT, FILE_MODE); 25069570cc8Sopenharmony_ci if (fd < 0) { 25169570cc8Sopenharmony_ci APPSPAWN_LOGW("failed create %{public}s, err=%{public}d", file, errno); 25269570cc8Sopenharmony_ci } else { 25369570cc8Sopenharmony_ci close(fd); 25469570cc8Sopenharmony_ci } 25569570cc8Sopenharmony_ci return; 25669570cc8Sopenharmony_ci} 25769570cc8Sopenharmony_ci 25869570cc8Sopenharmony_ciint32_t SandboxUtils::DoAppSandboxMountOnce(const char *originPath, const char *destinationPath, 25969570cc8Sopenharmony_ci const char *fsType, unsigned long mountFlags, 26069570cc8Sopenharmony_ci const char *options, mode_t mountSharedFlag) 26169570cc8Sopenharmony_ci{ 26269570cc8Sopenharmony_ci if (originPath != nullptr && strstr(originPath, "system/etc/hosts") != nullptr) { 26369570cc8Sopenharmony_ci CheckAndCreatFile(destinationPath); 26469570cc8Sopenharmony_ci } else { 26569570cc8Sopenharmony_ci MakeDirRecursive(destinationPath, FILE_MODE); 26669570cc8Sopenharmony_ci } 26769570cc8Sopenharmony_ci 26869570cc8Sopenharmony_ci int ret = 0; 26969570cc8Sopenharmony_ci // to mount fs and bind mount files or directory 27069570cc8Sopenharmony_ci struct timespec mountStart = {0}; 27169570cc8Sopenharmony_ci clock_gettime(CLOCK_MONOTONIC, &mountStart); 27269570cc8Sopenharmony_ci APPSPAWN_LOGV("Bind mount %{public}s to %{public}s '%{public}s' '%{public}lu' '%{public}s' '%{public}u'", 27369570cc8Sopenharmony_ci originPath, destinationPath, fsType, mountFlags, options, mountSharedFlag); 27469570cc8Sopenharmony_ci ret = mount(originPath, destinationPath, fsType, mountFlags, options); 27569570cc8Sopenharmony_ci struct timespec mountEnd = {0}; 27669570cc8Sopenharmony_ci clock_gettime(CLOCK_MONOTONIC, &mountEnd); 27769570cc8Sopenharmony_ci uint64_t diff = DiffTime(&mountStart, &mountEnd); 27869570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_LOG(diff < MAX_MOUNT_TIME, "mount %{public}s time %{public}" PRId64 " us", originPath, diff); 27969570cc8Sopenharmony_ci if (ret != 0) { 28069570cc8Sopenharmony_ci APPSPAWN_LOGI("errno is: %{public}d, bind mount %{public}s to %{public}s", errno, originPath, destinationPath); 28169570cc8Sopenharmony_ci std::string originPathStr = originPath == nullptr ? "" : originPath; 28269570cc8Sopenharmony_ci if (originPathStr.find("data/app/el1/") != std::string::npos || 28369570cc8Sopenharmony_ci originPathStr.find("data/app/el2/") != std::string::npos) { 28469570cc8Sopenharmony_ci CheckDirRecursive(originPathStr); 28569570cc8Sopenharmony_ci } 28669570cc8Sopenharmony_ci return ret; 28769570cc8Sopenharmony_ci } 28869570cc8Sopenharmony_ci 28969570cc8Sopenharmony_ci ret = mount(nullptr, destinationPath, nullptr, mountSharedFlag, nullptr); 29069570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "errno is: %{public}d, private mount to %{public}s %{public}u failed", 29169570cc8Sopenharmony_ci errno, destinationPath, mountSharedFlag); 29269570cc8Sopenharmony_ci return 0; 29369570cc8Sopenharmony_ci} 29469570cc8Sopenharmony_ci 29569570cc8Sopenharmony_cistatic std::string& replace_all(std::string& str, const std::string& old_value, const std::string& new_value) 29669570cc8Sopenharmony_ci{ 29769570cc8Sopenharmony_ci while (true) { 29869570cc8Sopenharmony_ci std::string::size_type pos(0); 29969570cc8Sopenharmony_ci if ((pos = str.find(old_value)) != std::string::npos) { 30069570cc8Sopenharmony_ci str.replace(pos, old_value.length(), new_value); 30169570cc8Sopenharmony_ci } else { 30269570cc8Sopenharmony_ci break; 30369570cc8Sopenharmony_ci } 30469570cc8Sopenharmony_ci } 30569570cc8Sopenharmony_ci return str; 30669570cc8Sopenharmony_ci} 30769570cc8Sopenharmony_ci 30869570cc8Sopenharmony_cistatic std::vector<std::string> split(std::string &str, const std::string &pattern) 30969570cc8Sopenharmony_ci{ 31069570cc8Sopenharmony_ci std::string::size_type pos; 31169570cc8Sopenharmony_ci std::vector<std::string> result; 31269570cc8Sopenharmony_ci str += pattern; 31369570cc8Sopenharmony_ci size_t size = str.size(); 31469570cc8Sopenharmony_ci 31569570cc8Sopenharmony_ci for (unsigned int i = 0; i < size; i++) { 31669570cc8Sopenharmony_ci pos = str.find(pattern, i); 31769570cc8Sopenharmony_ci if (pos < size) { 31869570cc8Sopenharmony_ci std::string s = str.substr(i, pos - i); 31969570cc8Sopenharmony_ci result.push_back(s); 32069570cc8Sopenharmony_ci i = pos + pattern.size() - 1; 32169570cc8Sopenharmony_ci } 32269570cc8Sopenharmony_ci } 32369570cc8Sopenharmony_ci 32469570cc8Sopenharmony_ci return result; 32569570cc8Sopenharmony_ci} 32669570cc8Sopenharmony_ci 32769570cc8Sopenharmony_civoid SandboxUtils::DoSandboxChmod(nlohmann::json jsonConfig, std::string &sandboxRoot) 32869570cc8Sopenharmony_ci{ 32969570cc8Sopenharmony_ci const std::map<std::string, mode_t> modeMap = {{"S_IRUSR", S_IRUSR}, {"S_IWUSR", S_IWUSR}, {"S_IXUSR", S_IXUSR}, 33069570cc8Sopenharmony_ci {"S_IRGRP", S_IRGRP}, {"S_IWGRP", S_IWGRP}, {"S_IXGRP", S_IXGRP}, 33169570cc8Sopenharmony_ci {"S_IROTH", S_IROTH}, {"S_IWOTH", S_IWOTH}, {"S_IXOTH", S_IXOTH}, 33269570cc8Sopenharmony_ci {"S_IRWXU", S_IRWXU}, {"S_IRWXG", S_IRWXG}, {"S_IRWXO", S_IRWXO}}; 33369570cc8Sopenharmony_ci std::string fileModeStr; 33469570cc8Sopenharmony_ci mode_t mode = 0; 33569570cc8Sopenharmony_ci 33669570cc8Sopenharmony_ci bool rc = JsonUtils::GetStringFromJson(jsonConfig, g_destMode, fileModeStr); 33769570cc8Sopenharmony_ci if (rc == false) { 33869570cc8Sopenharmony_ci return; 33969570cc8Sopenharmony_ci } 34069570cc8Sopenharmony_ci 34169570cc8Sopenharmony_ci std::vector<std::string> modeVec = split(fileModeStr, "|"); 34269570cc8Sopenharmony_ci for (unsigned int i = 0; i < modeVec.size(); i++) { 34369570cc8Sopenharmony_ci if (modeMap.count(modeVec[i])) { 34469570cc8Sopenharmony_ci mode |= modeMap.at(modeVec[i]); 34569570cc8Sopenharmony_ci } 34669570cc8Sopenharmony_ci } 34769570cc8Sopenharmony_ci 34869570cc8Sopenharmony_ci chmod(sandboxRoot.c_str(), mode); 34969570cc8Sopenharmony_ci} 35069570cc8Sopenharmony_ci 35169570cc8Sopenharmony_ciunsigned long SandboxUtils::GetMountFlagsFromConfig(const std::vector<std::string> &vec) 35269570cc8Sopenharmony_ci{ 35369570cc8Sopenharmony_ci const std::map<std::string, mode_t> MountFlagsMap = { {"rec", MS_REC}, {"MS_REC", MS_REC}, 35469570cc8Sopenharmony_ci {"bind", MS_BIND}, {"MS_BIND", MS_BIND}, 35569570cc8Sopenharmony_ci {"move", MS_MOVE}, {"MS_MOVE", MS_MOVE}, 35669570cc8Sopenharmony_ci {"slave", MS_SLAVE}, {"MS_SLAVE", MS_SLAVE}, 35769570cc8Sopenharmony_ci {"rdonly", MS_RDONLY}, {"MS_RDONLY", MS_RDONLY}, 35869570cc8Sopenharmony_ci {"shared", MS_SHARED}, {"MS_SHARED", MS_SHARED}, 35969570cc8Sopenharmony_ci {"unbindable", MS_UNBINDABLE}, 36069570cc8Sopenharmony_ci {"MS_UNBINDABLE", MS_UNBINDABLE}, 36169570cc8Sopenharmony_ci {"remount", MS_REMOUNT}, {"MS_REMOUNT", MS_REMOUNT}, 36269570cc8Sopenharmony_ci {"nosuid", MS_NOSUID}, {"MS_NOSUID", MS_NOSUID}, 36369570cc8Sopenharmony_ci {"nodev", MS_NODEV}, {"MS_NODEV", MS_NODEV}, 36469570cc8Sopenharmony_ci {"noexec", MS_NOEXEC}, {"MS_NOEXEC", MS_NOEXEC}, 36569570cc8Sopenharmony_ci {"noatime", MS_NOATIME}, {"MS_NOATIME", MS_NOATIME}, 36669570cc8Sopenharmony_ci {"lazytime", MS_LAZYTIME}, {"MS_LAZYTIME", MS_LAZYTIME}}; 36769570cc8Sopenharmony_ci unsigned long mountFlags = 0; 36869570cc8Sopenharmony_ci 36969570cc8Sopenharmony_ci for (unsigned int i = 0; i < vec.size(); i++) { 37069570cc8Sopenharmony_ci if (MountFlagsMap.count(vec[i])) { 37169570cc8Sopenharmony_ci mountFlags |= MountFlagsMap.at(vec[i]); 37269570cc8Sopenharmony_ci } 37369570cc8Sopenharmony_ci } 37469570cc8Sopenharmony_ci 37569570cc8Sopenharmony_ci return mountFlags; 37669570cc8Sopenharmony_ci} 37769570cc8Sopenharmony_ci 37869570cc8Sopenharmony_cistatic void MakeAtomicServiceDir(const AppSpawningCtx *appProperty, std::string path) 37969570cc8Sopenharmony_ci{ 38069570cc8Sopenharmony_ci struct stat st = {}; 38169570cc8Sopenharmony_ci if (stat(path.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) { 38269570cc8Sopenharmony_ci return; 38369570cc8Sopenharmony_ci } 38469570cc8Sopenharmony_ci int ret = mkdir(path.c_str(), S_IRWXU); 38569570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return, "mkdir %{public}s failed, errno %{public}d", path.c_str(), errno); 38669570cc8Sopenharmony_ci 38769570cc8Sopenharmony_ci if (path.find("/database") != std::string::npos) { 38869570cc8Sopenharmony_ci ret = chmod(path.c_str(), S_IRWXU | S_IRWXG | S_ISGID); 38969570cc8Sopenharmony_ci } else if (path.find("/log") != std::string::npos) { 39069570cc8Sopenharmony_ci ret = chmod(path.c_str(), S_IRWXU | S_IRWXG); 39169570cc8Sopenharmony_ci } 39269570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return, "chmod %{public}s failed, errno %{public}d", path.c_str(), errno); 39369570cc8Sopenharmony_ci 39469570cc8Sopenharmony_ci#ifdef WITH_SELINUX 39569570cc8Sopenharmony_ci AppSpawnMsgDomainInfo *msgDomainInfo = 39669570cc8Sopenharmony_ci reinterpret_cast<AppSpawnMsgDomainInfo *>(GetAppProperty(appProperty, TLV_DOMAIN_INFO)); 39769570cc8Sopenharmony_ci APPSPAWN_CHECK(msgDomainInfo != NULL, return, "No domain info for %{public}s", GetProcessName(appProperty)); 39869570cc8Sopenharmony_ci HapContext hapContext; 39969570cc8Sopenharmony_ci HapFileInfo hapFileInfo; 40069570cc8Sopenharmony_ci hapFileInfo.pathNameOrig.push_back(path); 40169570cc8Sopenharmony_ci hapFileInfo.apl = msgDomainInfo->apl; 40269570cc8Sopenharmony_ci hapFileInfo.packageName = GetProcessName(appProperty); 40369570cc8Sopenharmony_ci hapFileInfo.hapFlags = msgDomainInfo->hapFlags; 40469570cc8Sopenharmony_ci if (CheckAppMsgFlagsSet(appProperty, APP_FLAGS_DEBUGGABLE)) { 40569570cc8Sopenharmony_ci hapFileInfo.hapFlags |= SELINUX_HAP_DEBUGGABLE; 40669570cc8Sopenharmony_ci } 40769570cc8Sopenharmony_ci if ((path.find("/base") != std::string::npos) || (path.find("/database") != std::string::npos)) { 40869570cc8Sopenharmony_ci ret = hapContext.HapFileRestorecon(hapFileInfo); 40969570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return, "set dir %{public}s selinuxLabel failed, apl %{public}s, ret %{public}d", 41069570cc8Sopenharmony_ci path.c_str(), hapFileInfo.apl.c_str(), ret); 41169570cc8Sopenharmony_ci } 41269570cc8Sopenharmony_ci#endif 41369570cc8Sopenharmony_ci AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO)); 41469570cc8Sopenharmony_ci APPSPAWN_CHECK(dacInfo != NULL, return, "No dac info in msg app property"); 41569570cc8Sopenharmony_ci if (path.find("/base") != std::string::npos) { 41669570cc8Sopenharmony_ci ret = chown(path.c_str(), dacInfo->uid, dacInfo->gid); 41769570cc8Sopenharmony_ci } else if (path.find("/database") != std::string::npos) { 41869570cc8Sopenharmony_ci ret = chown(path.c_str(), dacInfo->uid, APP_DATABASE_DIR_GID); 41969570cc8Sopenharmony_ci } else if (path.find("/log") != std::string::npos) { 42069570cc8Sopenharmony_ci ret = chown(path.c_str(), dacInfo->uid, APP_LOG_DIR_GID); 42169570cc8Sopenharmony_ci } 42269570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return, "chown %{public}s failed, errno %{public}d", path.c_str(), errno); 42369570cc8Sopenharmony_ci return; 42469570cc8Sopenharmony_ci} 42569570cc8Sopenharmony_ci 42669570cc8Sopenharmony_cistatic std::string ReplaceVariablePackageName(const AppSpawningCtx *appProperty, const std::string &path) 42769570cc8Sopenharmony_ci{ 42869570cc8Sopenharmony_ci std::string tmpSandboxPath = path; 42969570cc8Sopenharmony_ci AppSpawnMsgBundleInfo *bundleInfo = 43069570cc8Sopenharmony_ci reinterpret_cast<AppSpawnMsgBundleInfo *>(GetAppProperty(appProperty, TLV_BUNDLE_INFO)); 43169570cc8Sopenharmony_ci APPSPAWN_CHECK(bundleInfo != NULL, return "", "No bundle info in msg %{public}s", GetBundleName(appProperty)); 43269570cc8Sopenharmony_ci 43369570cc8Sopenharmony_ci char *extension; 43469570cc8Sopenharmony_ci uint32_t flags = CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_ATOMIC_SERVICE) ? 0x4 : 0; 43569570cc8Sopenharmony_ci if (flags == 0) { 43669570cc8Sopenharmony_ci flags = (CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_CLONE_ENABLE) && 43769570cc8Sopenharmony_ci bundleInfo->bundleIndex > 0) ? 0x1 : 0; 43869570cc8Sopenharmony_ci flags |= CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_EXTENSION_SANDBOX) ? 0x2 : 0; 43969570cc8Sopenharmony_ci extension = reinterpret_cast<char *>( 44069570cc8Sopenharmony_ci GetAppSpawnMsgExtInfo(appProperty->message, MSG_EXT_NAME_APP_EXTENSION, NULL)); 44169570cc8Sopenharmony_ci } 44269570cc8Sopenharmony_ci std::ostringstream variablePackageName; 44369570cc8Sopenharmony_ci switch (flags) { 44469570cc8Sopenharmony_ci case 0: // 0 default 44569570cc8Sopenharmony_ci variablePackageName << bundleInfo->bundleName; 44669570cc8Sopenharmony_ci break; 44769570cc8Sopenharmony_ci case 1: // 1 +clone-bundleIndex+packageName 44869570cc8Sopenharmony_ci variablePackageName << "+clone-" << bundleInfo->bundleIndex << "+" << bundleInfo->bundleName; 44969570cc8Sopenharmony_ci break; 45069570cc8Sopenharmony_ci case 2: { // 2 +extension-<extensionType>+packageName 45169570cc8Sopenharmony_ci APPSPAWN_CHECK(extension != NULL, return "", "Invalid extension data "); 45269570cc8Sopenharmony_ci variablePackageName << "+extension-" << extension << "+" << bundleInfo->bundleName; 45369570cc8Sopenharmony_ci break; 45469570cc8Sopenharmony_ci } 45569570cc8Sopenharmony_ci case 3: { // 3 +clone-bundleIndex+extension-<extensionType>+packageName 45669570cc8Sopenharmony_ci APPSPAWN_CHECK(extension != NULL, return "", "Invalid extension data "); 45769570cc8Sopenharmony_ci variablePackageName << "+clone-" << bundleInfo->bundleIndex << "+extension" << "-" << 45869570cc8Sopenharmony_ci extension << "+" << bundleInfo->bundleName; 45969570cc8Sopenharmony_ci break; 46069570cc8Sopenharmony_ci } 46169570cc8Sopenharmony_ci case 4: { // 4 +auid-<accountId>+packageName 46269570cc8Sopenharmony_ci std::string accountId = SandboxUtils::GetExtraInfoByType(appProperty, MSG_EXT_NAME_ACCOUNT_ID); 46369570cc8Sopenharmony_ci variablePackageName << "+auid-" << accountId << "+" << bundleInfo->bundleName; 46469570cc8Sopenharmony_ci std::string atomicServicePath = path; 46569570cc8Sopenharmony_ci atomicServicePath = replace_all(atomicServicePath, g_variablePackageName, variablePackageName.str()); 46669570cc8Sopenharmony_ci MakeAtomicServiceDir(appProperty, atomicServicePath); 46769570cc8Sopenharmony_ci break; 46869570cc8Sopenharmony_ci } 46969570cc8Sopenharmony_ci default: 47069570cc8Sopenharmony_ci variablePackageName << bundleInfo->bundleName; 47169570cc8Sopenharmony_ci break; 47269570cc8Sopenharmony_ci } 47369570cc8Sopenharmony_ci tmpSandboxPath = replace_all(tmpSandboxPath, g_variablePackageName, variablePackageName.str()); 47469570cc8Sopenharmony_ci APPSPAWN_LOGV("tmpSandboxPath %{public}s", tmpSandboxPath.c_str()); 47569570cc8Sopenharmony_ci return tmpSandboxPath; 47669570cc8Sopenharmony_ci} 47769570cc8Sopenharmony_ci 47869570cc8Sopenharmony_cistring SandboxUtils::ConvertToRealPath(const AppSpawningCtx *appProperty, std::string path) 47969570cc8Sopenharmony_ci{ 48069570cc8Sopenharmony_ci AppSpawnMsgBundleInfo *info = 48169570cc8Sopenharmony_ci reinterpret_cast<AppSpawnMsgBundleInfo *>(GetAppProperty(appProperty, TLV_BUNDLE_INFO)); 48269570cc8Sopenharmony_ci AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO)); 48369570cc8Sopenharmony_ci if (info == nullptr || dacInfo == nullptr) { 48469570cc8Sopenharmony_ci return ""; 48569570cc8Sopenharmony_ci } 48669570cc8Sopenharmony_ci if (path.find(g_packageNameIndex) != std::string::npos) { 48769570cc8Sopenharmony_ci std::string bundleNameWithIndex = info->bundleName; 48869570cc8Sopenharmony_ci if (info->bundleIndex != 0) { 48969570cc8Sopenharmony_ci bundleNameWithIndex = std::to_string(info->bundleIndex) + "_" + bundleNameWithIndex; 49069570cc8Sopenharmony_ci } 49169570cc8Sopenharmony_ci path = replace_all(path, g_packageNameIndex, bundleNameWithIndex); 49269570cc8Sopenharmony_ci } 49369570cc8Sopenharmony_ci 49469570cc8Sopenharmony_ci if (path.find(g_packageName) != std::string::npos) { 49569570cc8Sopenharmony_ci path = replace_all(path, g_packageName, info->bundleName); 49669570cc8Sopenharmony_ci } 49769570cc8Sopenharmony_ci 49869570cc8Sopenharmony_ci if (path.find(g_userId) != std::string::npos) { 49969570cc8Sopenharmony_ci path = replace_all(path, g_userId, std::to_string(dacInfo->uid / UID_BASE)); 50069570cc8Sopenharmony_ci } 50169570cc8Sopenharmony_ci 50269570cc8Sopenharmony_ci if (path.find(g_variablePackageName) != std::string::npos) { 50369570cc8Sopenharmony_ci path = ReplaceVariablePackageName(appProperty, path); 50469570cc8Sopenharmony_ci } 50569570cc8Sopenharmony_ci 50669570cc8Sopenharmony_ci if (path.find(g_arkWebPackageName) != std::string::npos) { 50769570cc8Sopenharmony_ci path = replace_all(path, g_arkWebPackageName, getArkWebPackageName()); 50869570cc8Sopenharmony_ci APPSPAWN_LOGV( 50969570cc8Sopenharmony_ci "arkWeb sandbox, path %{public}s, package:%{public}s", 51069570cc8Sopenharmony_ci path.c_str(), getArkWebPackageName().c_str()); 51169570cc8Sopenharmony_ci } 51269570cc8Sopenharmony_ci 51369570cc8Sopenharmony_ci return path; 51469570cc8Sopenharmony_ci} 51569570cc8Sopenharmony_ci 51669570cc8Sopenharmony_cistd::string SandboxUtils::ConvertToRealPathWithPermission(const AppSpawningCtx *appProperty, 51769570cc8Sopenharmony_ci std::string path) 51869570cc8Sopenharmony_ci{ 51969570cc8Sopenharmony_ci AppSpawnMsgBundleInfo *info = 52069570cc8Sopenharmony_ci reinterpret_cast<AppSpawnMsgBundleInfo *>(GetAppProperty(appProperty, TLV_BUNDLE_INFO)); 52169570cc8Sopenharmony_ci if (info == nullptr) { 52269570cc8Sopenharmony_ci return ""; 52369570cc8Sopenharmony_ci } 52469570cc8Sopenharmony_ci if (path.find(g_packageNameIndex) != std::string::npos) { 52569570cc8Sopenharmony_ci std::string bundleNameWithIndex = info->bundleName; 52669570cc8Sopenharmony_ci if (info->bundleIndex != 0) { 52769570cc8Sopenharmony_ci bundleNameWithIndex = std::to_string(info->bundleIndex) + "_" + bundleNameWithIndex; 52869570cc8Sopenharmony_ci } 52969570cc8Sopenharmony_ci path = replace_all(path, g_packageNameIndex, bundleNameWithIndex); 53069570cc8Sopenharmony_ci } 53169570cc8Sopenharmony_ci 53269570cc8Sopenharmony_ci if (path.find(g_packageName) != std::string::npos) { 53369570cc8Sopenharmony_ci path = replace_all(path, g_packageName, info->bundleName); 53469570cc8Sopenharmony_ci } 53569570cc8Sopenharmony_ci 53669570cc8Sopenharmony_ci if (path.find(g_userId) != std::string::npos) { 53769570cc8Sopenharmony_ci if (deviceTypeEnable_ == FILE_CROSS_APP_STATUS) { 53869570cc8Sopenharmony_ci path = replace_all(path, g_userId, "currentUser"); 53969570cc8Sopenharmony_ci } else if (deviceTypeEnable_ == FILE_ACCESS_COMMON_DIR_STATUS) { 54069570cc8Sopenharmony_ci path = replace_all(path, g_userId, "currentUser"); 54169570cc8Sopenharmony_ci } else { 54269570cc8Sopenharmony_ci return ""; 54369570cc8Sopenharmony_ci } 54469570cc8Sopenharmony_ci } 54569570cc8Sopenharmony_ci return path; 54669570cc8Sopenharmony_ci} 54769570cc8Sopenharmony_ci 54869570cc8Sopenharmony_cibool SandboxUtils::GetSandboxDacOverrideEnable(nlohmann::json &config) 54969570cc8Sopenharmony_ci{ 55069570cc8Sopenharmony_ci std::string dacOverrideSensitive = ""; 55169570cc8Sopenharmony_ci if (config.find(g_dacOverrideSensitive) == config.end()) { 55269570cc8Sopenharmony_ci return false; 55369570cc8Sopenharmony_ci } 55469570cc8Sopenharmony_ci dacOverrideSensitive = config[g_dacOverrideSensitive].get<std::string>(); 55569570cc8Sopenharmony_ci if (dacOverrideSensitive.compare("true") == 0) { 55669570cc8Sopenharmony_ci return true; 55769570cc8Sopenharmony_ci } 55869570cc8Sopenharmony_ci return false; 55969570cc8Sopenharmony_ci} 56069570cc8Sopenharmony_ci 56169570cc8Sopenharmony_cistd::string SandboxUtils::GetSbxPathByConfig(const AppSpawningCtx *appProperty, nlohmann::json &config) 56269570cc8Sopenharmony_ci{ 56369570cc8Sopenharmony_ci AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO)); 56469570cc8Sopenharmony_ci if (dacInfo == nullptr) { 56569570cc8Sopenharmony_ci return ""; 56669570cc8Sopenharmony_ci } 56769570cc8Sopenharmony_ci 56869570cc8Sopenharmony_ci std::string sandboxRoot = ""; 56969570cc8Sopenharmony_ci const std::string originSandboxPath = "/mnt/sandbox/<PackageName>"; 57069570cc8Sopenharmony_ci std::string isolatedFlagText = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? "isolated/" : ""; 57169570cc8Sopenharmony_ci const std::string defaultSandboxRoot = g_sandBoxDir + to_string(dacInfo->uid / UID_BASE) + 57269570cc8Sopenharmony_ci "/" + isolatedFlagText.c_str() + GetBundleName(appProperty); 57369570cc8Sopenharmony_ci if (config.find(g_sandboxRootPrefix) != config.end()) { 57469570cc8Sopenharmony_ci sandboxRoot = config[g_sandboxRootPrefix].get<std::string>(); 57569570cc8Sopenharmony_ci if (sandboxRoot == originSandboxPath) { 57669570cc8Sopenharmony_ci sandboxRoot = defaultSandboxRoot; 57769570cc8Sopenharmony_ci } else { 57869570cc8Sopenharmony_ci sandboxRoot = ConvertToRealPath(appProperty, sandboxRoot); 57969570cc8Sopenharmony_ci APPSPAWN_LOGV("set sandbox-root name is %{public}s", sandboxRoot.c_str()); 58069570cc8Sopenharmony_ci } 58169570cc8Sopenharmony_ci } else { 58269570cc8Sopenharmony_ci sandboxRoot = defaultSandboxRoot; 58369570cc8Sopenharmony_ci APPSPAWN_LOGV("set sandbox-root to default rootapp name is %{public}s", GetBundleName(appProperty)); 58469570cc8Sopenharmony_ci } 58569570cc8Sopenharmony_ci 58669570cc8Sopenharmony_ci return sandboxRoot; 58769570cc8Sopenharmony_ci} 58869570cc8Sopenharmony_ci 58969570cc8Sopenharmony_cibool SandboxUtils::GetSbxSwitchStatusByConfig(nlohmann::json &config) 59069570cc8Sopenharmony_ci{ 59169570cc8Sopenharmony_ci if (config.find(g_sandBoxSwitchPrefix) != config.end()) { 59269570cc8Sopenharmony_ci std::string switchStatus = config[g_sandBoxSwitchPrefix].get<std::string>(); 59369570cc8Sopenharmony_ci if (switchStatus == g_sbxSwitchCheck) { 59469570cc8Sopenharmony_ci return true; 59569570cc8Sopenharmony_ci } else { 59669570cc8Sopenharmony_ci return false; 59769570cc8Sopenharmony_ci } 59869570cc8Sopenharmony_ci } 59969570cc8Sopenharmony_ci 60069570cc8Sopenharmony_ci // if not find sandbox-switch node, default switch status is true 60169570cc8Sopenharmony_ci return true; 60269570cc8Sopenharmony_ci} 60369570cc8Sopenharmony_ci 60469570cc8Sopenharmony_cistatic bool CheckMountConfig(nlohmann::json &mntPoint, const AppSpawningCtx *appProperty, 60569570cc8Sopenharmony_ci bool checkFlag) 60669570cc8Sopenharmony_ci{ 60769570cc8Sopenharmony_ci bool istrue = mntPoint.find(g_srcPath) == mntPoint.end() || (!mntPoint[g_srcPath].is_string()) || 60869570cc8Sopenharmony_ci mntPoint.find(g_sandBoxPath) == mntPoint.end() || (!mntPoint[g_sandBoxPath].is_string()) || 60969570cc8Sopenharmony_ci ((mntPoint.find(g_sandBoxFlags) == mntPoint.end()) && 61069570cc8Sopenharmony_ci (mntPoint.find(g_sandBoxFlagsCustomized) == mntPoint.end())); 61169570cc8Sopenharmony_ci APPSPAWN_CHECK(!istrue, return false, 61269570cc8Sopenharmony_ci "read mount config failed, app name is %{public}s", GetBundleName(appProperty)); 61369570cc8Sopenharmony_ci 61469570cc8Sopenharmony_ci AppSpawnMsgDomainInfo *info = 61569570cc8Sopenharmony_ci reinterpret_cast<AppSpawnMsgDomainInfo *>(GetAppProperty(appProperty, TLV_DOMAIN_INFO)); 61669570cc8Sopenharmony_ci APPSPAWN_CHECK(info != nullptr, return false, "Filed to get domain info %{public}s", GetBundleName(appProperty)); 61769570cc8Sopenharmony_ci 61869570cc8Sopenharmony_ci if (mntPoint[g_appAplName] != nullptr) { 61969570cc8Sopenharmony_ci std::string app_apl_name = mntPoint[g_appAplName].get<std::string>(); 62069570cc8Sopenharmony_ci const char *p_app_apl = nullptr; 62169570cc8Sopenharmony_ci p_app_apl = app_apl_name.c_str(); 62269570cc8Sopenharmony_ci if (!strcmp(p_app_apl, info->apl)) { 62369570cc8Sopenharmony_ci return false; 62469570cc8Sopenharmony_ci } 62569570cc8Sopenharmony_ci } 62669570cc8Sopenharmony_ci 62769570cc8Sopenharmony_ci const std::string configSrcPath = mntPoint[g_srcPath].get<std::string>(); 62869570cc8Sopenharmony_ci // special handle wps and don't use /data/app/xxx/<Package> config 62969570cc8Sopenharmony_ci if (checkFlag && (configSrcPath.find("/data/app") != std::string::npos && 63069570cc8Sopenharmony_ci (configSrcPath.find("/base") != std::string::npos || 63169570cc8Sopenharmony_ci configSrcPath.find("/database") != std::string::npos 63269570cc8Sopenharmony_ci ) && configSrcPath.find(g_packageName) != std::string::npos)) { 63369570cc8Sopenharmony_ci return false; 63469570cc8Sopenharmony_ci } 63569570cc8Sopenharmony_ci 63669570cc8Sopenharmony_ci return true; 63769570cc8Sopenharmony_ci} 63869570cc8Sopenharmony_ci 63969570cc8Sopenharmony_cistatic int32_t DoDlpAppMountStrategy(const AppSpawningCtx *appProperty, 64069570cc8Sopenharmony_ci const std::string &srcPath, const std::string &sandboxPath, 64169570cc8Sopenharmony_ci const std::string &fsType, unsigned long mountFlags) 64269570cc8Sopenharmony_ci{ 64369570cc8Sopenharmony_ci AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO)); 64469570cc8Sopenharmony_ci if (dacInfo == nullptr) { 64569570cc8Sopenharmony_ci return -1; 64669570cc8Sopenharmony_ci } 64769570cc8Sopenharmony_ci 64869570cc8Sopenharmony_ci // umount fuse path, make sure that sandbox path is not a mount point 64969570cc8Sopenharmony_ci umount2(sandboxPath.c_str(), MNT_DETACH); 65069570cc8Sopenharmony_ci 65169570cc8Sopenharmony_ci int fd = open("/dev/fuse", O_RDWR); 65269570cc8Sopenharmony_ci APPSPAWN_CHECK(fd != -1, return -EINVAL, "open /dev/fuse failed, errno is %{public}d", errno); 65369570cc8Sopenharmony_ci 65469570cc8Sopenharmony_ci char options[OPTIONS_MAX_LEN]; 65569570cc8Sopenharmony_ci (void)sprintf_s(options, sizeof(options), "fd=%d," 65669570cc8Sopenharmony_ci "rootmode=40000,user_id=%u,group_id=%u,allow_other," 65769570cc8Sopenharmony_ci "context=\"u:object_r:dlp_fuse_file:s0\"," 65869570cc8Sopenharmony_ci "fscontext=u:object_r:dlp_fuse_file:s0", 65969570cc8Sopenharmony_ci fd, dacInfo->uid, dacInfo->gid); 66069570cc8Sopenharmony_ci 66169570cc8Sopenharmony_ci // To make sure destinationPath exist 66269570cc8Sopenharmony_ci MakeDirRecursive(sandboxPath, FILE_MODE); 66369570cc8Sopenharmony_ci 66469570cc8Sopenharmony_ci int ret = 0; 66569570cc8Sopenharmony_ci#ifndef APPSPAWN_TEST 66669570cc8Sopenharmony_ci APPSPAWN_LOGV("Bind mount %{public}s to %{public}s '%{public}s' '%{public}lu' '%{public}s'", 66769570cc8Sopenharmony_ci srcPath.c_str(), sandboxPath.c_str(), fsType.c_str(), mountFlags, options); 66869570cc8Sopenharmony_ci ret = mount(srcPath.c_str(), sandboxPath.c_str(), fsType.c_str(), mountFlags, options); 66969570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, close(fd); 67069570cc8Sopenharmony_ci return ret, "DoDlpAppMountStrategy failed, bind mount %{public}s to %{public}s failed %{public}d", 67169570cc8Sopenharmony_ci srcPath.c_str(), sandboxPath.c_str(), errno); 67269570cc8Sopenharmony_ci 67369570cc8Sopenharmony_ci ret = mount(nullptr, sandboxPath.c_str(), nullptr, MS_SHARED, nullptr); 67469570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, close(fd); 67569570cc8Sopenharmony_ci return ret, "errno is: %{public}d, private mount to %{public}s failed", errno, sandboxPath.c_str()); 67669570cc8Sopenharmony_ci#endif 67769570cc8Sopenharmony_ci /* set DLP_FUSE_FD */ 67869570cc8Sopenharmony_ci#ifdef WITH_DLP 67969570cc8Sopenharmony_ci SetDlpFuseFd(fd); 68069570cc8Sopenharmony_ci#endif 68169570cc8Sopenharmony_ci ret = fd; 68269570cc8Sopenharmony_ci return ret; 68369570cc8Sopenharmony_ci} 68469570cc8Sopenharmony_ci 68569570cc8Sopenharmony_cistatic int32_t HandleSpecialAppMount(const AppSpawningCtx *appProperty, 68669570cc8Sopenharmony_ci const std::string &srcPath, const std::string &sandboxPath, const std::string &fsType, unsigned long mountFlags) 68769570cc8Sopenharmony_ci{ 68869570cc8Sopenharmony_ci std::string bundleName = GetBundleName(appProperty); 68969570cc8Sopenharmony_ci std::string processName = GetProcessName(appProperty); 69069570cc8Sopenharmony_ci /* dlp application mount strategy */ 69169570cc8Sopenharmony_ci /* dlp is an example, we should change to real bundle name later */ 69269570cc8Sopenharmony_ci if (bundleName.find(g_dlpBundleName) != std::string::npos && 69369570cc8Sopenharmony_ci processName.compare(g_dlpBundleName) == 0) { 69469570cc8Sopenharmony_ci if (!fsType.empty()) { 69569570cc8Sopenharmony_ci return DoDlpAppMountStrategy(appProperty, srcPath, sandboxPath, fsType, mountFlags); 69669570cc8Sopenharmony_ci } 69769570cc8Sopenharmony_ci } 69869570cc8Sopenharmony_ci return -1; 69969570cc8Sopenharmony_ci} 70069570cc8Sopenharmony_ci 70169570cc8Sopenharmony_cistatic uint32_t ConvertFlagStr(const std::string &flagStr) 70269570cc8Sopenharmony_ci{ 70369570cc8Sopenharmony_ci const std::map<std::string, int> flagsMap = {{"0", 0}, {"START_FLAGS_BACKUP", 1}, 70469570cc8Sopenharmony_ci {"DLP_MANAGER", 2}, 70569570cc8Sopenharmony_ci {"DEVELOPER_MODE", 17}}; 70669570cc8Sopenharmony_ci 70769570cc8Sopenharmony_ci if (flagsMap.count(flagStr)) { 70869570cc8Sopenharmony_ci return 1 << flagsMap.at(flagStr); 70969570cc8Sopenharmony_ci } 71069570cc8Sopenharmony_ci 71169570cc8Sopenharmony_ci return 0; 71269570cc8Sopenharmony_ci} 71369570cc8Sopenharmony_ci 71469570cc8Sopenharmony_ciunsigned long SandboxUtils::GetSandboxMountFlags(nlohmann::json &config) 71569570cc8Sopenharmony_ci{ 71669570cc8Sopenharmony_ci unsigned long mountFlags = BASIC_MOUNT_FLAGS; 71769570cc8Sopenharmony_ci if (GetSandboxDacOverrideEnable(config) && (config.find(g_sandBoxFlagsCustomized) != config.end())) { 71869570cc8Sopenharmony_ci mountFlags = GetMountFlagsFromConfig(config[g_sandBoxFlagsCustomized].get<std::vector<std::string>>()); 71969570cc8Sopenharmony_ci } else if (config.find(g_sandBoxFlags) != config.end()) { 72069570cc8Sopenharmony_ci mountFlags = GetMountFlagsFromConfig(config[g_sandBoxFlags].get<std::vector<std::string>>()); 72169570cc8Sopenharmony_ci } 72269570cc8Sopenharmony_ci return mountFlags; 72369570cc8Sopenharmony_ci} 72469570cc8Sopenharmony_ci 72569570cc8Sopenharmony_cistd::string SandboxUtils::GetSandboxFsType(nlohmann::json &config) 72669570cc8Sopenharmony_ci{ 72769570cc8Sopenharmony_ci std::string fsType = ""; 72869570cc8Sopenharmony_ci if (GetSandboxDacOverrideEnable(config) && (config.find(g_fsType) != config.end())) { 72969570cc8Sopenharmony_ci fsType = config[g_fsType].get<std::string>(); 73069570cc8Sopenharmony_ci } 73169570cc8Sopenharmony_ci return fsType; 73269570cc8Sopenharmony_ci} 73369570cc8Sopenharmony_ci 73469570cc8Sopenharmony_cistd::string SandboxUtils::GetSandboxOptions(const AppSpawningCtx *appProperty, nlohmann::json &config) 73569570cc8Sopenharmony_ci{ 73669570cc8Sopenharmony_ci AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO)); 73769570cc8Sopenharmony_ci if (dacInfo == nullptr) { 73869570cc8Sopenharmony_ci return ""; 73969570cc8Sopenharmony_ci } 74069570cc8Sopenharmony_ci 74169570cc8Sopenharmony_ci std::string options = ""; 74269570cc8Sopenharmony_ci const int userIdBase = 200000; 74369570cc8Sopenharmony_ci if (GetSandboxDacOverrideEnable(config) && (config.find(g_sandBoxOptions) != config.end())) { 74469570cc8Sopenharmony_ci options = config[g_sandBoxOptions].get<std::string>() + ",user_id="; 74569570cc8Sopenharmony_ci options += std::to_string(dacInfo->uid / userIdBase); 74669570cc8Sopenharmony_ci } 74769570cc8Sopenharmony_ci return options; 74869570cc8Sopenharmony_ci} 74969570cc8Sopenharmony_ci 75069570cc8Sopenharmony_civoid SandboxUtils::GetSandboxMountConfig(const AppSpawningCtx *appProperty, const std::string §ion, 75169570cc8Sopenharmony_ci nlohmann::json &mntPoint, SandboxMountConfig &mountConfig) 75269570cc8Sopenharmony_ci{ 75369570cc8Sopenharmony_ci if (section.compare(g_permissionPrefix) == 0) { 75469570cc8Sopenharmony_ci mountConfig.optionsPoint = GetSandboxOptions(appProperty, mntPoint); 75569570cc8Sopenharmony_ci mountConfig.fsType = GetSandboxFsType(mntPoint); 75669570cc8Sopenharmony_ci } else { 75769570cc8Sopenharmony_ci mountConfig.fsType = (mntPoint.find(g_fsType) != mntPoint.end()) ? mntPoint[g_fsType].get<std::string>() : ""; 75869570cc8Sopenharmony_ci mountConfig.optionsPoint = ""; 75969570cc8Sopenharmony_ci } 76069570cc8Sopenharmony_ci return; 76169570cc8Sopenharmony_ci} 76269570cc8Sopenharmony_ci 76369570cc8Sopenharmony_cistd::string SandboxUtils::GetSandboxPath(const AppSpawningCtx *appProperty, nlohmann::json &mntPoint, 76469570cc8Sopenharmony_ci const std::string §ion, std::string sandboxRoot) 76569570cc8Sopenharmony_ci{ 76669570cc8Sopenharmony_ci std::string sandboxPath = ""; 76769570cc8Sopenharmony_ci std::string tmpSandboxPath = mntPoint[g_sandBoxPath].get<std::string>(); 76869570cc8Sopenharmony_ci if (section.compare(g_permissionPrefix) == 0) { 76969570cc8Sopenharmony_ci sandboxPath = sandboxRoot + ConvertToRealPathWithPermission(appProperty, tmpSandboxPath); 77069570cc8Sopenharmony_ci } else { 77169570cc8Sopenharmony_ci sandboxPath = sandboxRoot + ConvertToRealPath(appProperty, tmpSandboxPath); 77269570cc8Sopenharmony_ci } 77369570cc8Sopenharmony_ci return sandboxPath; 77469570cc8Sopenharmony_ci} 77569570cc8Sopenharmony_ci 77669570cc8Sopenharmony_cistatic bool CheckMountFlag(const AppSpawningCtx *appProperty, const std::string bundleName, nlohmann::json &appConfig) 77769570cc8Sopenharmony_ci{ 77869570cc8Sopenharmony_ci if (appConfig.find(g_flags) != appConfig.end()) { 77969570cc8Sopenharmony_ci if (((ConvertFlagStr(appConfig[g_flags].get<std::string>()) & GetAppMsgFlags(appProperty)) != 0) && 78069570cc8Sopenharmony_ci bundleName.find("wps") != std::string::npos) { 78169570cc8Sopenharmony_ci return true; 78269570cc8Sopenharmony_ci } 78369570cc8Sopenharmony_ci } 78469570cc8Sopenharmony_ci return false; 78569570cc8Sopenharmony_ci} 78669570cc8Sopenharmony_ci 78769570cc8Sopenharmony_ciint SandboxUtils::DoAllMntPointsMount(const AppSpawningCtx *appProperty, 78869570cc8Sopenharmony_ci nlohmann::json &appConfig, const char *typeName, const std::string §ion) 78969570cc8Sopenharmony_ci{ 79069570cc8Sopenharmony_ci std::string bundleName = GetBundleName(appProperty); 79169570cc8Sopenharmony_ci if (appConfig.find(g_mountPrefix) == appConfig.end()) { 79269570cc8Sopenharmony_ci APPSPAWN_LOGV("mount config is not found in %{public}s, app name is %{public}s", 79369570cc8Sopenharmony_ci section.c_str(), bundleName.c_str()); 79469570cc8Sopenharmony_ci return 0; 79569570cc8Sopenharmony_ci } 79669570cc8Sopenharmony_ci 79769570cc8Sopenharmony_ci std::string sandboxRoot = GetSbxPathByConfig(appProperty, appConfig); 79869570cc8Sopenharmony_ci bool checkFlag = CheckMountFlag(appProperty, bundleName, appConfig); 79969570cc8Sopenharmony_ci 80069570cc8Sopenharmony_ci nlohmann::json& mountPoints = appConfig[g_mountPrefix]; 80169570cc8Sopenharmony_ci unsigned int mountPointSize = mountPoints.size(); 80269570cc8Sopenharmony_ci for (unsigned int i = 0; i < mountPointSize; i++) { 80369570cc8Sopenharmony_ci nlohmann::json& mntPoint = mountPoints[i]; 80469570cc8Sopenharmony_ci if ((CheckMountConfig(mntPoint, appProperty, checkFlag) == false)) { 80569570cc8Sopenharmony_ci continue; 80669570cc8Sopenharmony_ci } 80769570cc8Sopenharmony_ci 80869570cc8Sopenharmony_ci std::string srcPath = ConvertToRealPath(appProperty, mntPoint[g_srcPath].get<std::string>()); 80969570cc8Sopenharmony_ci std::string sandboxPath = GetSandboxPath(appProperty, mntPoint, section, sandboxRoot); 81069570cc8Sopenharmony_ci SandboxMountConfig mountConfig = {0}; 81169570cc8Sopenharmony_ci GetSandboxMountConfig(appProperty, section, mntPoint, mountConfig); 81269570cc8Sopenharmony_ci unsigned long mountFlags = GetSandboxMountFlags(mntPoint); 81369570cc8Sopenharmony_ci mode_t mountSharedFlag = (mntPoint.find(g_mountSharedFlag) != mntPoint.end()) ? MS_SHARED : MS_SLAVE; 81469570cc8Sopenharmony_ci 81569570cc8Sopenharmony_ci /* if app mount failed for special strategy, we need deal with common mount config */ 81669570cc8Sopenharmony_ci int ret = HandleSpecialAppMount(appProperty, srcPath, sandboxPath, mountConfig.fsType, mountFlags); 81769570cc8Sopenharmony_ci if (ret < 0) { 81869570cc8Sopenharmony_ci ret = DoAppSandboxMountOnce(srcPath.c_str(), sandboxPath.c_str(), mountConfig.fsType.c_str(), 81969570cc8Sopenharmony_ci mountFlags, mountConfig.optionsPoint.c_str(), mountSharedFlag); 82069570cc8Sopenharmony_ci } 82169570cc8Sopenharmony_ci if (ret) { 82269570cc8Sopenharmony_ci std::string actionStatus = g_statusCheck; 82369570cc8Sopenharmony_ci (void)JsonUtils::GetStringFromJson(mntPoint, g_actionStatuc, actionStatus); 82469570cc8Sopenharmony_ci if (actionStatus == g_statusCheck) { 82569570cc8Sopenharmony_ci APPSPAWN_LOGE("DoAppSandboxMountOnce section %{public}s failed, %{public}s", 82669570cc8Sopenharmony_ci section.c_str(), sandboxPath.c_str()); 82769570cc8Sopenharmony_ci return ret; 82869570cc8Sopenharmony_ci } 82969570cc8Sopenharmony_ci } 83069570cc8Sopenharmony_ci 83169570cc8Sopenharmony_ci DoSandboxChmod(mntPoint, sandboxRoot); 83269570cc8Sopenharmony_ci } 83369570cc8Sopenharmony_ci 83469570cc8Sopenharmony_ci return 0; 83569570cc8Sopenharmony_ci} 83669570cc8Sopenharmony_ci 83769570cc8Sopenharmony_ciint32_t SandboxUtils::DoAddGid(AppSpawningCtx *appProperty, nlohmann::json &appConfig, 83869570cc8Sopenharmony_ci const char* permissionName, const std::string §ion) 83969570cc8Sopenharmony_ci{ 84069570cc8Sopenharmony_ci std::string bundleName = GetBundleName(appProperty); 84169570cc8Sopenharmony_ci if (appConfig.find(g_gidPrefix) == appConfig.end()) { 84269570cc8Sopenharmony_ci return 0; 84369570cc8Sopenharmony_ci } 84469570cc8Sopenharmony_ci AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO)); 84569570cc8Sopenharmony_ci if (dacInfo == nullptr) { 84669570cc8Sopenharmony_ci return 0; 84769570cc8Sopenharmony_ci } 84869570cc8Sopenharmony_ci 84969570cc8Sopenharmony_ci nlohmann::json& gids = appConfig[g_gidPrefix]; 85069570cc8Sopenharmony_ci unsigned int gidSize = gids.size(); 85169570cc8Sopenharmony_ci for (unsigned int i = 0; i < gidSize; i++) { 85269570cc8Sopenharmony_ci if (dacInfo->gidCount < APP_MAX_GIDS) { 85369570cc8Sopenharmony_ci APPSPAWN_LOGI("add gid to gitTable in %{public}s, permission is %{public}s, gid:%{public}u", 85469570cc8Sopenharmony_ci bundleName.c_str(), permissionName, gids[i].get<uint32_t>()); 85569570cc8Sopenharmony_ci dacInfo->gidTable[dacInfo->gidCount++] = gids[i].get<uint32_t>(); 85669570cc8Sopenharmony_ci } 85769570cc8Sopenharmony_ci } 85869570cc8Sopenharmony_ci return 0; 85969570cc8Sopenharmony_ci} 86069570cc8Sopenharmony_ci 86169570cc8Sopenharmony_ciint SandboxUtils::DoAllSymlinkPointslink(const AppSpawningCtx *appProperty, nlohmann::json &appConfig) 86269570cc8Sopenharmony_ci{ 86369570cc8Sopenharmony_ci APPSPAWN_CHECK(appConfig.find(g_symlinkPrefix) != appConfig.end(), return 0, "symlink config is not found," 86469570cc8Sopenharmony_ci "maybe result sandbox launch failed app name is %{public}s", GetBundleName(appProperty)); 86569570cc8Sopenharmony_ci 86669570cc8Sopenharmony_ci nlohmann::json& symlinkPoints = appConfig[g_symlinkPrefix]; 86769570cc8Sopenharmony_ci std::string sandboxRoot = GetSbxPathByConfig(appProperty, appConfig); 86869570cc8Sopenharmony_ci unsigned int symlinkPointSize = symlinkPoints.size(); 86969570cc8Sopenharmony_ci 87069570cc8Sopenharmony_ci for (unsigned int i = 0; i < symlinkPointSize; i++) { 87169570cc8Sopenharmony_ci nlohmann::json& symPoint = symlinkPoints[i]; 87269570cc8Sopenharmony_ci 87369570cc8Sopenharmony_ci // Check the validity of the symlink configuration 87469570cc8Sopenharmony_ci if (symPoint.find(g_targetName) == symPoint.end() || (!symPoint[g_targetName].is_string()) || 87569570cc8Sopenharmony_ci symPoint.find(g_linkName) == symPoint.end() || (!symPoint[g_linkName].is_string())) { 87669570cc8Sopenharmony_ci APPSPAWN_LOGE("read symlink config failed, app name is %{public}s", GetBundleName(appProperty)); 87769570cc8Sopenharmony_ci continue; 87869570cc8Sopenharmony_ci } 87969570cc8Sopenharmony_ci 88069570cc8Sopenharmony_ci std::string targetName = ConvertToRealPath(appProperty, symPoint[g_targetName].get<std::string>()); 88169570cc8Sopenharmony_ci std::string linkName = sandboxRoot + ConvertToRealPath(appProperty, symPoint[g_linkName].get<std::string>()); 88269570cc8Sopenharmony_ci APPSPAWN_LOGV("symlink, from %{public}s to %{public}s", targetName.c_str(), linkName.c_str()); 88369570cc8Sopenharmony_ci 88469570cc8Sopenharmony_ci int ret = symlink(targetName.c_str(), linkName.c_str()); 88569570cc8Sopenharmony_ci if (ret && errno != EEXIST) { 88669570cc8Sopenharmony_ci APPSPAWN_LOGE("errno is %{public}d, symlink failed, %{public}s", errno, linkName.c_str()); 88769570cc8Sopenharmony_ci 88869570cc8Sopenharmony_ci std::string actionStatus = g_statusCheck; 88969570cc8Sopenharmony_ci (void)JsonUtils::GetStringFromJson(symPoint, g_actionStatuc, actionStatus); 89069570cc8Sopenharmony_ci if (actionStatus == g_statusCheck) { 89169570cc8Sopenharmony_ci return ret; 89269570cc8Sopenharmony_ci } 89369570cc8Sopenharmony_ci } 89469570cc8Sopenharmony_ci 89569570cc8Sopenharmony_ci DoSandboxChmod(symPoint, sandboxRoot); 89669570cc8Sopenharmony_ci } 89769570cc8Sopenharmony_ci 89869570cc8Sopenharmony_ci return 0; 89969570cc8Sopenharmony_ci} 90069570cc8Sopenharmony_ci 90169570cc8Sopenharmony_ciint32_t SandboxUtils::DoSandboxFilePrivateBind(const AppSpawningCtx *appProperty, 90269570cc8Sopenharmony_ci nlohmann::json &wholeConfig) 90369570cc8Sopenharmony_ci{ 90469570cc8Sopenharmony_ci const char *bundleName = GetBundleName(appProperty); 90569570cc8Sopenharmony_ci nlohmann::json& privateAppConfig = wholeConfig[g_privatePrefix][0]; 90669570cc8Sopenharmony_ci if (privateAppConfig.find(bundleName) != privateAppConfig.end()) { 90769570cc8Sopenharmony_ci APPSPAWN_LOGV("DoSandboxFilePrivateBind %{public}s", bundleName); 90869570cc8Sopenharmony_ci DoAddGid((AppSpawningCtx *)appProperty, privateAppConfig[bundleName][0], "", g_privatePrefix); 90969570cc8Sopenharmony_ci return DoAllMntPointsMount(appProperty, privateAppConfig[bundleName][0], nullptr, g_privatePrefix); 91069570cc8Sopenharmony_ci } 91169570cc8Sopenharmony_ci 91269570cc8Sopenharmony_ci return 0; 91369570cc8Sopenharmony_ci} 91469570cc8Sopenharmony_ci 91569570cc8Sopenharmony_ciint32_t SandboxUtils::DoSandboxFilePermissionBind(AppSpawningCtx *appProperty, 91669570cc8Sopenharmony_ci nlohmann::json &wholeConfig) 91769570cc8Sopenharmony_ci{ 91869570cc8Sopenharmony_ci if (wholeConfig.find(g_permissionPrefix) == wholeConfig.end()) { 91969570cc8Sopenharmony_ci APPSPAWN_LOGV("DoSandboxFilePermissionBind not found permission information in config file"); 92069570cc8Sopenharmony_ci return 0; 92169570cc8Sopenharmony_ci } 92269570cc8Sopenharmony_ci nlohmann::json& permissionAppConfig = wholeConfig[g_permissionPrefix][0]; 92369570cc8Sopenharmony_ci for (nlohmann::json::iterator it = permissionAppConfig.begin(); it != permissionAppConfig.end(); ++it) { 92469570cc8Sopenharmony_ci const std::string permission = it.key(); 92569570cc8Sopenharmony_ci int index = GetPermissionIndex(nullptr, permission.c_str()); 92669570cc8Sopenharmony_ci APPSPAWN_LOGV("DoSandboxFilePermissionBind mountPermissionFlags %{public}d", index); 92769570cc8Sopenharmony_ci if (CheckAppPermissionFlagSet(appProperty, static_cast<uint32_t>(index))) { 92869570cc8Sopenharmony_ci DoAddGid(appProperty, permissionAppConfig[permission][0], permission.c_str(), g_permissionPrefix); 92969570cc8Sopenharmony_ci DoAllMntPointsMount(appProperty, permissionAppConfig[permission][0], permission.c_str(), 93069570cc8Sopenharmony_ci g_permissionPrefix); 93169570cc8Sopenharmony_ci } else { 93269570cc8Sopenharmony_ci APPSPAWN_LOGV("DoSandboxFilePermissionBind false %{public}s permission %{public}s", 93369570cc8Sopenharmony_ci GetBundleName(appProperty), permission.c_str()); 93469570cc8Sopenharmony_ci } 93569570cc8Sopenharmony_ci } 93669570cc8Sopenharmony_ci return 0; 93769570cc8Sopenharmony_ci} 93869570cc8Sopenharmony_ci 93969570cc8Sopenharmony_cistd::set<std::string> SandboxUtils::GetMountPermissionNames() 94069570cc8Sopenharmony_ci{ 94169570cc8Sopenharmony_ci std::set<std::string> permissionSet; 94269570cc8Sopenharmony_ci for (auto& config : SandboxUtils::GetJsonConfig(SANBOX_APP_JSON_CONFIG)) { 94369570cc8Sopenharmony_ci if (config.find(g_permissionPrefix) == config.end()) { 94469570cc8Sopenharmony_ci continue; 94569570cc8Sopenharmony_ci } 94669570cc8Sopenharmony_ci nlohmann::json& permissionAppConfig = config[g_permissionPrefix][0]; 94769570cc8Sopenharmony_ci for (auto it = permissionAppConfig.begin(); it != permissionAppConfig.end(); it++) { 94869570cc8Sopenharmony_ci permissionSet.insert(it.key()); 94969570cc8Sopenharmony_ci } 95069570cc8Sopenharmony_ci } 95169570cc8Sopenharmony_ci APPSPAWN_LOGI("GetMountPermissionNames size: %{public}lu", static_cast<unsigned long>(permissionSet.size())); 95269570cc8Sopenharmony_ci return permissionSet; 95369570cc8Sopenharmony_ci} 95469570cc8Sopenharmony_ci 95569570cc8Sopenharmony_ciint32_t SandboxUtils::DoSandboxFilePrivateSymlink(const AppSpawningCtx *appProperty, 95669570cc8Sopenharmony_ci nlohmann::json &wholeConfig) 95769570cc8Sopenharmony_ci{ 95869570cc8Sopenharmony_ci const char *bundleName = GetBundleName(appProperty); 95969570cc8Sopenharmony_ci nlohmann::json& privateAppConfig = wholeConfig[g_privatePrefix][0]; 96069570cc8Sopenharmony_ci if (privateAppConfig.find(bundleName) != privateAppConfig.end()) { 96169570cc8Sopenharmony_ci return DoAllSymlinkPointslink(appProperty, privateAppConfig[bundleName][0]); 96269570cc8Sopenharmony_ci } 96369570cc8Sopenharmony_ci 96469570cc8Sopenharmony_ci return 0; 96569570cc8Sopenharmony_ci} 96669570cc8Sopenharmony_ci 96769570cc8Sopenharmony_ciint32_t SandboxUtils::HandleFlagsPoint(const AppSpawningCtx *appProperty, 96869570cc8Sopenharmony_ci nlohmann::json &appConfig) 96969570cc8Sopenharmony_ci{ 97069570cc8Sopenharmony_ci if (appConfig.find(g_flagePoint) == appConfig.end()) { 97169570cc8Sopenharmony_ci return 0; 97269570cc8Sopenharmony_ci } 97369570cc8Sopenharmony_ci 97469570cc8Sopenharmony_ci nlohmann::json& flagsPoints = appConfig[g_flagePoint]; 97569570cc8Sopenharmony_ci unsigned int flagsPointSize = flagsPoints.size(); 97669570cc8Sopenharmony_ci 97769570cc8Sopenharmony_ci for (unsigned int i = 0; i < flagsPointSize; i++) { 97869570cc8Sopenharmony_ci nlohmann::json& flagPoint = flagsPoints[i]; 97969570cc8Sopenharmony_ci 98069570cc8Sopenharmony_ci if (flagPoint.find(g_flags) != flagPoint.end() && flagPoint[g_flags].is_string()) { 98169570cc8Sopenharmony_ci std::string flagsStr = flagPoint[g_flags].get<std::string>(); 98269570cc8Sopenharmony_ci uint32_t flag = ConvertFlagStr(flagsStr); 98369570cc8Sopenharmony_ci if ((GetAppMsgFlags(appProperty) & flag) != 0) { 98469570cc8Sopenharmony_ci return DoAllMntPointsMount(appProperty, flagPoint, nullptr, g_flagePoint); 98569570cc8Sopenharmony_ci } 98669570cc8Sopenharmony_ci } else { 98769570cc8Sopenharmony_ci APPSPAWN_LOGE("read flags config failed, app name is %{public}s", GetBundleName(appProperty)); 98869570cc8Sopenharmony_ci } 98969570cc8Sopenharmony_ci } 99069570cc8Sopenharmony_ci 99169570cc8Sopenharmony_ci return 0; 99269570cc8Sopenharmony_ci} 99369570cc8Sopenharmony_ci 99469570cc8Sopenharmony_ciint32_t SandboxUtils::DoSandboxFilePrivateFlagsPointHandle(const AppSpawningCtx *appProperty, 99569570cc8Sopenharmony_ci nlohmann::json &wholeConfig) 99669570cc8Sopenharmony_ci{ 99769570cc8Sopenharmony_ci const char *bundleName = GetBundleName(appProperty); 99869570cc8Sopenharmony_ci nlohmann::json& privateAppConfig = wholeConfig[g_privatePrefix][0]; 99969570cc8Sopenharmony_ci if (privateAppConfig.find(bundleName) != privateAppConfig.end()) { 100069570cc8Sopenharmony_ci return HandleFlagsPoint(appProperty, privateAppConfig[bundleName][0]); 100169570cc8Sopenharmony_ci } 100269570cc8Sopenharmony_ci 100369570cc8Sopenharmony_ci return 0; 100469570cc8Sopenharmony_ci} 100569570cc8Sopenharmony_ci 100669570cc8Sopenharmony_ciint32_t SandboxUtils::DoSandboxFileCommonFlagsPointHandle(const AppSpawningCtx *appProperty, 100769570cc8Sopenharmony_ci nlohmann::json &wholeConfig) 100869570cc8Sopenharmony_ci{ 100969570cc8Sopenharmony_ci nlohmann::json& commonConfig = wholeConfig[g_commonPrefix][0]; 101069570cc8Sopenharmony_ci if (commonConfig.find(g_appResources) != commonConfig.end()) { 101169570cc8Sopenharmony_ci return HandleFlagsPoint(appProperty, commonConfig[g_appResources][0]); 101269570cc8Sopenharmony_ci } 101369570cc8Sopenharmony_ci 101469570cc8Sopenharmony_ci return 0; 101569570cc8Sopenharmony_ci} 101669570cc8Sopenharmony_ci 101769570cc8Sopenharmony_ciint32_t SandboxUtils::DoSandboxFileCommonBind(const AppSpawningCtx *appProperty, nlohmann::json &wholeConfig) 101869570cc8Sopenharmony_ci{ 101969570cc8Sopenharmony_ci nlohmann::json& commonConfig = wholeConfig[g_commonPrefix][0]; 102069570cc8Sopenharmony_ci int ret = 0; 102169570cc8Sopenharmony_ci 102269570cc8Sopenharmony_ci if (commonConfig.find(g_appBase) != commonConfig.end()) { 102369570cc8Sopenharmony_ci ret = DoAllMntPointsMount(appProperty, commonConfig[g_appBase][0], nullptr, g_appBase); 102469570cc8Sopenharmony_ci if (ret) { 102569570cc8Sopenharmony_ci return ret; 102669570cc8Sopenharmony_ci } 102769570cc8Sopenharmony_ci } 102869570cc8Sopenharmony_ci 102969570cc8Sopenharmony_ci if (commonConfig.find(g_appResources) != commonConfig.end()) { 103069570cc8Sopenharmony_ci ret = DoAllMntPointsMount(appProperty, commonConfig[g_appResources][0], nullptr, g_appResources); 103169570cc8Sopenharmony_ci } 103269570cc8Sopenharmony_ci 103369570cc8Sopenharmony_ci return ret; 103469570cc8Sopenharmony_ci} 103569570cc8Sopenharmony_ci 103669570cc8Sopenharmony_ciint32_t SandboxUtils::DoSandboxFileCommonSymlink(const AppSpawningCtx *appProperty, 103769570cc8Sopenharmony_ci nlohmann::json &wholeConfig) 103869570cc8Sopenharmony_ci{ 103969570cc8Sopenharmony_ci nlohmann::json& commonConfig = wholeConfig[g_commonPrefix][0]; 104069570cc8Sopenharmony_ci int ret = 0; 104169570cc8Sopenharmony_ci 104269570cc8Sopenharmony_ci if (commonConfig.find(g_appBase) != commonConfig.end()) { 104369570cc8Sopenharmony_ci ret = DoAllSymlinkPointslink(appProperty, commonConfig[g_appBase][0]); 104469570cc8Sopenharmony_ci if (ret) { 104569570cc8Sopenharmony_ci return ret; 104669570cc8Sopenharmony_ci } 104769570cc8Sopenharmony_ci } 104869570cc8Sopenharmony_ci 104969570cc8Sopenharmony_ci if (commonConfig.find(g_appResources) != commonConfig.end()) { 105069570cc8Sopenharmony_ci ret = DoAllSymlinkPointslink(appProperty, commonConfig[g_appResources][0]); 105169570cc8Sopenharmony_ci } 105269570cc8Sopenharmony_ci 105369570cc8Sopenharmony_ci return ret; 105469570cc8Sopenharmony_ci} 105569570cc8Sopenharmony_ci 105669570cc8Sopenharmony_ciint32_t SandboxUtils::SetPrivateAppSandboxProperty_(const AppSpawningCtx *appProperty, 105769570cc8Sopenharmony_ci nlohmann::json &config) 105869570cc8Sopenharmony_ci{ 105969570cc8Sopenharmony_ci int ret = DoSandboxFilePrivateBind(appProperty, config); 106069570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "DoSandboxFilePrivateBind failed"); 106169570cc8Sopenharmony_ci 106269570cc8Sopenharmony_ci ret = DoSandboxFilePrivateSymlink(appProperty, config); 106369570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_LOG(ret == 0, "DoSandboxFilePrivateSymlink failed"); 106469570cc8Sopenharmony_ci 106569570cc8Sopenharmony_ci ret = DoSandboxFilePrivateFlagsPointHandle(appProperty, config); 106669570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_LOG(ret == 0, "DoSandboxFilePrivateFlagsPointHandle failed"); 106769570cc8Sopenharmony_ci 106869570cc8Sopenharmony_ci return ret; 106969570cc8Sopenharmony_ci} 107069570cc8Sopenharmony_ci 107169570cc8Sopenharmony_ciint32_t SandboxUtils::SetPermissionAppSandboxProperty_(AppSpawningCtx *appProperty, 107269570cc8Sopenharmony_ci nlohmann::json &config) 107369570cc8Sopenharmony_ci{ 107469570cc8Sopenharmony_ci int ret = DoSandboxFilePermissionBind(appProperty, config); 107569570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "DoSandboxFilePermissionBind failed"); 107669570cc8Sopenharmony_ci return ret; 107769570cc8Sopenharmony_ci} 107869570cc8Sopenharmony_ci 107969570cc8Sopenharmony_ci 108069570cc8Sopenharmony_ciint32_t SandboxUtils::SetRenderSandboxProperty(const AppSpawningCtx *appProperty, 108169570cc8Sopenharmony_ci std::string &sandboxPackagePath) 108269570cc8Sopenharmony_ci{ 108369570cc8Sopenharmony_ci return 0; 108469570cc8Sopenharmony_ci} 108569570cc8Sopenharmony_ci 108669570cc8Sopenharmony_ciint32_t SandboxUtils::SetRenderSandboxPropertyNweb(const AppSpawningCtx *appProperty, 108769570cc8Sopenharmony_ci std::string &sandboxPackagePath) 108869570cc8Sopenharmony_ci{ 108969570cc8Sopenharmony_ci SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? 109069570cc8Sopenharmony_ci SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG; 109169570cc8Sopenharmony_ci 109269570cc8Sopenharmony_ci for (auto& config : SandboxUtils::GetJsonConfig(type)) { 109369570cc8Sopenharmony_ci nlohmann::json& privateAppConfig = config[g_privatePrefix][0]; 109469570cc8Sopenharmony_ci if (privateAppConfig.find(g_ohosRender) != privateAppConfig.end()) { 109569570cc8Sopenharmony_ci int ret = DoAllMntPointsMount(appProperty, privateAppConfig[g_ohosRender][0], nullptr, g_ohosRender); 109669570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "DoAllMntPointsMount failed, %{public}s", 109769570cc8Sopenharmony_ci GetBundleName(appProperty)); 109869570cc8Sopenharmony_ci ret = DoAllSymlinkPointslink(appProperty, privateAppConfig[g_ohosRender][0]); 109969570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "DoAllSymlinkPointslink failed, %{public}s", 110069570cc8Sopenharmony_ci GetBundleName(appProperty)); 110169570cc8Sopenharmony_ci ret = HandleFlagsPoint(appProperty, privateAppConfig[g_ohosRender][0]); 110269570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_LOG(ret == 0, "HandleFlagsPoint for render-sandbox failed, %{public}s", 110369570cc8Sopenharmony_ci GetBundleName(appProperty)); 110469570cc8Sopenharmony_ci } 110569570cc8Sopenharmony_ci } 110669570cc8Sopenharmony_ci return 0; 110769570cc8Sopenharmony_ci} 110869570cc8Sopenharmony_ci 110969570cc8Sopenharmony_ciint32_t SandboxUtils::SetPrivateAppSandboxProperty(const AppSpawningCtx *appProperty) 111069570cc8Sopenharmony_ci{ 111169570cc8Sopenharmony_ci int ret = 0; 111269570cc8Sopenharmony_ci SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? 111369570cc8Sopenharmony_ci SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG; 111469570cc8Sopenharmony_ci 111569570cc8Sopenharmony_ci for (auto& config : SandboxUtils::GetJsonConfig(type)) { 111669570cc8Sopenharmony_ci ret = SetPrivateAppSandboxProperty_(appProperty, config); 111769570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "parse adddata-sandbox config failed"); 111869570cc8Sopenharmony_ci } 111969570cc8Sopenharmony_ci return ret; 112069570cc8Sopenharmony_ci} 112169570cc8Sopenharmony_ci 112269570cc8Sopenharmony_cistatic bool GetSandboxPrivateSharedStatus(const string &bundleName, AppSpawningCtx *appProperty) 112369570cc8Sopenharmony_ci{ 112469570cc8Sopenharmony_ci bool result = false; 112569570cc8Sopenharmony_ci SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? 112669570cc8Sopenharmony_ci SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG; 112769570cc8Sopenharmony_ci 112869570cc8Sopenharmony_ci for (auto& config : SandboxUtils::GetJsonConfig(type)) { 112969570cc8Sopenharmony_ci nlohmann::json& privateAppConfig = config[g_privatePrefix][0]; 113069570cc8Sopenharmony_ci if (privateAppConfig.find(bundleName) != privateAppConfig.end() && 113169570cc8Sopenharmony_ci privateAppConfig[bundleName][0].find(g_sandBoxShared) != 113269570cc8Sopenharmony_ci privateAppConfig[bundleName][0].end()) { 113369570cc8Sopenharmony_ci string sandboxSharedStatus = 113469570cc8Sopenharmony_ci privateAppConfig[bundleName][0][g_sandBoxShared].get<std::string>(); 113569570cc8Sopenharmony_ci if (sandboxSharedStatus == g_statusCheck) { 113669570cc8Sopenharmony_ci result = true; 113769570cc8Sopenharmony_ci } 113869570cc8Sopenharmony_ci } 113969570cc8Sopenharmony_ci } 114069570cc8Sopenharmony_ci return result; 114169570cc8Sopenharmony_ci} 114269570cc8Sopenharmony_ci 114369570cc8Sopenharmony_ciint32_t SandboxUtils::SetPermissionAppSandboxProperty(AppSpawningCtx *appProperty) 114469570cc8Sopenharmony_ci{ 114569570cc8Sopenharmony_ci int ret = 0; 114669570cc8Sopenharmony_ci SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? 114769570cc8Sopenharmony_ci SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG; 114869570cc8Sopenharmony_ci 114969570cc8Sopenharmony_ci for (auto& config : SandboxUtils::GetJsonConfig(type)) { 115069570cc8Sopenharmony_ci ret = SetPermissionAppSandboxProperty_(appProperty, config); 115169570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "parse adddata-sandbox config failed"); 115269570cc8Sopenharmony_ci } 115369570cc8Sopenharmony_ci return ret; 115469570cc8Sopenharmony_ci} 115569570cc8Sopenharmony_ci 115669570cc8Sopenharmony_ci 115769570cc8Sopenharmony_ciint32_t SandboxUtils::SetCommonAppSandboxProperty_(const AppSpawningCtx *appProperty, 115869570cc8Sopenharmony_ci nlohmann::json &config) 115969570cc8Sopenharmony_ci{ 116069570cc8Sopenharmony_ci int rc = 0; 116169570cc8Sopenharmony_ci 116269570cc8Sopenharmony_ci rc = DoSandboxFileCommonBind(appProperty, config); 116369570cc8Sopenharmony_ci APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxFileCommonBind failed, %{public}s", GetBundleName(appProperty)); 116469570cc8Sopenharmony_ci 116569570cc8Sopenharmony_ci // if sandbox switch is off, don't do symlink work again 116669570cc8Sopenharmony_ci if (CheckAppSandboxSwitchStatus(appProperty) == true && (CheckTotalSandboxSwitchStatus(appProperty) == true)) { 116769570cc8Sopenharmony_ci rc = DoSandboxFileCommonSymlink(appProperty, config); 116869570cc8Sopenharmony_ci APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxFileCommonSymlink failed, %{public}s", GetBundleName(appProperty)); 116969570cc8Sopenharmony_ci } 117069570cc8Sopenharmony_ci 117169570cc8Sopenharmony_ci rc = DoSandboxFileCommonFlagsPointHandle(appProperty, config); 117269570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_LOG(rc == 0, "DoSandboxFilePrivateFlagsPointHandle failed"); 117369570cc8Sopenharmony_ci 117469570cc8Sopenharmony_ci return rc; 117569570cc8Sopenharmony_ci} 117669570cc8Sopenharmony_ci 117769570cc8Sopenharmony_ciint32_t SandboxUtils::SetCommonAppSandboxProperty(const AppSpawningCtx *appProperty, 117869570cc8Sopenharmony_ci std::string &sandboxPackagePath) 117969570cc8Sopenharmony_ci{ 118069570cc8Sopenharmony_ci int ret = 0; 118169570cc8Sopenharmony_ci SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? 118269570cc8Sopenharmony_ci SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG; 118369570cc8Sopenharmony_ci 118469570cc8Sopenharmony_ci for (auto& jsonConfig : SandboxUtils::GetJsonConfig(type)) { 118569570cc8Sopenharmony_ci ret = SetCommonAppSandboxProperty_(appProperty, jsonConfig); 118669570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, 118769570cc8Sopenharmony_ci "parse appdata config for common failed, %{public}s", sandboxPackagePath.c_str()); 118869570cc8Sopenharmony_ci } 118969570cc8Sopenharmony_ci 119069570cc8Sopenharmony_ci ret = MountAllHsp(appProperty, sandboxPackagePath); 119169570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "mount extraInfo failed, %{public}s", sandboxPackagePath.c_str()); 119269570cc8Sopenharmony_ci 119369570cc8Sopenharmony_ci ret = MountAllGroup(appProperty, sandboxPackagePath); 119469570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "mount groupList failed, %{public}s", sandboxPackagePath.c_str()); 119569570cc8Sopenharmony_ci 119669570cc8Sopenharmony_ci AppSpawnMsgDomainInfo *info = 119769570cc8Sopenharmony_ci reinterpret_cast<AppSpawnMsgDomainInfo *>(GetAppProperty(appProperty, TLV_DOMAIN_INFO)); 119869570cc8Sopenharmony_ci APPSPAWN_CHECK(info != nullptr, return -1, "No domain info %{public}s", sandboxPackagePath.c_str()); 119969570cc8Sopenharmony_ci if (strcmp(info->apl, APL_SYSTEM_BASIC.data()) == 0 || 120069570cc8Sopenharmony_ci strcmp(info->apl, APL_SYSTEM_CORE.data()) == 0 || 120169570cc8Sopenharmony_ci CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ACCESS_BUNDLE_DIR)) { 120269570cc8Sopenharmony_ci // need permission check for system app here 120369570cc8Sopenharmony_ci std::string destbundlesPath = sandboxPackagePath + g_dataBundles; 120469570cc8Sopenharmony_ci DoAppSandboxMountOnce(g_physicalAppInstallPath.c_str(), destbundlesPath.c_str(), "", BASIC_MOUNT_FLAGS, 120569570cc8Sopenharmony_ci nullptr); 120669570cc8Sopenharmony_ci } 120769570cc8Sopenharmony_ci 120869570cc8Sopenharmony_ci return 0; 120969570cc8Sopenharmony_ci} 121069570cc8Sopenharmony_ci 121169570cc8Sopenharmony_cistatic inline bool CheckPath(const std::string& name) 121269570cc8Sopenharmony_ci{ 121369570cc8Sopenharmony_ci return !name.empty() && name != "." && name != ".." && name.find("/") == std::string::npos; 121469570cc8Sopenharmony_ci} 121569570cc8Sopenharmony_ci 121669570cc8Sopenharmony_cistd::string SandboxUtils::GetExtraInfoByType(const AppSpawningCtx *appProperty, const std::string &type) 121769570cc8Sopenharmony_ci{ 121869570cc8Sopenharmony_ci uint32_t len = 0; 121969570cc8Sopenharmony_ci char *info = reinterpret_cast<char *>(GetAppPropertyExt(appProperty, type.c_str(), &len)); 122069570cc8Sopenharmony_ci if (info == nullptr) { 122169570cc8Sopenharmony_ci return ""; 122269570cc8Sopenharmony_ci } 122369570cc8Sopenharmony_ci return std::string(info, len); 122469570cc8Sopenharmony_ci} 122569570cc8Sopenharmony_ci 122669570cc8Sopenharmony_ciint32_t SandboxUtils::MountAllHsp(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath) 122769570cc8Sopenharmony_ci{ 122869570cc8Sopenharmony_ci int ret = 0; 122969570cc8Sopenharmony_ci string hspListInfo = GetExtraInfoByType(appProperty, HSPLIST_SOCKET_TYPE); 123069570cc8Sopenharmony_ci if (hspListInfo.length() == 0) { 123169570cc8Sopenharmony_ci return ret; 123269570cc8Sopenharmony_ci } 123369570cc8Sopenharmony_ci 123469570cc8Sopenharmony_ci nlohmann::json hsps = nlohmann::json::parse(hspListInfo.c_str(), nullptr, false); 123569570cc8Sopenharmony_ci APPSPAWN_CHECK(!hsps.is_discarded() && hsps.contains(g_hspList_key_bundles) && hsps.contains(g_hspList_key_modules) 123669570cc8Sopenharmony_ci && hsps.contains(g_hspList_key_versions), return -1, "MountAllHsp: json parse failed"); 123769570cc8Sopenharmony_ci 123869570cc8Sopenharmony_ci nlohmann::json& bundles = hsps[g_hspList_key_bundles]; 123969570cc8Sopenharmony_ci nlohmann::json& modules = hsps[g_hspList_key_modules]; 124069570cc8Sopenharmony_ci nlohmann::json& versions = hsps[g_hspList_key_versions]; 124169570cc8Sopenharmony_ci APPSPAWN_CHECK(bundles.is_array() && modules.is_array() && versions.is_array() && bundles.size() == modules.size() 124269570cc8Sopenharmony_ci && bundles.size() == versions.size(), return -1, "MountAllHsp: value is not arrary or sizes are not same"); 124369570cc8Sopenharmony_ci 124469570cc8Sopenharmony_ci APPSPAWN_LOGI("MountAllHsp: app = %{public}s, cnt = %{public}lu", 124569570cc8Sopenharmony_ci GetBundleName(appProperty), static_cast<unsigned long>(bundles.size())); 124669570cc8Sopenharmony_ci for (uint32_t i = 0; i < bundles.size(); i++) { 124769570cc8Sopenharmony_ci // elements in json arrary can be different type 124869570cc8Sopenharmony_ci APPSPAWN_CHECK(bundles[i].is_string() && modules[i].is_string() && versions[i].is_string(), 124969570cc8Sopenharmony_ci return -1, "MountAllHsp: element type error"); 125069570cc8Sopenharmony_ci 125169570cc8Sopenharmony_ci std::string libBundleName = bundles[i]; 125269570cc8Sopenharmony_ci std::string libModuleName = modules[i]; 125369570cc8Sopenharmony_ci std::string libVersion = versions[i]; 125469570cc8Sopenharmony_ci APPSPAWN_CHECK(CheckPath(libBundleName) && CheckPath(libModuleName) && CheckPath(libVersion), 125569570cc8Sopenharmony_ci return -1, "MountAllHsp: path error"); 125669570cc8Sopenharmony_ci 125769570cc8Sopenharmony_ci std::string libPhysicalPath = g_physicalAppInstallPath + libBundleName + "/" + libVersion + "/" + libModuleName; 125869570cc8Sopenharmony_ci std::string mntPath = sandboxPackagePath + g_sandboxHspInstallPath + libBundleName + "/" + libModuleName; 125969570cc8Sopenharmony_ci ret = DoAppSandboxMountOnce(libPhysicalPath.c_str(), mntPath.c_str(), "", BASIC_MOUNT_FLAGS, nullptr); 126069570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "mount library failed %{public}d", ret); 126169570cc8Sopenharmony_ci } 126269570cc8Sopenharmony_ci return ret; 126369570cc8Sopenharmony_ci} 126469570cc8Sopenharmony_ci 126569570cc8Sopenharmony_ciint32_t SandboxUtils::DoSandboxRootFolderCreateAdapt(std::string &sandboxPackagePath) 126669570cc8Sopenharmony_ci{ 126769570cc8Sopenharmony_ci#ifndef APPSPAWN_TEST 126869570cc8Sopenharmony_ci int rc = mount(nullptr, "/", nullptr, MS_REC | MS_SLAVE, nullptr); 126969570cc8Sopenharmony_ci APPSPAWN_CHECK(rc == 0, return rc, "set propagation slave failed"); 127069570cc8Sopenharmony_ci#endif 127169570cc8Sopenharmony_ci MakeDirRecursive(sandboxPackagePath, FILE_MODE); 127269570cc8Sopenharmony_ci 127369570cc8Sopenharmony_ci // bind mount "/" to /mnt/sandbox/<currentUserId>/<packageName> path 127469570cc8Sopenharmony_ci // rootfs: to do more resources bind mount here to get more strict resources constraints 127569570cc8Sopenharmony_ci#ifndef APPSPAWN_TEST 127669570cc8Sopenharmony_ci rc = mount("/", sandboxPackagePath.c_str(), nullptr, BASIC_MOUNT_FLAGS, nullptr); 127769570cc8Sopenharmony_ci APPSPAWN_CHECK(rc == 0, return rc, "mount bind / failed, %{public}d", errno); 127869570cc8Sopenharmony_ci#endif 127969570cc8Sopenharmony_ci return 0; 128069570cc8Sopenharmony_ci} 128169570cc8Sopenharmony_ci 128269570cc8Sopenharmony_ciint32_t SandboxUtils::MountAllGroup(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath) 128369570cc8Sopenharmony_ci{ 128469570cc8Sopenharmony_ci int ret = 0; 128569570cc8Sopenharmony_ci string dataGroupInfo = GetExtraInfoByType(appProperty, DATA_GROUP_SOCKET_TYPE); 128669570cc8Sopenharmony_ci if (dataGroupInfo.length() == 0) { 128769570cc8Sopenharmony_ci return ret; 128869570cc8Sopenharmony_ci } 128969570cc8Sopenharmony_ci 129069570cc8Sopenharmony_ci nlohmann::json groups = nlohmann::json::parse(dataGroupInfo.c_str(), nullptr, false); 129169570cc8Sopenharmony_ci APPSPAWN_CHECK(!groups.is_discarded() && groups.contains(g_groupList_key_dataGroupId) 129269570cc8Sopenharmony_ci && groups.contains(g_groupList_key_gid) && groups.contains(g_groupList_key_dir), return -1, 129369570cc8Sopenharmony_ci "MountAllGroup: json parse failed"); 129469570cc8Sopenharmony_ci 129569570cc8Sopenharmony_ci nlohmann::json& dataGroupIds = groups[g_groupList_key_dataGroupId]; 129669570cc8Sopenharmony_ci nlohmann::json& gids = groups[g_groupList_key_gid]; 129769570cc8Sopenharmony_ci nlohmann::json& dirs = groups[g_groupList_key_dir]; 129869570cc8Sopenharmony_ci APPSPAWN_CHECK(dataGroupIds.is_array() && gids.is_array() && dirs.is_array() && dataGroupIds.size() == gids.size() 129969570cc8Sopenharmony_ci && dataGroupIds.size() == dirs.size(), return -1, "MountAllGroup: value is not arrary or sizes are not same"); 130069570cc8Sopenharmony_ci APPSPAWN_LOGI("MountAllGroup: app = %{public}s, cnt = %{public}lu", 130169570cc8Sopenharmony_ci GetBundleName(appProperty), static_cast<unsigned long>(dataGroupIds.size())); 130269570cc8Sopenharmony_ci for (uint32_t i = 0; i < dataGroupIds.size(); i++) { 130369570cc8Sopenharmony_ci // elements in json arrary can be different type 130469570cc8Sopenharmony_ci APPSPAWN_CHECK(dataGroupIds[i].is_string() && gids[i].is_string() && dirs[i].is_string(), 130569570cc8Sopenharmony_ci return -1, "MountAllGroup: element type error"); 130669570cc8Sopenharmony_ci 130769570cc8Sopenharmony_ci std::string libPhysicalPath = dirs[i]; 130869570cc8Sopenharmony_ci APPSPAWN_CHECK(!CheckPath(libPhysicalPath), return -1, "MountAllGroup: path error"); 130969570cc8Sopenharmony_ci 131069570cc8Sopenharmony_ci size_t lastPathSplitPos = libPhysicalPath.find_last_of(g_fileSeparator); 131169570cc8Sopenharmony_ci APPSPAWN_CHECK(lastPathSplitPos != std::string::npos, return -1, "MountAllGroup: path error"); 131269570cc8Sopenharmony_ci 131369570cc8Sopenharmony_ci std::string dataGroupUuid = libPhysicalPath.substr(lastPathSplitPos + 1); 131469570cc8Sopenharmony_ci std::string mntPath = sandboxPackagePath + g_sandboxGroupPath + dataGroupUuid; 131569570cc8Sopenharmony_ci mode_t mountFlags = MS_REC | MS_BIND; 131669570cc8Sopenharmony_ci mode_t mountSharedFlag = MS_SLAVE; 131769570cc8Sopenharmony_ci if (CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX)) { 131869570cc8Sopenharmony_ci mountSharedFlag |= MS_REMOUNT | MS_NODEV | MS_RDONLY | MS_BIND; 131969570cc8Sopenharmony_ci } 132069570cc8Sopenharmony_ci ret = DoAppSandboxMountOnce(libPhysicalPath.c_str(), mntPath.c_str(), "", mountFlags, nullptr, 132169570cc8Sopenharmony_ci mountSharedFlag); 132269570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "mount library failed %{public}d", ret); 132369570cc8Sopenharmony_ci } 132469570cc8Sopenharmony_ci return ret; 132569570cc8Sopenharmony_ci} 132669570cc8Sopenharmony_ci 132769570cc8Sopenharmony_ciint32_t SandboxUtils::DoSandboxRootFolderCreate(const AppSpawningCtx *appProperty, 132869570cc8Sopenharmony_ci std::string &sandboxPackagePath) 132969570cc8Sopenharmony_ci{ 133069570cc8Sopenharmony_ci#ifndef APPSPAWN_TEST 133169570cc8Sopenharmony_ci int rc = mount(nullptr, "/", nullptr, MS_REC | MS_SLAVE, nullptr); 133269570cc8Sopenharmony_ci if (rc) { 133369570cc8Sopenharmony_ci return rc; 133469570cc8Sopenharmony_ci } 133569570cc8Sopenharmony_ci#endif 133669570cc8Sopenharmony_ci DoAppSandboxMountOnce(sandboxPackagePath.c_str(), sandboxPackagePath.c_str(), "", 133769570cc8Sopenharmony_ci BASIC_MOUNT_FLAGS, nullptr); 133869570cc8Sopenharmony_ci 133969570cc8Sopenharmony_ci return 0; 134069570cc8Sopenharmony_ci} 134169570cc8Sopenharmony_ci 134269570cc8Sopenharmony_ciuint32_t SandboxUtils::GetSandboxNsFlags(bool isNweb) 134369570cc8Sopenharmony_ci{ 134469570cc8Sopenharmony_ci uint32_t nsFlags = 0; 134569570cc8Sopenharmony_ci nlohmann::json appConfig; 134669570cc8Sopenharmony_ci const std::map<std::string, uint32_t> NamespaceFlagsMap = { {"pid", CLONE_NEWPID}, 134769570cc8Sopenharmony_ci {"net", CLONE_NEWNET} }; 134869570cc8Sopenharmony_ci 134969570cc8Sopenharmony_ci if (!CheckTotalSandboxSwitchStatus(nullptr)) { 135069570cc8Sopenharmony_ci return nsFlags; 135169570cc8Sopenharmony_ci } 135269570cc8Sopenharmony_ci 135369570cc8Sopenharmony_ci for (auto& config : SandboxUtils::GetJsonConfig(SANBOX_APP_JSON_CONFIG)) { 135469570cc8Sopenharmony_ci if (isNweb) { 135569570cc8Sopenharmony_ci nlohmann::json& privateAppConfig = config[g_privatePrefix][0]; 135669570cc8Sopenharmony_ci if (privateAppConfig.find(g_ohosRender) == privateAppConfig.end()) { 135769570cc8Sopenharmony_ci continue; 135869570cc8Sopenharmony_ci } 135969570cc8Sopenharmony_ci appConfig = privateAppConfig[g_ohosRender][0]; 136069570cc8Sopenharmony_ci } else { 136169570cc8Sopenharmony_ci nlohmann::json& baseConfig = config[g_commonPrefix][0]; 136269570cc8Sopenharmony_ci if (baseConfig.find(g_appBase) == baseConfig.end()) { 136369570cc8Sopenharmony_ci continue; 136469570cc8Sopenharmony_ci } 136569570cc8Sopenharmony_ci appConfig = baseConfig[g_appBase][0]; 136669570cc8Sopenharmony_ci } 136769570cc8Sopenharmony_ci if (appConfig.find(g_sandBoxNsFlags) == appConfig.end()) { 136869570cc8Sopenharmony_ci continue; 136969570cc8Sopenharmony_ci } 137069570cc8Sopenharmony_ci const auto vec = appConfig[g_sandBoxNsFlags].get<std::vector<std::string>>(); 137169570cc8Sopenharmony_ci for (unsigned int j = 0; j < vec.size(); j++) { 137269570cc8Sopenharmony_ci if (NamespaceFlagsMap.count(vec[j])) { 137369570cc8Sopenharmony_ci nsFlags |= NamespaceFlagsMap.at(vec[j]); 137469570cc8Sopenharmony_ci } 137569570cc8Sopenharmony_ci } 137669570cc8Sopenharmony_ci } 137769570cc8Sopenharmony_ci 137869570cc8Sopenharmony_ci if (!nsFlags) { 137969570cc8Sopenharmony_ci APPSPAWN_LOGE("config is not found %{public}s ns config", isNweb ? "Nweb" : "App"); 138069570cc8Sopenharmony_ci } 138169570cc8Sopenharmony_ci return nsFlags; 138269570cc8Sopenharmony_ci} 138369570cc8Sopenharmony_ci 138469570cc8Sopenharmony_cibool SandboxUtils::CheckBundleNameForPrivate(const std::string &bundleName) 138569570cc8Sopenharmony_ci{ 138669570cc8Sopenharmony_ci if (bundleName.find(g_internal) != std::string::npos) { 138769570cc8Sopenharmony_ci return false; 138869570cc8Sopenharmony_ci } 138969570cc8Sopenharmony_ci return true; 139069570cc8Sopenharmony_ci} 139169570cc8Sopenharmony_ci 139269570cc8Sopenharmony_cibool SandboxUtils::CheckTotalSandboxSwitchStatus(const AppSpawningCtx *appProperty) 139369570cc8Sopenharmony_ci{ 139469570cc8Sopenharmony_ci SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? 139569570cc8Sopenharmony_ci SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG; 139669570cc8Sopenharmony_ci 139769570cc8Sopenharmony_ci for (auto& wholeConfig : SandboxUtils::GetJsonConfig(type)) { 139869570cc8Sopenharmony_ci if (wholeConfig.find(g_commonPrefix) == wholeConfig.end()) { 139969570cc8Sopenharmony_ci continue; 140069570cc8Sopenharmony_ci } 140169570cc8Sopenharmony_ci nlohmann::json& commonAppConfig = wholeConfig[g_commonPrefix][0]; 140269570cc8Sopenharmony_ci if (commonAppConfig.find(g_topSandBoxSwitchPrefix) != commonAppConfig.end()) { 140369570cc8Sopenharmony_ci std::string switchStatus = commonAppConfig[g_topSandBoxSwitchPrefix].get<std::string>(); 140469570cc8Sopenharmony_ci return switchStatus == g_sbxSwitchCheck; 140569570cc8Sopenharmony_ci } 140669570cc8Sopenharmony_ci } 140769570cc8Sopenharmony_ci // default sandbox switch is on 140869570cc8Sopenharmony_ci return true; 140969570cc8Sopenharmony_ci} 141069570cc8Sopenharmony_ci 141169570cc8Sopenharmony_cibool SandboxUtils::CheckAppSandboxSwitchStatus(const AppSpawningCtx *appProperty) 141269570cc8Sopenharmony_ci{ 141369570cc8Sopenharmony_ci bool rc = true; 141469570cc8Sopenharmony_ci SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? 141569570cc8Sopenharmony_ci SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG; 141669570cc8Sopenharmony_ci 141769570cc8Sopenharmony_ci for (auto& wholeConfig : SandboxUtils::GetJsonConfig(type)) { 141869570cc8Sopenharmony_ci if (wholeConfig.find(g_privatePrefix) == wholeConfig.end()) { 141969570cc8Sopenharmony_ci continue; 142069570cc8Sopenharmony_ci } 142169570cc8Sopenharmony_ci nlohmann::json& privateAppConfig = wholeConfig[g_privatePrefix][0]; 142269570cc8Sopenharmony_ci if (privateAppConfig.find(GetBundleName(appProperty)) != privateAppConfig.end()) { 142369570cc8Sopenharmony_ci nlohmann::json& appConfig = privateAppConfig[GetBundleName(appProperty)][0]; 142469570cc8Sopenharmony_ci rc = GetSbxSwitchStatusByConfig(appConfig); 142569570cc8Sopenharmony_ci if (rc) { 142669570cc8Sopenharmony_ci break; 142769570cc8Sopenharmony_ci } 142869570cc8Sopenharmony_ci } 142969570cc8Sopenharmony_ci } 143069570cc8Sopenharmony_ci // default sandbox switch is on 143169570cc8Sopenharmony_ci return rc; 143269570cc8Sopenharmony_ci} 143369570cc8Sopenharmony_ci 143469570cc8Sopenharmony_cistatic int CheckBundleName(const std::string &bundleName) 143569570cc8Sopenharmony_ci{ 143669570cc8Sopenharmony_ci if (bundleName.empty() || bundleName.size() > APP_LEN_BUNDLE_NAME) { 143769570cc8Sopenharmony_ci return -1; 143869570cc8Sopenharmony_ci } 143969570cc8Sopenharmony_ci if (bundleName.find('\\') != std::string::npos || bundleName.find('/') != std::string::npos) { 144069570cc8Sopenharmony_ci return -1; 144169570cc8Sopenharmony_ci } 144269570cc8Sopenharmony_ci return 0; 144369570cc8Sopenharmony_ci} 144469570cc8Sopenharmony_ci 144569570cc8Sopenharmony_ciint32_t SandboxUtils::SetOverlayAppSandboxProperty(const AppSpawningCtx *appProperty, 144669570cc8Sopenharmony_ci string &sandboxPackagePath) 144769570cc8Sopenharmony_ci{ 144869570cc8Sopenharmony_ci int ret = 0; 144969570cc8Sopenharmony_ci if (!CheckAppMsgFlagsSet(appProperty, APP_FLAGS_OVERLAY)) { 145069570cc8Sopenharmony_ci return ret; 145169570cc8Sopenharmony_ci } 145269570cc8Sopenharmony_ci 145369570cc8Sopenharmony_ci string overlayInfo = GetExtraInfoByType(appProperty, OVERLAY_SOCKET_TYPE); 145469570cc8Sopenharmony_ci set<string> mountedSrcSet; 145569570cc8Sopenharmony_ci vector<string> splits = split(overlayInfo, g_overlayDecollator); 145669570cc8Sopenharmony_ci string sandboxOverlayPath = sandboxPackagePath + g_overlayPath; 145769570cc8Sopenharmony_ci for (auto hapPath : splits) { 145869570cc8Sopenharmony_ci size_t pathIndex = hapPath.find_last_of(g_fileSeparator); 145969570cc8Sopenharmony_ci if (pathIndex == string::npos) { 146069570cc8Sopenharmony_ci continue; 146169570cc8Sopenharmony_ci } 146269570cc8Sopenharmony_ci std::string srcPath = hapPath.substr(0, pathIndex); 146369570cc8Sopenharmony_ci if (mountedSrcSet.find(srcPath) != mountedSrcSet.end()) { 146469570cc8Sopenharmony_ci APPSPAWN_LOGV("%{public}s have mounted before, no need to mount twice.", srcPath.c_str()); 146569570cc8Sopenharmony_ci continue; 146669570cc8Sopenharmony_ci } 146769570cc8Sopenharmony_ci 146869570cc8Sopenharmony_ci auto bundleNameIndex = srcPath.find_last_of(g_fileSeparator); 146969570cc8Sopenharmony_ci string destPath = sandboxOverlayPath + srcPath.substr(bundleNameIndex + 1, srcPath.length()); 147069570cc8Sopenharmony_ci int32_t retMount = DoAppSandboxMountOnce(srcPath.c_str(), destPath.c_str(), 147169570cc8Sopenharmony_ci nullptr, BASIC_MOUNT_FLAGS, nullptr); 147269570cc8Sopenharmony_ci if (retMount != 0) { 147369570cc8Sopenharmony_ci APPSPAWN_LOGE("fail to mount overlay path, src is %{public}s.", hapPath.c_str()); 147469570cc8Sopenharmony_ci ret = retMount; 147569570cc8Sopenharmony_ci } 147669570cc8Sopenharmony_ci 147769570cc8Sopenharmony_ci mountedSrcSet.emplace(srcPath); 147869570cc8Sopenharmony_ci } 147969570cc8Sopenharmony_ci return ret; 148069570cc8Sopenharmony_ci} 148169570cc8Sopenharmony_ci 148269570cc8Sopenharmony_ciint32_t SandboxUtils::SetBundleResourceAppSandboxProperty(const AppSpawningCtx *appProperty, 148369570cc8Sopenharmony_ci string &sandboxPackagePath) 148469570cc8Sopenharmony_ci{ 148569570cc8Sopenharmony_ci int ret = 0; 148669570cc8Sopenharmony_ci if (!CheckAppMsgFlagsSet(appProperty, APP_FLAGS_BUNDLE_RESOURCES)) { 148769570cc8Sopenharmony_ci return ret; 148869570cc8Sopenharmony_ci } 148969570cc8Sopenharmony_ci 149069570cc8Sopenharmony_ci string srcPath = g_bundleResourceSrcPath; 149169570cc8Sopenharmony_ci string destPath = sandboxPackagePath + g_bundleResourceDestPath; 149269570cc8Sopenharmony_ci ret = DoAppSandboxMountOnce( 149369570cc8Sopenharmony_ci srcPath.c_str(), destPath.c_str(), nullptr, BASIC_MOUNT_FLAGS, nullptr); 149469570cc8Sopenharmony_ci return ret; 149569570cc8Sopenharmony_ci} 149669570cc8Sopenharmony_ci 149769570cc8Sopenharmony_ciint32_t SandboxUtils::CheckAppFullMountEnable() 149869570cc8Sopenharmony_ci{ 149969570cc8Sopenharmony_ci if (deviceTypeEnable_ != -1) { 150069570cc8Sopenharmony_ci return deviceTypeEnable_; 150169570cc8Sopenharmony_ci } 150269570cc8Sopenharmony_ci 150369570cc8Sopenharmony_ci char value[] = "false"; 150469570cc8Sopenharmony_ci int32_t ret = GetParameter("const.filemanager.full_mount.enable", "false", value, sizeof(value)); 150569570cc8Sopenharmony_ci if (ret > 0 && (strcmp(value, "true")) == 0) { 150669570cc8Sopenharmony_ci deviceTypeEnable_ = FILE_CROSS_APP_STATUS; 150769570cc8Sopenharmony_ci } else if (ret > 0 && (strcmp(value, "false")) == 0) { 150869570cc8Sopenharmony_ci deviceTypeEnable_ = FILE_ACCESS_COMMON_DIR_STATUS; 150969570cc8Sopenharmony_ci } else { 151069570cc8Sopenharmony_ci deviceTypeEnable_ = -1; 151169570cc8Sopenharmony_ci } 151269570cc8Sopenharmony_ci 151369570cc8Sopenharmony_ci return deviceTypeEnable_; 151469570cc8Sopenharmony_ci} 151569570cc8Sopenharmony_ci 151669570cc8Sopenharmony_ciint32_t SandboxUtils::SetSandboxProperty(AppSpawningCtx *appProperty, std::string &sandboxPackagePath) 151769570cc8Sopenharmony_ci{ 151869570cc8Sopenharmony_ci int32_t ret = 0; 151969570cc8Sopenharmony_ci const std::string bundleName = GetBundleName(appProperty); 152069570cc8Sopenharmony_ci ret = SetCommonAppSandboxProperty(appProperty, sandboxPackagePath); 152169570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "SetCommonAppSandboxProperty failed, packagename is %{public}s", 152269570cc8Sopenharmony_ci bundleName.c_str()); 152369570cc8Sopenharmony_ci if (CheckBundleNameForPrivate(bundleName)) { 152469570cc8Sopenharmony_ci ret = SetPrivateAppSandboxProperty(appProperty); 152569570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "SetPrivateAppSandboxProperty failed, packagename is %{public}s", 152669570cc8Sopenharmony_ci bundleName.c_str()); 152769570cc8Sopenharmony_ci } 152869570cc8Sopenharmony_ci ret = SetPermissionAppSandboxProperty(appProperty); 152969570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "SetPermissionAppSandboxProperty failed, packagename is %{public}s", 153069570cc8Sopenharmony_ci bundleName.c_str()); 153169570cc8Sopenharmony_ci 153269570cc8Sopenharmony_ci ret = SetOverlayAppSandboxProperty(appProperty, sandboxPackagePath); 153369570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "SetOverlayAppSandboxProperty failed, packagename is %{public}s", 153469570cc8Sopenharmony_ci bundleName.c_str()); 153569570cc8Sopenharmony_ci 153669570cc8Sopenharmony_ci ret = SetBundleResourceAppSandboxProperty(appProperty, sandboxPackagePath); 153769570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "SetBundleResourceAppSandboxProperty failed, packagename is %{public}s", 153869570cc8Sopenharmony_ci bundleName.c_str()); 153969570cc8Sopenharmony_ci APPSPAWN_LOGI("Set appsandbox property success"); 154069570cc8Sopenharmony_ci return ret; 154169570cc8Sopenharmony_ci} 154269570cc8Sopenharmony_ci 154369570cc8Sopenharmony_ciint32_t SandboxUtils::ChangeCurrentDir(std::string &sandboxPackagePath, const std::string &bundleName, 154469570cc8Sopenharmony_ci bool sandboxSharedStatus) 154569570cc8Sopenharmony_ci{ 154669570cc8Sopenharmony_ci int32_t ret = 0; 154769570cc8Sopenharmony_ci ret = chdir(sandboxPackagePath.c_str()); 154869570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "chdir failed, packagename is %{public}s, path is %{public}s", 154969570cc8Sopenharmony_ci bundleName.c_str(), sandboxPackagePath.c_str()); 155069570cc8Sopenharmony_ci 155169570cc8Sopenharmony_ci if (sandboxSharedStatus) { 155269570cc8Sopenharmony_ci ret = chroot(sandboxPackagePath.c_str()); 155369570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "chroot failed, path is %{public}s errno is %{public}d", 155469570cc8Sopenharmony_ci sandboxPackagePath.c_str(), errno); 155569570cc8Sopenharmony_ci return ret; 155669570cc8Sopenharmony_ci } 155769570cc8Sopenharmony_ci 155869570cc8Sopenharmony_ci ret = syscall(SYS_pivot_root, sandboxPackagePath.c_str(), sandboxPackagePath.c_str()); 155969570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "errno is %{public}d, pivot root failed, packagename is %{public}s", 156069570cc8Sopenharmony_ci errno, bundleName.c_str()); 156169570cc8Sopenharmony_ci 156269570cc8Sopenharmony_ci ret = umount2(".", MNT_DETACH); 156369570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "MNT_DETACH failed, packagename is %{public}s", bundleName.c_str()); 156469570cc8Sopenharmony_ci return ret; 156569570cc8Sopenharmony_ci} 156669570cc8Sopenharmony_ci 156769570cc8Sopenharmony_cistatic inline int EnableSandboxNamespace(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags) 156869570cc8Sopenharmony_ci{ 156969570cc8Sopenharmony_ci int rc = unshare(sandboxNsFlags); 157069570cc8Sopenharmony_ci APPSPAWN_CHECK(rc == 0, return rc, "unshare failed, packagename is %{public}s", GetBundleName(appProperty)); 157169570cc8Sopenharmony_ci 157269570cc8Sopenharmony_ci if ((sandboxNsFlags & CLONE_NEWNET) == CLONE_NEWNET) { 157369570cc8Sopenharmony_ci rc = EnableNewNetNamespace(); 157469570cc8Sopenharmony_ci APPSPAWN_CHECK(rc == 0, return rc, "Set new netnamespace failed %{public}s", GetBundleName(appProperty)); 157569570cc8Sopenharmony_ci } 157669570cc8Sopenharmony_ci return 0; 157769570cc8Sopenharmony_ci} 157869570cc8Sopenharmony_ci 157969570cc8Sopenharmony_ciint32_t SandboxUtils::SetPermissionWithParam(AppSpawningCtx *appProperty) 158069570cc8Sopenharmony_ci{ 158169570cc8Sopenharmony_ci int32_t index = 0; 158269570cc8Sopenharmony_ci int32_t appFullMountStatus = CheckAppFullMountEnable(); 158369570cc8Sopenharmony_ci if (appFullMountStatus == FILE_CROSS_APP_STATUS) { 158469570cc8Sopenharmony_ci index = GetPermissionIndex(nullptr, FILE_CROSS_APP_MODE.c_str()); 158569570cc8Sopenharmony_ci } else if (appFullMountStatus == FILE_ACCESS_COMMON_DIR_STATUS) { 158669570cc8Sopenharmony_ci index = GetPermissionIndex(nullptr, FILE_ACCESS_COMMON_DIR_MODE.c_str()); 158769570cc8Sopenharmony_ci } 158869570cc8Sopenharmony_ci 158969570cc8Sopenharmony_ci int32_t fileMgrIndex = GetPermissionIndex(nullptr, FILE_ACCESS_MANAGER_MODE.c_str()); 159069570cc8Sopenharmony_ci if (index > 0 && fileMgrIndex > 0 && 159169570cc8Sopenharmony_ci (CheckAppPermissionFlagSet(appProperty, static_cast<uint32_t>(fileMgrIndex)) == 0)) { 159269570cc8Sopenharmony_ci return SetAppPermissionFlags(appProperty, index); 159369570cc8Sopenharmony_ci } 159469570cc8Sopenharmony_ci return -1; 159569570cc8Sopenharmony_ci} 159669570cc8Sopenharmony_ci 159769570cc8Sopenharmony_ci#ifdef APPSPAWN_MOUNT_TMPSHM 159869570cc8Sopenharmony_civoid SandboxUtils::MountDevShmPath(std::string &sandboxPath) 159969570cc8Sopenharmony_ci{ 160069570cc8Sopenharmony_ci std::string sandboxDevShmPath = sandboxPath + DEV_SHM_DIR; 160169570cc8Sopenharmony_ci int result = mount("tmpfs", sandboxDevShmPath.c_str(), "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV, "size=32M"); 160269570cc8Sopenharmony_ci if (result != 0) { 160369570cc8Sopenharmony_ci APPSPAWN_LOGW("Error mounting %{public}s to tmpfs, errno %{public}d", sandboxDevShmPath.c_str(), errno); 160469570cc8Sopenharmony_ci } 160569570cc8Sopenharmony_ci} 160669570cc8Sopenharmony_ci#endif 160769570cc8Sopenharmony_ci 160869570cc8Sopenharmony_ciint32_t SandboxUtils::SetAppSandboxProperty(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags) 160969570cc8Sopenharmony_ci{ 161069570cc8Sopenharmony_ci APPSPAWN_CHECK(appProperty != nullptr, return -1, "Invalid appspwn client"); 161169570cc8Sopenharmony_ci if (CheckBundleName(GetBundleName(appProperty)) != 0) { 161269570cc8Sopenharmony_ci return -1; 161369570cc8Sopenharmony_ci } 161469570cc8Sopenharmony_ci AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO)); 161569570cc8Sopenharmony_ci if (dacInfo == nullptr) { 161669570cc8Sopenharmony_ci return -1; 161769570cc8Sopenharmony_ci } 161869570cc8Sopenharmony_ci 161969570cc8Sopenharmony_ci std::string sandboxPackagePath = g_sandBoxRootDir + to_string(dacInfo->uid / UID_BASE) + "/"; 162069570cc8Sopenharmony_ci const std::string bundleName = GetBundleName(appProperty); 162169570cc8Sopenharmony_ci bool sandboxSharedStatus = GetSandboxPrivateSharedStatus(bundleName, appProperty) || 162269570cc8Sopenharmony_ci (CheckAppPermissionFlagSet(appProperty, static_cast<uint32_t>(GetPermissionIndex(nullptr, 162369570cc8Sopenharmony_ci ACCESS_DLP_FILE_MODE.c_str()))) != 0); 162469570cc8Sopenharmony_ci sandboxPackagePath += CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? "isolated/" : ""; 162569570cc8Sopenharmony_ci sandboxPackagePath += bundleName; 162669570cc8Sopenharmony_ci MakeDirRecursive(sandboxPackagePath.c_str(), FILE_MODE); 162769570cc8Sopenharmony_ci 162869570cc8Sopenharmony_ci // add pid to a new mnt namespace 162969570cc8Sopenharmony_ci int rc = EnableSandboxNamespace(appProperty, sandboxNsFlags); 163069570cc8Sopenharmony_ci APPSPAWN_CHECK(rc == 0, return rc, "unshare failed, packagename is %{public}s", bundleName.c_str()); 163169570cc8Sopenharmony_ci 163269570cc8Sopenharmony_ci if (SetPermissionWithParam(appProperty) != 0) { 163369570cc8Sopenharmony_ci APPSPAWN_LOGW("Set app permission flag fail."); 163469570cc8Sopenharmony_ci } 163569570cc8Sopenharmony_ci 163669570cc8Sopenharmony_ci // check app sandbox switch 163769570cc8Sopenharmony_ci if ((CheckTotalSandboxSwitchStatus(appProperty) == false) || 163869570cc8Sopenharmony_ci (CheckAppSandboxSwitchStatus(appProperty) == false)) { 163969570cc8Sopenharmony_ci rc = DoSandboxRootFolderCreateAdapt(sandboxPackagePath); 164069570cc8Sopenharmony_ci } else if (!sandboxSharedStatus) { 164169570cc8Sopenharmony_ci rc = DoSandboxRootFolderCreate(appProperty, sandboxPackagePath); 164269570cc8Sopenharmony_ci } 164369570cc8Sopenharmony_ci APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxRootFolderCreate failed, %{public}s", bundleName.c_str()); 164469570cc8Sopenharmony_ci rc = SetSandboxProperty(appProperty, sandboxPackagePath); 164569570cc8Sopenharmony_ci APPSPAWN_CHECK(rc == 0, return rc, "SetSandboxProperty failed, %{public}s", bundleName.c_str()); 164669570cc8Sopenharmony_ci 164769570cc8Sopenharmony_ci#ifdef APPSPAWN_MOUNT_TMPSHM 164869570cc8Sopenharmony_ci MountDevShmPath(sandboxPackagePath); 164969570cc8Sopenharmony_ci#endif 165069570cc8Sopenharmony_ci 165169570cc8Sopenharmony_ci#ifndef APPSPAWN_TEST 165269570cc8Sopenharmony_ci rc = ChangeCurrentDir(sandboxPackagePath, bundleName, sandboxSharedStatus); 165369570cc8Sopenharmony_ci APPSPAWN_CHECK(rc == 0, return rc, "change current dir failed"); 165469570cc8Sopenharmony_ci APPSPAWN_LOGI("Change root dir success"); 165569570cc8Sopenharmony_ci#if defined(APPSPAWN_MOUNT_TMPSHM) && defined(WITH_SELINUX) 165669570cc8Sopenharmony_ci Restorecon(DEV_SHM_DIR); 165769570cc8Sopenharmony_ci#endif // APPSPAWN_MOUNT_TMPSHM && WITH_SELINUX 165869570cc8Sopenharmony_ci#endif // APPSPAWN_TEST 165969570cc8Sopenharmony_ci return 0; 166069570cc8Sopenharmony_ci} 166169570cc8Sopenharmony_ci 166269570cc8Sopenharmony_ciint32_t SandboxUtils::SetAppSandboxPropertyNweb(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags) 166369570cc8Sopenharmony_ci{ 166469570cc8Sopenharmony_ci APPSPAWN_CHECK(appProperty != nullptr, return -1, "Invalid appspwn client"); 166569570cc8Sopenharmony_ci if (CheckBundleName(GetBundleName(appProperty)) != 0) { 166669570cc8Sopenharmony_ci return -1; 166769570cc8Sopenharmony_ci } 166869570cc8Sopenharmony_ci std::string sandboxPackagePath = g_sandBoxRootDirNweb; 166969570cc8Sopenharmony_ci const std::string bundleName = GetBundleName(appProperty); 167069570cc8Sopenharmony_ci bool sandboxSharedStatus = GetSandboxPrivateSharedStatus(bundleName, appProperty); 167169570cc8Sopenharmony_ci sandboxPackagePath += bundleName; 167269570cc8Sopenharmony_ci MakeDirRecursive(sandboxPackagePath.c_str(), FILE_MODE); 167369570cc8Sopenharmony_ci 167469570cc8Sopenharmony_ci // add pid to a new mnt namespace 167569570cc8Sopenharmony_ci int rc = EnableSandboxNamespace(appProperty, sandboxNsFlags); 167669570cc8Sopenharmony_ci APPSPAWN_CHECK(rc == 0, return rc, "unshare failed, packagename is %{public}s", bundleName.c_str()); 167769570cc8Sopenharmony_ci 167869570cc8Sopenharmony_ci // check app sandbox switch 167969570cc8Sopenharmony_ci if ((CheckTotalSandboxSwitchStatus(appProperty) == false) || 168069570cc8Sopenharmony_ci (CheckAppSandboxSwitchStatus(appProperty) == false)) { 168169570cc8Sopenharmony_ci rc = DoSandboxRootFolderCreateAdapt(sandboxPackagePath); 168269570cc8Sopenharmony_ci } else if (!sandboxSharedStatus) { 168369570cc8Sopenharmony_ci rc = DoSandboxRootFolderCreate(appProperty, sandboxPackagePath); 168469570cc8Sopenharmony_ci } 168569570cc8Sopenharmony_ci APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxRootFolderCreate failed, %{public}s", bundleName.c_str()); 168669570cc8Sopenharmony_ci // rendering process can be created by different apps, 168769570cc8Sopenharmony_ci // and the bundle names of these apps are different, 168869570cc8Sopenharmony_ci // so we can't use the method SetPrivateAppSandboxProperty 168969570cc8Sopenharmony_ci // which mount dirs by using bundle name. 169069570cc8Sopenharmony_ci rc = SetRenderSandboxPropertyNweb(appProperty, sandboxPackagePath); 169169570cc8Sopenharmony_ci APPSPAWN_CHECK(rc == 0, return rc, "SetRenderSandboxPropertyNweb failed, packagename is %{public}s", 169269570cc8Sopenharmony_ci sandboxPackagePath.c_str()); 169369570cc8Sopenharmony_ci 169469570cc8Sopenharmony_ci rc = SetOverlayAppSandboxProperty(appProperty, sandboxPackagePath); 169569570cc8Sopenharmony_ci APPSPAWN_CHECK(rc == 0, return rc, "SetOverlayAppSandboxProperty failed, packagename is %{public}s", 169669570cc8Sopenharmony_ci bundleName.c_str()); 169769570cc8Sopenharmony_ci 169869570cc8Sopenharmony_ci rc = SetBundleResourceAppSandboxProperty(appProperty, sandboxPackagePath); 169969570cc8Sopenharmony_ci APPSPAWN_CHECK(rc == 0, return rc, "SetBundleResourceAppSandboxProperty failed, packagename is %{public}s", 170069570cc8Sopenharmony_ci bundleName.c_str()); 170169570cc8Sopenharmony_ci 170269570cc8Sopenharmony_ci#ifndef APPSPAWN_TEST 170369570cc8Sopenharmony_ci rc = chdir(sandboxPackagePath.c_str()); 170469570cc8Sopenharmony_ci APPSPAWN_CHECK(rc == 0, return rc, "chdir failed, packagename is %{public}s, path is %{public}s", 170569570cc8Sopenharmony_ci bundleName.c_str(), sandboxPackagePath.c_str()); 170669570cc8Sopenharmony_ci 170769570cc8Sopenharmony_ci if (sandboxSharedStatus) { 170869570cc8Sopenharmony_ci rc = chroot(sandboxPackagePath.c_str()); 170969570cc8Sopenharmony_ci APPSPAWN_CHECK(rc == 0, return rc, "chroot failed, path is %{public}s errno is %{public}d", 171069570cc8Sopenharmony_ci sandboxPackagePath.c_str(), errno); 171169570cc8Sopenharmony_ci return 0; 171269570cc8Sopenharmony_ci } 171369570cc8Sopenharmony_ci 171469570cc8Sopenharmony_ci rc = syscall(SYS_pivot_root, sandboxPackagePath.c_str(), sandboxPackagePath.c_str()); 171569570cc8Sopenharmony_ci APPSPAWN_CHECK(rc == 0, return rc, "errno is %{public}d, pivot root failed, packagename is %{public}s", 171669570cc8Sopenharmony_ci errno, bundleName.c_str()); 171769570cc8Sopenharmony_ci 171869570cc8Sopenharmony_ci rc = umount2(".", MNT_DETACH); 171969570cc8Sopenharmony_ci APPSPAWN_CHECK(rc == 0, return rc, "MNT_DETACH failed, packagename is %{public}s", bundleName.c_str()); 172069570cc8Sopenharmony_ci#endif 172169570cc8Sopenharmony_ci return 0; 172269570cc8Sopenharmony_ci} 172369570cc8Sopenharmony_ci} // namespace AppSpawn 172469570cc8Sopenharmony_ci} // namespace OHOS 172569570cc8Sopenharmony_ci 172669570cc8Sopenharmony_cistatic bool AppSandboxPidNsIsSupport(void) 172769570cc8Sopenharmony_ci{ 172869570cc8Sopenharmony_ci char buffer[10] = {0}; 172969570cc8Sopenharmony_ci uint32_t buffSize = sizeof(buffer); 173069570cc8Sopenharmony_ci 173169570cc8Sopenharmony_ci if (SystemGetParameter("const.sandbox.pidns.support", buffer, &buffSize) != 0) { 173269570cc8Sopenharmony_ci return true; 173369570cc8Sopenharmony_ci } 173469570cc8Sopenharmony_ci if (!strcmp(buffer, "false")) { 173569570cc8Sopenharmony_ci return false; 173669570cc8Sopenharmony_ci } 173769570cc8Sopenharmony_ci return true; 173869570cc8Sopenharmony_ci} 173969570cc8Sopenharmony_ci 174069570cc8Sopenharmony_ciint LoadAppSandboxConfig(AppSpawnMgr *content) 174169570cc8Sopenharmony_ci{ 174269570cc8Sopenharmony_ci bool rc = true; 174369570cc8Sopenharmony_ci // load sandbox config 174469570cc8Sopenharmony_ci nlohmann::json appSandboxConfig; 174569570cc8Sopenharmony_ci CfgFiles *files = GetCfgFiles("etc/sandbox"); 174669570cc8Sopenharmony_ci for (int i = 0; (files != nullptr) && (i < MAX_CFG_POLICY_DIRS_CNT); ++i) { 174769570cc8Sopenharmony_ci if (files->paths[i] == nullptr) { 174869570cc8Sopenharmony_ci continue; 174969570cc8Sopenharmony_ci } 175069570cc8Sopenharmony_ci std::string path = files->paths[i]; 175169570cc8Sopenharmony_ci std::string appPath = path + OHOS::AppSpawn::APP_JSON_CONFIG; 175269570cc8Sopenharmony_ci APPSPAWN_LOGI("LoadAppSandboxConfig %{public}s", appPath.c_str()); 175369570cc8Sopenharmony_ci rc = OHOS::AppSpawn::JsonUtils::GetJsonObjFromJson(appSandboxConfig, appPath); 175469570cc8Sopenharmony_ci APPSPAWN_CHECK(rc, continue, "Failed to load app data sandbox config %{public}s", appPath.c_str()); 175569570cc8Sopenharmony_ci OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(appSandboxConfig, SANBOX_APP_JSON_CONFIG); 175669570cc8Sopenharmony_ci 175769570cc8Sopenharmony_ci std::string isolatedPath = path + OHOS::AppSpawn::APP_ISOLATED_JSON_CONFIG; 175869570cc8Sopenharmony_ci APPSPAWN_LOGI("LoadAppSandboxConfig %{public}s", isolatedPath.c_str()); 175969570cc8Sopenharmony_ci rc = OHOS::AppSpawn::JsonUtils::GetJsonObjFromJson(appSandboxConfig, isolatedPath); 176069570cc8Sopenharmony_ci APPSPAWN_CHECK(rc, continue, "Failed to load app data sandbox config %{public}s", isolatedPath.c_str()); 176169570cc8Sopenharmony_ci OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(appSandboxConfig, SANBOX_ISOLATED_JSON_CONFIG); 176269570cc8Sopenharmony_ci } 176369570cc8Sopenharmony_ci FreeCfgFiles(files); 176469570cc8Sopenharmony_ci bool isNweb = IsNWebSpawnMode(content); 176569570cc8Sopenharmony_ci if (!isNweb && !AppSandboxPidNsIsSupport()) { 176669570cc8Sopenharmony_ci return 0; 176769570cc8Sopenharmony_ci } 176869570cc8Sopenharmony_ci content->content.sandboxNsFlags = OHOS::AppSpawn::SandboxUtils::GetSandboxNsFlags(isNweb); 176969570cc8Sopenharmony_ci return 0; 177069570cc8Sopenharmony_ci} 177169570cc8Sopenharmony_ci 177269570cc8Sopenharmony_ciint32_t SetAppSandboxProperty(AppSpawnMgr *content, AppSpawningCtx *property) 177369570cc8Sopenharmony_ci{ 177469570cc8Sopenharmony_ci APPSPAWN_CHECK(property != nullptr, return -1, "Invalid appspwn client"); 177569570cc8Sopenharmony_ci APPSPAWN_CHECK(content != nullptr, return -1, "Invalid appspwn content"); 177669570cc8Sopenharmony_ci int ret = 0; 177769570cc8Sopenharmony_ci // no sandbox 177869570cc8Sopenharmony_ci if (CheckAppMsgFlagsSet(property, APP_FLAGS_NO_SANDBOX)) { 177969570cc8Sopenharmony_ci return 0; 178069570cc8Sopenharmony_ci } 178169570cc8Sopenharmony_ci if ((content->content.sandboxNsFlags & CLONE_NEWPID) == CLONE_NEWPID) { 178269570cc8Sopenharmony_ci ret = getprocpid(); 178369570cc8Sopenharmony_ci if (ret < 0) { 178469570cc8Sopenharmony_ci return ret; 178569570cc8Sopenharmony_ci } 178669570cc8Sopenharmony_ci } 178769570cc8Sopenharmony_ci uint32_t sandboxNsFlags = CLONE_NEWNS; 178869570cc8Sopenharmony_ci if ((CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX) && !IsDeveloperModeOpen()) || 178969570cc8Sopenharmony_ci CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_NETWORK)) { 179069570cc8Sopenharmony_ci sandboxNsFlags |= content->content.sandboxNsFlags & CLONE_NEWNET ? CLONE_NEWNET : 0; 179169570cc8Sopenharmony_ci } 179269570cc8Sopenharmony_ci APPSPAWN_LOGV("SetAppSandboxProperty sandboxNsFlags 0x%{public}x", sandboxNsFlags); 179369570cc8Sopenharmony_ci 179469570cc8Sopenharmony_ci if (IsNWebSpawnMode(content)) { 179569570cc8Sopenharmony_ci ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxPropertyNweb(property, sandboxNsFlags); 179669570cc8Sopenharmony_ci } else { 179769570cc8Sopenharmony_ci ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(property, sandboxNsFlags); 179869570cc8Sopenharmony_ci } 179969570cc8Sopenharmony_ci // for module test do not create sandbox, use APP_FLAGS_IGNORE_SANDBOX to ignore sandbox result 180069570cc8Sopenharmony_ci if (CheckAppMsgFlagsSet(property, APP_FLAGS_IGNORE_SANDBOX)) { 180169570cc8Sopenharmony_ci APPSPAWN_LOGW("Do not care sandbox result %{public}d", ret); 180269570cc8Sopenharmony_ci return 0; 180369570cc8Sopenharmony_ci } 180469570cc8Sopenharmony_ci return ret; 180569570cc8Sopenharmony_ci} 180669570cc8Sopenharmony_ci 180769570cc8Sopenharmony_ci#define USER_ID_SIZE 16 180869570cc8Sopenharmony_ci#define DIR_MODE 0711 180969570cc8Sopenharmony_ci 181069570cc8Sopenharmony_ci#ifndef APPSPAWN_SANDBOX_NEW 181169570cc8Sopenharmony_cistatic bool IsUnlockStatus(uint32_t uid, const char *bundleName, size_t bundleNameLen) 181269570cc8Sopenharmony_ci{ 181369570cc8Sopenharmony_ci const int userIdBase = 200000; 181469570cc8Sopenharmony_ci uid = uid / userIdBase; 181569570cc8Sopenharmony_ci if (uid == 0) { 181669570cc8Sopenharmony_ci return true; 181769570cc8Sopenharmony_ci } 181869570cc8Sopenharmony_ci 181969570cc8Sopenharmony_ci const char rootPath[] = "/data/app/el2/"; 182069570cc8Sopenharmony_ci const char basePath[] = "/base/"; 182169570cc8Sopenharmony_ci size_t allPathSize = strlen(rootPath) + strlen(basePath) + 1 + USER_ID_SIZE + bundleNameLen; 182269570cc8Sopenharmony_ci char *path = reinterpret_cast<char *>(malloc(sizeof(char) * allPathSize)); 182369570cc8Sopenharmony_ci APPSPAWN_CHECK(path != NULL, return true, "Failed to malloc path"); 182469570cc8Sopenharmony_ci int len = sprintf_s(path, allPathSize, "%s%u%s%s", rootPath, uid, basePath, bundleName); 182569570cc8Sopenharmony_ci APPSPAWN_CHECK(len > 0 && ((size_t)len < allPathSize), free(path); 182669570cc8Sopenharmony_ci return true, "Failed to get base path"); 182769570cc8Sopenharmony_ci 182869570cc8Sopenharmony_ci if (access(path, F_OK) == 0) { 182969570cc8Sopenharmony_ci APPSPAWN_LOGI("this is unlock status"); 183069570cc8Sopenharmony_ci free(path); 183169570cc8Sopenharmony_ci return true; 183269570cc8Sopenharmony_ci } 183369570cc8Sopenharmony_ci free(path); 183469570cc8Sopenharmony_ci APPSPAWN_LOGI("this is lock status"); 183569570cc8Sopenharmony_ci return false; 183669570cc8Sopenharmony_ci} 183769570cc8Sopenharmony_ci 183869570cc8Sopenharmony_cistatic void MountDir(const AppSpawningCtx *property, const char *rootPath, const char *srcPath, const char *targetPath) 183969570cc8Sopenharmony_ci{ 184069570cc8Sopenharmony_ci const int userIdBase = 200000; 184169570cc8Sopenharmony_ci AppDacInfo *info = reinterpret_cast<AppDacInfo *>(GetAppProperty(property, TLV_DAC_INFO)); 184269570cc8Sopenharmony_ci const char *bundleName = GetBundleName(property); 184369570cc8Sopenharmony_ci if (info == NULL || bundleName == NULL) { 184469570cc8Sopenharmony_ci return; 184569570cc8Sopenharmony_ci } 184669570cc8Sopenharmony_ci 184769570cc8Sopenharmony_ci size_t allPathSize = strlen(rootPath) + strlen(targetPath) + strlen(bundleName) + 2; 184869570cc8Sopenharmony_ci allPathSize += USER_ID_SIZE; 184969570cc8Sopenharmony_ci char *path = reinterpret_cast<char *>(malloc(sizeof(char) * (allPathSize))); 185069570cc8Sopenharmony_ci APPSPAWN_CHECK(path != NULL, return, "Failed to malloc path"); 185169570cc8Sopenharmony_ci int len = sprintf_s(path, allPathSize, "%s%u/%s%s", rootPath, info->uid / userIdBase, bundleName, targetPath); 185269570cc8Sopenharmony_ci APPSPAWN_CHECK(len > 0 && ((size_t)len < allPathSize), free(path); 185369570cc8Sopenharmony_ci return, "Failed to get sandbox path"); 185469570cc8Sopenharmony_ci 185569570cc8Sopenharmony_ci if (access(path, F_OK) == 0 && srcPath == nullptr) { 185669570cc8Sopenharmony_ci free(path); 185769570cc8Sopenharmony_ci return; 185869570cc8Sopenharmony_ci } 185969570cc8Sopenharmony_ci 186069570cc8Sopenharmony_ci MakeDirRec(path, DIR_MODE, 1); 186169570cc8Sopenharmony_ci const char *sourcePath = (srcPath == nullptr) ? path : srcPath; 186269570cc8Sopenharmony_ci if (srcPath != nullptr) { 186369570cc8Sopenharmony_ci int ret = umount2(path, MNT_DETACH); 186469570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_LOG(ret == 0, "Failed to umount path %{public}s, errno %{public}d", path, errno); 186569570cc8Sopenharmony_ci } 186669570cc8Sopenharmony_ci 186769570cc8Sopenharmony_ci if (mount(sourcePath, path, nullptr, MS_BIND | MS_REC, nullptr) != 0) { 186869570cc8Sopenharmony_ci APPSPAWN_LOGI("bind mount %{public}s to %{public}s failed, error %{public}d", sourcePath, path, errno); 186969570cc8Sopenharmony_ci free(path); 187069570cc8Sopenharmony_ci return; 187169570cc8Sopenharmony_ci } 187269570cc8Sopenharmony_ci if (mount(nullptr, path, nullptr, MS_SHARED, nullptr) != 0) { 187369570cc8Sopenharmony_ci APPSPAWN_LOGI("mount path %{public}s to shared failed, errno %{public}d", path, errno); 187469570cc8Sopenharmony_ci free(path); 187569570cc8Sopenharmony_ci return; 187669570cc8Sopenharmony_ci } 187769570cc8Sopenharmony_ci APPSPAWN_LOGI("mount path %{public}s to shared success", path); 187869570cc8Sopenharmony_ci free(path); 187969570cc8Sopenharmony_ci return; 188069570cc8Sopenharmony_ci} 188169570cc8Sopenharmony_ci 188269570cc8Sopenharmony_cistatic const MountSharedTemplate MOUNT_SHARED_MAP[] = { 188369570cc8Sopenharmony_ci {"/data/storage/el2", nullptr}, 188469570cc8Sopenharmony_ci {"/data/storage/el3", nullptr}, 188569570cc8Sopenharmony_ci {"/data/storage/el4", nullptr}, 188669570cc8Sopenharmony_ci {"/data/storage/el5", "ohos.permission.PROTECT_SCREEN_LOCK_DATA"}, 188769570cc8Sopenharmony_ci {"/storage/Users", "ohos.permission.FILE_ACCESS_MANAGER"}, 188869570cc8Sopenharmony_ci}; 188969570cc8Sopenharmony_ci 189069570cc8Sopenharmony_cistatic void MountDirToShared(const AppSpawningCtx *property) 189169570cc8Sopenharmony_ci{ 189269570cc8Sopenharmony_ci const char rootPath[] = "/mnt/sandbox/"; 189369570cc8Sopenharmony_ci const char el1Path[] = "/data/storage/el1/bundle"; 189469570cc8Sopenharmony_ci const char lockSuffix[] = "_locked"; 189569570cc8Sopenharmony_ci AppDacInfo *info = reinterpret_cast<AppDacInfo *>(GetAppProperty(property, TLV_DAC_INFO)); 189669570cc8Sopenharmony_ci const char *bundleName = GetBundleName(property); 189769570cc8Sopenharmony_ci if (info == NULL || bundleName == NULL) { 189869570cc8Sopenharmony_ci return; 189969570cc8Sopenharmony_ci } 190069570cc8Sopenharmony_ci 190169570cc8Sopenharmony_ci string sourcePath = "/data/app/el1/bundle/public/" + string(bundleName); 190269570cc8Sopenharmony_ci MountDir(property, rootPath, sourcePath.c_str(), el1Path); 190369570cc8Sopenharmony_ci size_t bundleNameLen = strlen(bundleName); 190469570cc8Sopenharmony_ci if (IsUnlockStatus(info->uid, bundleName, bundleNameLen)) { 190569570cc8Sopenharmony_ci return; 190669570cc8Sopenharmony_ci } 190769570cc8Sopenharmony_ci 190869570cc8Sopenharmony_ci int length = sizeof(MOUNT_SHARED_MAP) / sizeof(MOUNT_SHARED_MAP[0]); 190969570cc8Sopenharmony_ci for (int i = 0; i < length; i++) { 191069570cc8Sopenharmony_ci if (MOUNT_SHARED_MAP[i].permission == nullptr) { 191169570cc8Sopenharmony_ci MountDir(property, rootPath, nullptr, MOUNT_SHARED_MAP[i].sandboxPath); 191269570cc8Sopenharmony_ci } else { 191369570cc8Sopenharmony_ci int index = GetPermissionIndex(nullptr, MOUNT_SHARED_MAP[i].permission); 191469570cc8Sopenharmony_ci APPSPAWN_LOGV("mount dir on lock mountPermissionFlags %{public}d", index); 191569570cc8Sopenharmony_ci if (CheckAppPermissionFlagSet(property, static_cast<uint32_t>(index))) { 191669570cc8Sopenharmony_ci MountDir(property, rootPath, nullptr, MOUNT_SHARED_MAP[i].sandboxPath); 191769570cc8Sopenharmony_ci } 191869570cc8Sopenharmony_ci } 191969570cc8Sopenharmony_ci } 192069570cc8Sopenharmony_ci 192169570cc8Sopenharmony_ci std::string lockSbxPathStamp = rootPath + to_string(info->uid / UID_BASE) + "/"; 192269570cc8Sopenharmony_ci lockSbxPathStamp += CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? "isolated/" : ""; 192369570cc8Sopenharmony_ci lockSbxPathStamp += bundleName; 192469570cc8Sopenharmony_ci lockSbxPathStamp += lockSuffix; 192569570cc8Sopenharmony_ci OHOS::AppSpawn::MakeDirRecursive(lockSbxPathStamp.c_str(), OHOS::AppSpawn::FILE_MODE); 192669570cc8Sopenharmony_ci} 192769570cc8Sopenharmony_ci#endif 192869570cc8Sopenharmony_ci 192969570cc8Sopenharmony_cistatic int SpawnMountDirToShared(AppSpawnMgr *content, AppSpawningCtx *property) 193069570cc8Sopenharmony_ci{ 193169570cc8Sopenharmony_ci#ifndef APPSPAWN_SANDBOX_NEW 193269570cc8Sopenharmony_ci // mount dynamic directory 193369570cc8Sopenharmony_ci MountDirToShared(property); 193469570cc8Sopenharmony_ci#endif 193569570cc8Sopenharmony_ci return 0; 193669570cc8Sopenharmony_ci} 193769570cc8Sopenharmony_ci 193869570cc8Sopenharmony_ci#ifndef APPSPAWN_SANDBOX_NEW 193969570cc8Sopenharmony_ciMODULE_CONSTRUCTOR(void) 194069570cc8Sopenharmony_ci{ 194169570cc8Sopenharmony_ci APPSPAWN_LOGV("Load sandbox module ..."); 194269570cc8Sopenharmony_ci (void)AddServerStageHook(STAGE_SERVER_PRELOAD, HOOK_PRIO_SANDBOX, LoadAppSandboxConfig); 194369570cc8Sopenharmony_ci (void)AddAppSpawnHook(STAGE_PARENT_PRE_FORK, HOOK_PRIO_COMMON, SpawnMountDirToShared); 194469570cc8Sopenharmony_ci (void)AddAppSpawnHook(STAGE_CHILD_EXECUTE, HOOK_PRIO_SANDBOX, SetAppSandboxProperty); 194569570cc8Sopenharmony_ci} 194669570cc8Sopenharmony_ci#endif 1947