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 &section,
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 &section, 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 &section)
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 &section)
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