1/*
2 * Copyright (C) 2022-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "sandbox_utils.h"
17
18#include <cerrno>
19#include <cstddef>
20#include <fcntl.h>
21#include <fstream>
22#include <sstream>
23#include <cerrno>
24#include <vector>
25#include <unistd.h>
26#include <sys/mount.h>
27#include <sys/stat.h>
28#include <sys/syscall.h>
29#include <sys/types.h>
30
31#include "appspawn_hook.h"
32#include "appspawn_mount_permission.h"
33#include "appspawn_msg.h"
34#include "appspawn_server.h"
35#include "appspawn_service.h"
36#include "appspawn_utils.h"
37#include "config_policy_utils.h"
38#ifdef WITH_DLP
39#include "dlp_fuse_fd.h"
40#endif
41#include "init_param.h"
42#include "parameter.h"
43#include "parameters.h"
44#include "securec.h"
45
46#ifdef WITH_SELINUX
47#include "hap_restorecon.h"
48#ifdef APPSPAWN_MOUNT_TMPSHM
49#include "policycoreutils.h"
50#endif // APPSPAWN_MOUNT_TMPSHM
51#endif // WITH_SELINUX
52
53#define MAX_MOUNT_TIME 500  // 500us
54#define DEV_SHM_DIR "/dev/shm/"
55
56using namespace std;
57using namespace OHOS;
58
59namespace OHOS {
60namespace AppSpawn {
61namespace {
62    constexpr int32_t OPTIONS_MAX_LEN = 256;
63    constexpr int32_t APP_LOG_DIR_GID = 1007;
64    constexpr int32_t APP_DATABASE_DIR_GID = 3012;
65    constexpr int32_t FILE_ACCESS_COMMON_DIR_STATUS = 0;
66    constexpr int32_t FILE_CROSS_APP_STATUS = 1;
67    constexpr static mode_t FILE_MODE = 0711;
68    constexpr static mode_t BASIC_MOUNT_FLAGS = MS_REC | MS_BIND;
69    constexpr std::string_view APL_SYSTEM_CORE("system_core");
70    constexpr std::string_view APL_SYSTEM_BASIC("system_basic");
71    const std::string APP_JSON_CONFIG("/appdata-sandbox.json");
72    const std::string APP_ISOLATED_JSON_CONFIG("/appdata-sandbox-isolated.json");
73    const std::string g_physicalAppInstallPath = "/data/app/el1/bundle/public/";
74    const std::string g_sandboxGroupPath = "/data/storage/el2/group/";
75    const std::string g_sandboxHspInstallPath = "/data/storage/el1/bundle/";
76    const std::string g_sandBoxAppInstallPath = "/data/accounts/account_0/applications/";
77    const std::string g_bundleResourceSrcPath = "/data/service/el1/public/bms/bundle_resources/";
78    const std::string g_bundleResourceDestPath = "/data/storage/bundle_resources/";
79    const std::string g_dataBundles = "/data/bundles/";
80    const std::string g_userId = "<currentUserId>";
81    const std::string g_packageName = "<PackageName>";
82    const std::string g_packageNameIndex = "<PackageName_index>";
83    const std::string g_variablePackageName = "<variablePackageName>";
84    const std::string g_arkWebPackageName = "<arkWebPackageName>";
85    const std::string g_sandBoxDir = "/mnt/sandbox/";
86    const std::string g_statusCheck = "true";
87    const std::string g_sbxSwitchCheck = "ON";
88    const std::string g_dlpBundleName = "com.ohos.dlpmanager";
89    const std::string g_internal = "__internal__";
90    const std::string g_hspList_key_bundles = "bundles";
91    const std::string g_hspList_key_modules = "modules";
92    const std::string g_hspList_key_versions = "versions";
93    const std::string g_overlayPath = "/data/storage/overlay/";
94    const std::string g_groupList_key_dataGroupId = "dataGroupId";
95    const std::string g_groupList_key_gid = "gid";
96    const std::string g_groupList_key_dir = "dir";
97    const std::string HSPLIST_SOCKET_TYPE = "HspList";
98    const std::string OVERLAY_SOCKET_TYPE = "Overlay";
99    const std::string DATA_GROUP_SOCKET_TYPE = "DataGroup";
100    const char *g_actionStatuc = "check-action-status";
101    const char *g_appBase = "app-base";
102    const char *g_appResources = "app-resources";
103    const char *g_appAplName = "app-apl-name";
104    const char *g_commonPrefix = "common";
105    const char *g_destMode = "dest-mode";
106    const char *g_fsType = "fs-type";
107    const char *g_linkName = "link-name";
108    const char *g_mountPrefix = "mount-paths";
109    const char *g_gidPrefix = "gids";
110    const char *g_privatePrefix = "individual";
111    const char *g_permissionPrefix = "permission";
112    const char *g_srcPath = "src-path";
113    const char *g_sandBoxPath = "sandbox-path";
114    const char *g_sandBoxFlags = "sandbox-flags";
115    const char *g_sandBoxFlagsCustomized = "sandbox-flags-customized";
116    const char *g_sandBoxOptions = "options";
117    const char *g_dacOverrideSensitive = "dac-override-sensitive";
118    const char *g_sandBoxShared = "sandbox-shared";
119    const char *g_sandBoxSwitchPrefix = "sandbox-switch";
120    const char *g_symlinkPrefix = "symbol-links";
121    const char *g_sandboxRootPrefix = "sandbox-root";
122    const char *g_topSandBoxSwitchPrefix = "top-sandbox-switch";
123    const char *g_targetName = "target-name";
124    const char *g_flagePoint = "flags-point";
125    const char *g_mountSharedFlag = "mount-shared-flag";
126    const char *g_flags = "flags";
127    const char *g_sandBoxNsFlags = "sandbox-ns-flags";
128    const char* g_fileSeparator = "/";
129    const char* g_overlayDecollator = "|";
130    const std::string g_sandBoxRootDir = "/mnt/sandbox/";
131    const std::string g_ohosRender = "__internal__.com.ohos.render";
132    const std::string g_sandBoxRootDirNweb = "/mnt/sandbox/com.ohos.render/";
133    const std::string FILE_CROSS_APP_MODE = "ohos.permission.FILE_CROSS_APP";
134    const std::string FILE_ACCESS_COMMON_DIR_MODE = "ohos.permission.FILE_ACCESS_COMMON_DIR";
135    const std::string ACCESS_DLP_FILE_MODE = "ohos.permission.ACCESS_DLP_FILE";
136    const std::string FILE_ACCESS_MANAGER_MODE = "ohos.permission.FILE_ACCESS_MANAGER";
137    const std::string ARK_WEB_PERSIST_PACKAGE_NAME = "persist.arkwebcore.package_name";
138
139    const std::string& getArkWebPackageName()
140    {
141        static std::string arkWebPackageName;
142        if (arkWebPackageName.empty()) {
143            arkWebPackageName = system::GetParameter(ARK_WEB_PERSIST_PACKAGE_NAME, "");
144        }
145        return arkWebPackageName;
146    }
147}
148
149static uint32_t GetAppMsgFlags(const AppSpawningCtx *property)
150{
151    APPSPAWN_CHECK(property != nullptr && property->message != nullptr,
152        return 0, "Invalid property for name %{public}u", TLV_MSG_FLAGS);
153    AppSpawnMsgFlags *msgFlags = (AppSpawnMsgFlags *)GetAppSpawnMsgInfo(property->message, TLV_MSG_FLAGS);
154    APPSPAWN_CHECK(msgFlags != nullptr,
155        return 0, "No TLV_MSG_FLAGS in msg %{public}s", property->message->msgHeader.processName);
156    return msgFlags->flags[0];
157}
158
159bool JsonUtils::GetJsonObjFromJson(nlohmann::json &jsonObj, const std::string &jsonPath)
160{
161    APPSPAWN_CHECK(jsonPath.length() <= PATH_MAX, return false, "jsonPath is too long");
162    std::ifstream jsonFileStream;
163    jsonFileStream.open(jsonPath.c_str(), std::ios::in);
164    APPSPAWN_CHECK_ONLY_EXPER(jsonFileStream.is_open(), return false);
165    std::ostringstream buf;
166    char ch;
167    while (buf && jsonFileStream.get(ch)) {
168        buf.put(ch);
169    }
170    jsonFileStream.close();
171    jsonObj = nlohmann::json::parse(buf.str(), nullptr, false);
172    APPSPAWN_CHECK(!jsonObj.is_discarded() && jsonObj.is_structured(), return false, "Parse json file failed");
173    return true;
174}
175
176bool JsonUtils::GetStringFromJson(const nlohmann::json &json, const std::string &key, std::string &value)
177{
178    APPSPAWN_CHECK(json != nullptr && json.is_object(), return false, "json is not object.");
179    bool isRet = json.find(key) != json.end() && json.at(key).is_string();
180    if (isRet) {
181        value = json.at(key).get<std::string>();
182        APPSPAWN_LOGV("Find key[%{public}s] : %{public}s successful.", key.c_str(), value.c_str());
183    }
184    return isRet;
185}
186
187std::map<SandboxConfigType, std::vector<nlohmann::json>> SandboxUtils::appSandboxConfig_ = {};
188int32_t SandboxUtils::deviceTypeEnable_ = -1;
189
190void SandboxUtils::StoreJsonConfig(nlohmann::json &appSandboxConfig, SandboxConfigType type)
191{
192    SandboxUtils::appSandboxConfig_[type].push_back(appSandboxConfig);
193}
194
195std::vector<nlohmann::json> &SandboxUtils::GetJsonConfig(SandboxConfigType type)
196{
197    return SandboxUtils::appSandboxConfig_[type];
198}
199
200static void MakeDirRecursive(const std::string &path, mode_t mode)
201{
202    size_t size = path.size();
203    if (size == 0) {
204        return;
205    }
206
207    size_t index = 0;
208    do {
209        size_t pathIndex = path.find_first_of('/', index);
210        index = pathIndex == std::string::npos ? size : pathIndex + 1;
211        std::string dir = path.substr(0, index);
212#ifndef APPSPAWN_TEST
213        APPSPAWN_CHECK(!(access(dir.c_str(), F_OK) < 0 && mkdir(dir.c_str(), mode) < 0),
214            return, "errno is %{public}d, mkdir %{public}s failed", errno, dir.c_str());
215#endif
216    } while (index < size);
217}
218
219static bool CheckDirRecursive(const std::string &path)
220{
221    size_t size = path.size();
222    if (size == 0) {
223        return false;
224    }
225    size_t index = 0;
226    do {
227        size_t pathIndex = path.find_first_of('/', index);
228        index = pathIndex == std::string::npos ? size : pathIndex + 1;
229        std::string dir = path.substr(0, index);
230#ifndef APPSPAWN_TEST
231        APPSPAWN_CHECK(access(dir.c_str(), F_OK) == 0,
232            return false, "check dir %{public}s failed, strerror: %{public}s", dir.c_str(), strerror(errno));
233#endif
234    } while (index < size);
235    return true;
236}
237
238static void CheckAndCreatFile(const char *file)
239{
240    if (access(file, F_OK) == 0) {
241        APPSPAWN_LOGI("file %{public}s already exist", file);
242        return;
243    }
244    std::string path = file;
245    auto pos = path.find_last_of('/');
246    APPSPAWN_CHECK(pos != std::string::npos, return, "file %{public}s error", file);
247    std::string dir = path.substr(0, pos);
248    MakeDirRecursive(dir, FILE_MODE);
249    int fd = open(file, O_CREAT, FILE_MODE);
250    if (fd < 0) {
251        APPSPAWN_LOGW("failed create %{public}s, err=%{public}d", file, errno);
252    } else {
253        close(fd);
254    }
255    return;
256}
257
258int32_t SandboxUtils::DoAppSandboxMountOnce(const char *originPath, const char *destinationPath,
259                                            const char *fsType, unsigned long mountFlags,
260                                            const char *options, mode_t mountSharedFlag)
261{
262    if (originPath != nullptr && strstr(originPath, "system/etc/hosts") != nullptr) {
263        CheckAndCreatFile(destinationPath);
264    } else {
265        MakeDirRecursive(destinationPath, FILE_MODE);
266    }
267
268    int ret = 0;
269    // to mount fs and bind mount files or directory
270    struct timespec mountStart = {0};
271    clock_gettime(CLOCK_MONOTONIC, &mountStart);
272    APPSPAWN_LOGV("Bind mount %{public}s to %{public}s '%{public}s' '%{public}lu' '%{public}s' '%{public}u'",
273        originPath, destinationPath, fsType, mountFlags, options, mountSharedFlag);
274    ret = mount(originPath, destinationPath, fsType, mountFlags, options);
275    struct timespec mountEnd = {0};
276    clock_gettime(CLOCK_MONOTONIC, &mountEnd);
277    uint64_t diff = DiffTime(&mountStart, &mountEnd);
278    APPSPAWN_CHECK_ONLY_LOG(diff < MAX_MOUNT_TIME, "mount %{public}s time %{public}" PRId64 " us", originPath, diff);
279    if (ret != 0) {
280        APPSPAWN_LOGI("errno is: %{public}d, bind mount %{public}s to %{public}s", errno, originPath, destinationPath);
281        std::string originPathStr = originPath == nullptr ? "" : originPath;
282        if (originPathStr.find("data/app/el1/") != std::string::npos ||
283            originPathStr.find("data/app/el2/") != std::string::npos) {
284            CheckDirRecursive(originPathStr);
285        }
286        return ret;
287    }
288
289    ret = mount(nullptr, destinationPath, nullptr, mountSharedFlag, nullptr);
290    APPSPAWN_CHECK(ret == 0, return ret, "errno is: %{public}d, private mount to %{public}s %{public}u failed",
291        errno, destinationPath, mountSharedFlag);
292    return 0;
293}
294
295static std::string& replace_all(std::string& str, const std::string& old_value, const std::string& new_value)
296{
297    while (true) {
298        std::string::size_type pos(0);
299        if ((pos = str.find(old_value)) != std::string::npos) {
300            str.replace(pos, old_value.length(), new_value);
301        } else {
302            break;
303        }
304    }
305    return str;
306}
307
308static std::vector<std::string> split(std::string &str, const std::string &pattern)
309{
310    std::string::size_type pos;
311    std::vector<std::string> result;
312    str += pattern;
313    size_t size = str.size();
314
315    for (unsigned int i = 0; i < size; i++) {
316        pos = str.find(pattern, i);
317        if (pos < size) {
318            std::string s = str.substr(i, pos - i);
319            result.push_back(s);
320            i = pos + pattern.size() - 1;
321        }
322    }
323
324    return result;
325}
326
327void SandboxUtils::DoSandboxChmod(nlohmann::json jsonConfig, std::string &sandboxRoot)
328{
329    const std::map<std::string, mode_t> modeMap = {{"S_IRUSR", S_IRUSR}, {"S_IWUSR", S_IWUSR}, {"S_IXUSR", S_IXUSR},
330                                                   {"S_IRGRP", S_IRGRP}, {"S_IWGRP", S_IWGRP}, {"S_IXGRP", S_IXGRP},
331                                                   {"S_IROTH", S_IROTH}, {"S_IWOTH", S_IWOTH}, {"S_IXOTH", S_IXOTH},
332                                                   {"S_IRWXU", S_IRWXU}, {"S_IRWXG", S_IRWXG}, {"S_IRWXO", S_IRWXO}};
333    std::string fileModeStr;
334    mode_t mode = 0;
335
336    bool rc = JsonUtils::GetStringFromJson(jsonConfig, g_destMode, fileModeStr);
337    if (rc == false) {
338        return;
339    }
340
341    std::vector<std::string> modeVec = split(fileModeStr, "|");
342    for (unsigned int i = 0; i < modeVec.size(); i++) {
343        if (modeMap.count(modeVec[i])) {
344            mode |= modeMap.at(modeVec[i]);
345        }
346    }
347
348    chmod(sandboxRoot.c_str(), mode);
349}
350
351unsigned long SandboxUtils::GetMountFlagsFromConfig(const std::vector<std::string> &vec)
352{
353    const std::map<std::string, mode_t> MountFlagsMap = { {"rec", MS_REC}, {"MS_REC", MS_REC},
354                                                          {"bind", MS_BIND}, {"MS_BIND", MS_BIND},
355                                                          {"move", MS_MOVE}, {"MS_MOVE", MS_MOVE},
356                                                          {"slave", MS_SLAVE}, {"MS_SLAVE", MS_SLAVE},
357                                                          {"rdonly", MS_RDONLY}, {"MS_RDONLY", MS_RDONLY},
358                                                          {"shared", MS_SHARED}, {"MS_SHARED", MS_SHARED},
359                                                          {"unbindable", MS_UNBINDABLE},
360                                                          {"MS_UNBINDABLE", MS_UNBINDABLE},
361                                                          {"remount", MS_REMOUNT}, {"MS_REMOUNT", MS_REMOUNT},
362                                                          {"nosuid", MS_NOSUID}, {"MS_NOSUID", MS_NOSUID},
363                                                          {"nodev", MS_NODEV}, {"MS_NODEV", MS_NODEV},
364                                                          {"noexec", MS_NOEXEC}, {"MS_NOEXEC", MS_NOEXEC},
365                                                          {"noatime", MS_NOATIME}, {"MS_NOATIME", MS_NOATIME},
366                                                          {"lazytime", MS_LAZYTIME}, {"MS_LAZYTIME", MS_LAZYTIME}};
367    unsigned long mountFlags = 0;
368
369    for (unsigned int i = 0; i < vec.size(); i++) {
370        if (MountFlagsMap.count(vec[i])) {
371            mountFlags |= MountFlagsMap.at(vec[i]);
372        }
373    }
374
375    return mountFlags;
376}
377
378static void MakeAtomicServiceDir(const AppSpawningCtx *appProperty, std::string path)
379{
380    struct stat st = {};
381    if (stat(path.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) {
382        return;
383    }
384    int ret = mkdir(path.c_str(), S_IRWXU);
385    APPSPAWN_CHECK(ret == 0, return, "mkdir %{public}s failed, errno %{public}d", path.c_str(), errno);
386
387    if (path.find("/database") != std::string::npos) {
388        ret = chmod(path.c_str(), S_IRWXU | S_IRWXG | S_ISGID);
389    } else if (path.find("/log") != std::string::npos) {
390        ret = chmod(path.c_str(), S_IRWXU | S_IRWXG);
391    }
392    APPSPAWN_CHECK(ret == 0, return, "chmod %{public}s failed, errno %{public}d", path.c_str(), errno);
393
394#ifdef WITH_SELINUX
395    AppSpawnMsgDomainInfo *msgDomainInfo =
396        reinterpret_cast<AppSpawnMsgDomainInfo *>(GetAppProperty(appProperty, TLV_DOMAIN_INFO));
397    APPSPAWN_CHECK(msgDomainInfo != NULL, return, "No domain info for %{public}s", GetProcessName(appProperty));
398    HapContext hapContext;
399    HapFileInfo hapFileInfo;
400    hapFileInfo.pathNameOrig.push_back(path);
401    hapFileInfo.apl = msgDomainInfo->apl;
402    hapFileInfo.packageName = GetProcessName(appProperty);
403    hapFileInfo.hapFlags = msgDomainInfo->hapFlags;
404    if (CheckAppMsgFlagsSet(appProperty, APP_FLAGS_DEBUGGABLE)) {
405        hapFileInfo.hapFlags |= SELINUX_HAP_DEBUGGABLE;
406    }
407    if ((path.find("/base") != std::string::npos) || (path.find("/database") != std::string::npos)) {
408        ret = hapContext.HapFileRestorecon(hapFileInfo);
409        APPSPAWN_CHECK(ret == 0, return, "set dir %{public}s selinuxLabel failed, apl %{public}s, ret %{public}d",
410            path.c_str(), hapFileInfo.apl.c_str(), ret);
411    }
412#endif
413    AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO));
414    APPSPAWN_CHECK(dacInfo != NULL, return, "No dac info in msg app property");
415    if (path.find("/base") != std::string::npos) {
416        ret = chown(path.c_str(), dacInfo->uid, dacInfo->gid);
417    } else if (path.find("/database") != std::string::npos) {
418        ret = chown(path.c_str(), dacInfo->uid, APP_DATABASE_DIR_GID);
419    } else if (path.find("/log") != std::string::npos) {
420        ret = chown(path.c_str(), dacInfo->uid, APP_LOG_DIR_GID);
421    }
422    APPSPAWN_CHECK(ret == 0, return, "chown %{public}s failed, errno %{public}d", path.c_str(), errno);
423    return;
424}
425
426static std::string ReplaceVariablePackageName(const AppSpawningCtx *appProperty, const std::string &path)
427{
428    std::string tmpSandboxPath = path;
429    AppSpawnMsgBundleInfo *bundleInfo =
430        reinterpret_cast<AppSpawnMsgBundleInfo *>(GetAppProperty(appProperty, TLV_BUNDLE_INFO));
431    APPSPAWN_CHECK(bundleInfo != NULL, return "", "No bundle info in msg %{public}s", GetBundleName(appProperty));
432
433    char *extension;
434    uint32_t flags = CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_ATOMIC_SERVICE) ? 0x4 : 0;
435    if (flags == 0) {
436        flags = (CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_CLONE_ENABLE) &&
437            bundleInfo->bundleIndex > 0) ? 0x1 : 0;
438        flags |= CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_EXTENSION_SANDBOX) ? 0x2 : 0;
439        extension = reinterpret_cast<char *>(
440            GetAppSpawnMsgExtInfo(appProperty->message, MSG_EXT_NAME_APP_EXTENSION, NULL));
441    }
442    std::ostringstream variablePackageName;
443    switch (flags) {
444        case 0:    // 0 default
445            variablePackageName << bundleInfo->bundleName;
446            break;
447        case 1:    // 1 +clone-bundleIndex+packageName
448            variablePackageName << "+clone-" << bundleInfo->bundleIndex << "+" << bundleInfo->bundleName;
449            break;
450        case 2: {  // 2 +extension-<extensionType>+packageName
451            APPSPAWN_CHECK(extension != NULL, return "", "Invalid extension data ");
452            variablePackageName << "+extension-" << extension << "+" << bundleInfo->bundleName;
453            break;
454        }
455        case 3: {  // 3 +clone-bundleIndex+extension-<extensionType>+packageName
456            APPSPAWN_CHECK(extension != NULL, return "", "Invalid extension data ");
457            variablePackageName << "+clone-" << bundleInfo->bundleIndex << "+extension" << "-" <<
458                extension << "+" << bundleInfo->bundleName;
459            break;
460        }
461        case 4: {  // 4 +auid-<accountId>+packageName
462            std::string accountId = SandboxUtils::GetExtraInfoByType(appProperty, MSG_EXT_NAME_ACCOUNT_ID);
463            variablePackageName << "+auid-" << accountId << "+" << bundleInfo->bundleName;
464            std::string atomicServicePath = path;
465            atomicServicePath = replace_all(atomicServicePath, g_variablePackageName, variablePackageName.str());
466            MakeAtomicServiceDir(appProperty, atomicServicePath);
467            break;
468        }
469        default:
470            variablePackageName << bundleInfo->bundleName;
471            break;
472    }
473    tmpSandboxPath = replace_all(tmpSandboxPath, g_variablePackageName, variablePackageName.str());
474    APPSPAWN_LOGV("tmpSandboxPath %{public}s", tmpSandboxPath.c_str());
475    return tmpSandboxPath;
476}
477
478string SandboxUtils::ConvertToRealPath(const AppSpawningCtx *appProperty, std::string path)
479{
480    AppSpawnMsgBundleInfo *info =
481        reinterpret_cast<AppSpawnMsgBundleInfo *>(GetAppProperty(appProperty, TLV_BUNDLE_INFO));
482    AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO));
483    if (info == nullptr || dacInfo == nullptr) {
484        return "";
485    }
486    if (path.find(g_packageNameIndex) != std::string::npos) {
487        std::string bundleNameWithIndex = info->bundleName;
488        if (info->bundleIndex != 0) {
489            bundleNameWithIndex = std::to_string(info->bundleIndex) + "_" + bundleNameWithIndex;
490        }
491        path = replace_all(path, g_packageNameIndex, bundleNameWithIndex);
492    }
493
494    if (path.find(g_packageName) != std::string::npos) {
495        path = replace_all(path, g_packageName, info->bundleName);
496    }
497
498    if (path.find(g_userId) != std::string::npos) {
499        path = replace_all(path, g_userId, std::to_string(dacInfo->uid / UID_BASE));
500    }
501
502    if (path.find(g_variablePackageName) != std::string::npos) {
503        path = ReplaceVariablePackageName(appProperty, path);
504    }
505
506    if (path.find(g_arkWebPackageName) != std::string::npos) {
507        path = replace_all(path, g_arkWebPackageName, getArkWebPackageName());
508        APPSPAWN_LOGV(
509            "arkWeb sandbox, path %{public}s, package:%{public}s",
510            path.c_str(), getArkWebPackageName().c_str());
511    }
512
513    return path;
514}
515
516std::string SandboxUtils::ConvertToRealPathWithPermission(const AppSpawningCtx *appProperty,
517                                                          std::string path)
518{
519    AppSpawnMsgBundleInfo *info =
520        reinterpret_cast<AppSpawnMsgBundleInfo *>(GetAppProperty(appProperty, TLV_BUNDLE_INFO));
521    if (info == nullptr) {
522        return "";
523    }
524    if (path.find(g_packageNameIndex) != std::string::npos) {
525        std::string bundleNameWithIndex = info->bundleName;
526        if (info->bundleIndex != 0) {
527            bundleNameWithIndex = std::to_string(info->bundleIndex) + "_" + bundleNameWithIndex;
528        }
529        path = replace_all(path, g_packageNameIndex, bundleNameWithIndex);
530    }
531
532    if (path.find(g_packageName) != std::string::npos) {
533        path = replace_all(path, g_packageName, info->bundleName);
534    }
535
536    if (path.find(g_userId) != std::string::npos) {
537        if (deviceTypeEnable_ == FILE_CROSS_APP_STATUS) {
538            path = replace_all(path, g_userId, "currentUser");
539        } else if (deviceTypeEnable_ == FILE_ACCESS_COMMON_DIR_STATUS) {
540            path = replace_all(path, g_userId, "currentUser");
541        } else {
542            return "";
543        }
544    }
545    return path;
546}
547
548bool SandboxUtils::GetSandboxDacOverrideEnable(nlohmann::json &config)
549{
550    std::string dacOverrideSensitive = "";
551    if (config.find(g_dacOverrideSensitive) == config.end()) {
552        return false;
553    }
554    dacOverrideSensitive = config[g_dacOverrideSensitive].get<std::string>();
555    if (dacOverrideSensitive.compare("true") == 0) {
556        return true;
557    }
558    return false;
559}
560
561std::string SandboxUtils::GetSbxPathByConfig(const AppSpawningCtx *appProperty, nlohmann::json &config)
562{
563    AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO));
564    if (dacInfo == nullptr) {
565        return "";
566    }
567
568    std::string sandboxRoot = "";
569    const std::string originSandboxPath = "/mnt/sandbox/<PackageName>";
570    std::string isolatedFlagText = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? "isolated/" : "";
571    const std::string defaultSandboxRoot = g_sandBoxDir + to_string(dacInfo->uid / UID_BASE) +
572        "/" + isolatedFlagText.c_str() + GetBundleName(appProperty);
573    if (config.find(g_sandboxRootPrefix) != config.end()) {
574        sandboxRoot = config[g_sandboxRootPrefix].get<std::string>();
575        if (sandboxRoot == originSandboxPath) {
576            sandboxRoot = defaultSandboxRoot;
577        } else {
578            sandboxRoot = ConvertToRealPath(appProperty, sandboxRoot);
579            APPSPAWN_LOGV("set sandbox-root name is %{public}s", sandboxRoot.c_str());
580        }
581    } else {
582        sandboxRoot = defaultSandboxRoot;
583        APPSPAWN_LOGV("set sandbox-root to default rootapp name is %{public}s", GetBundleName(appProperty));
584    }
585
586    return sandboxRoot;
587}
588
589bool SandboxUtils::GetSbxSwitchStatusByConfig(nlohmann::json &config)
590{
591    if (config.find(g_sandBoxSwitchPrefix) != config.end()) {
592        std::string switchStatus = config[g_sandBoxSwitchPrefix].get<std::string>();
593        if (switchStatus == g_sbxSwitchCheck) {
594            return true;
595        } else {
596            return false;
597        }
598    }
599
600    // if not find sandbox-switch node, default switch status is true
601    return true;
602}
603
604static bool CheckMountConfig(nlohmann::json &mntPoint, const AppSpawningCtx *appProperty,
605                             bool checkFlag)
606{
607    bool istrue = mntPoint.find(g_srcPath) == mntPoint.end() || (!mntPoint[g_srcPath].is_string()) ||
608                  mntPoint.find(g_sandBoxPath) == mntPoint.end() || (!mntPoint[g_sandBoxPath].is_string()) ||
609                  ((mntPoint.find(g_sandBoxFlags) == mntPoint.end()) &&
610                  (mntPoint.find(g_sandBoxFlagsCustomized) == mntPoint.end()));
611    APPSPAWN_CHECK(!istrue, return false,
612        "read mount config failed, app name is %{public}s", GetBundleName(appProperty));
613
614    AppSpawnMsgDomainInfo *info =
615        reinterpret_cast<AppSpawnMsgDomainInfo *>(GetAppProperty(appProperty, TLV_DOMAIN_INFO));
616    APPSPAWN_CHECK(info != nullptr, return false, "Filed to get domain info %{public}s", GetBundleName(appProperty));
617
618    if (mntPoint[g_appAplName] != nullptr) {
619        std::string app_apl_name = mntPoint[g_appAplName].get<std::string>();
620        const char *p_app_apl = nullptr;
621        p_app_apl = app_apl_name.c_str();
622        if (!strcmp(p_app_apl, info->apl)) {
623            return false;
624        }
625    }
626
627    const std::string configSrcPath = mntPoint[g_srcPath].get<std::string>();
628    // special handle wps and don't use /data/app/xxx/<Package> config
629    if (checkFlag && (configSrcPath.find("/data/app") != std::string::npos &&
630        (configSrcPath.find("/base") != std::string::npos ||
631         configSrcPath.find("/database") != std::string::npos
632        ) && configSrcPath.find(g_packageName) != std::string::npos)) {
633        return false;
634    }
635
636    return true;
637}
638
639static int32_t DoDlpAppMountStrategy(const AppSpawningCtx *appProperty,
640                                     const std::string &srcPath, const std::string &sandboxPath,
641                                     const std::string &fsType, unsigned long mountFlags)
642{
643    AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO));
644    if (dacInfo == nullptr) {
645        return -1;
646    }
647
648    // umount fuse path, make sure that sandbox path is not a mount point
649    umount2(sandboxPath.c_str(), MNT_DETACH);
650
651    int fd = open("/dev/fuse", O_RDWR);
652    APPSPAWN_CHECK(fd != -1, return -EINVAL, "open /dev/fuse failed, errno is %{public}d", errno);
653
654    char options[OPTIONS_MAX_LEN];
655    (void)sprintf_s(options, sizeof(options), "fd=%d,"
656        "rootmode=40000,user_id=%u,group_id=%u,allow_other,"
657        "context=\"u:object_r:dlp_fuse_file:s0\","
658        "fscontext=u:object_r:dlp_fuse_file:s0",
659        fd, dacInfo->uid, dacInfo->gid);
660
661    // To make sure destinationPath exist
662    MakeDirRecursive(sandboxPath, FILE_MODE);
663
664    int ret = 0;
665#ifndef APPSPAWN_TEST
666    APPSPAWN_LOGV("Bind mount %{public}s to %{public}s '%{public}s' '%{public}lu' '%{public}s'",
667        srcPath.c_str(), sandboxPath.c_str(), fsType.c_str(), mountFlags, options);
668    ret = mount(srcPath.c_str(), sandboxPath.c_str(), fsType.c_str(), mountFlags, options);
669    APPSPAWN_CHECK(ret == 0, close(fd);
670        return ret, "DoDlpAppMountStrategy failed, bind mount %{public}s to %{public}s failed %{public}d",
671        srcPath.c_str(), sandboxPath.c_str(), errno);
672
673    ret = mount(nullptr, sandboxPath.c_str(), nullptr, MS_SHARED, nullptr);
674    APPSPAWN_CHECK(ret == 0, close(fd);
675        return ret, "errno is: %{public}d, private mount to %{public}s failed", errno, sandboxPath.c_str());
676#endif
677    /* set DLP_FUSE_FD  */
678#ifdef WITH_DLP
679    SetDlpFuseFd(fd);
680#endif
681    ret = fd;
682    return ret;
683}
684
685static int32_t HandleSpecialAppMount(const AppSpawningCtx *appProperty,
686    const std::string &srcPath, const std::string &sandboxPath, const std::string &fsType, unsigned long mountFlags)
687{
688    std::string bundleName = GetBundleName(appProperty);
689    std::string processName = GetProcessName(appProperty);
690    /* dlp application mount strategy */
691    /* dlp is an example, we should change to real bundle name later */
692    if (bundleName.find(g_dlpBundleName) != std::string::npos &&
693        processName.compare(g_dlpBundleName) == 0) {
694        if (!fsType.empty()) {
695            return DoDlpAppMountStrategy(appProperty, srcPath, sandboxPath, fsType, mountFlags);
696        }
697    }
698    return -1;
699}
700
701static uint32_t ConvertFlagStr(const std::string &flagStr)
702{
703    const std::map<std::string, int> flagsMap = {{"0", 0}, {"START_FLAGS_BACKUP", 1},
704                                                 {"DLP_MANAGER", 2},
705                                                 {"DEVELOPER_MODE", 17}};
706
707    if (flagsMap.count(flagStr)) {
708        return 1 << flagsMap.at(flagStr);
709    }
710
711    return 0;
712}
713
714unsigned long SandboxUtils::GetSandboxMountFlags(nlohmann::json &config)
715{
716    unsigned long mountFlags = BASIC_MOUNT_FLAGS;
717    if (GetSandboxDacOverrideEnable(config) && (config.find(g_sandBoxFlagsCustomized) != config.end())) {
718        mountFlags = GetMountFlagsFromConfig(config[g_sandBoxFlagsCustomized].get<std::vector<std::string>>());
719    } else if (config.find(g_sandBoxFlags) != config.end()) {
720        mountFlags = GetMountFlagsFromConfig(config[g_sandBoxFlags].get<std::vector<std::string>>());
721    }
722    return mountFlags;
723}
724
725std::string SandboxUtils::GetSandboxFsType(nlohmann::json &config)
726{
727    std::string fsType = "";
728    if (GetSandboxDacOverrideEnable(config) && (config.find(g_fsType) != config.end())) {
729        fsType = config[g_fsType].get<std::string>();
730    }
731    return fsType;
732}
733
734std::string SandboxUtils::GetSandboxOptions(const AppSpawningCtx *appProperty, nlohmann::json &config)
735{
736    AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO));
737    if (dacInfo == nullptr) {
738        return "";
739    }
740
741    std::string options = "";
742    const int userIdBase = 200000;
743    if (GetSandboxDacOverrideEnable(config) && (config.find(g_sandBoxOptions) != config.end())) {
744        options = config[g_sandBoxOptions].get<std::string>() + ",user_id=";
745        options += std::to_string(dacInfo->uid / userIdBase);
746    }
747    return options;
748}
749
750void SandboxUtils::GetSandboxMountConfig(const AppSpawningCtx *appProperty, const std::string &section,
751                                         nlohmann::json &mntPoint, SandboxMountConfig &mountConfig)
752{
753    if (section.compare(g_permissionPrefix) == 0) {
754        mountConfig.optionsPoint = GetSandboxOptions(appProperty, mntPoint);
755        mountConfig.fsType = GetSandboxFsType(mntPoint);
756    } else {
757        mountConfig.fsType = (mntPoint.find(g_fsType) != mntPoint.end()) ? mntPoint[g_fsType].get<std::string>() : "";
758        mountConfig.optionsPoint = "";
759    }
760    return;
761}
762
763std::string SandboxUtils::GetSandboxPath(const AppSpawningCtx *appProperty, nlohmann::json &mntPoint,
764    const std::string &section, std::string sandboxRoot)
765{
766    std::string sandboxPath = "";
767    std::string tmpSandboxPath = mntPoint[g_sandBoxPath].get<std::string>();
768    if (section.compare(g_permissionPrefix) == 0) {
769        sandboxPath = sandboxRoot + ConvertToRealPathWithPermission(appProperty, tmpSandboxPath);
770    } else {
771        sandboxPath = sandboxRoot + ConvertToRealPath(appProperty, tmpSandboxPath);
772    }
773    return sandboxPath;
774}
775
776static bool CheckMountFlag(const AppSpawningCtx *appProperty, const std::string bundleName, nlohmann::json &appConfig)
777{
778    if (appConfig.find(g_flags) != appConfig.end()) {
779        if (((ConvertFlagStr(appConfig[g_flags].get<std::string>()) & GetAppMsgFlags(appProperty)) != 0) &&
780            bundleName.find("wps") != std::string::npos) {
781            return true;
782        }
783    }
784    return false;
785}
786
787int SandboxUtils::DoAllMntPointsMount(const AppSpawningCtx *appProperty,
788                                      nlohmann::json &appConfig, const char *typeName, const std::string &section)
789{
790    std::string bundleName = GetBundleName(appProperty);
791    if (appConfig.find(g_mountPrefix) == appConfig.end()) {
792        APPSPAWN_LOGV("mount config is not found in %{public}s, app name is %{public}s",
793            section.c_str(), bundleName.c_str());
794        return 0;
795    }
796
797    std::string sandboxRoot = GetSbxPathByConfig(appProperty, appConfig);
798    bool checkFlag = CheckMountFlag(appProperty, bundleName, appConfig);
799
800    nlohmann::json& mountPoints = appConfig[g_mountPrefix];
801    unsigned int mountPointSize = mountPoints.size();
802    for (unsigned int i = 0; i < mountPointSize; i++) {
803        nlohmann::json& mntPoint = mountPoints[i];
804        if ((CheckMountConfig(mntPoint, appProperty, checkFlag) == false)) {
805            continue;
806        }
807
808        std::string srcPath = ConvertToRealPath(appProperty, mntPoint[g_srcPath].get<std::string>());
809        std::string sandboxPath = GetSandboxPath(appProperty, mntPoint, section, sandboxRoot);
810        SandboxMountConfig mountConfig = {0};
811        GetSandboxMountConfig(appProperty, section, mntPoint, mountConfig);
812        unsigned long mountFlags = GetSandboxMountFlags(mntPoint);
813        mode_t mountSharedFlag = (mntPoint.find(g_mountSharedFlag) != mntPoint.end()) ? MS_SHARED : MS_SLAVE;
814
815        /* if app mount failed for special strategy, we need deal with common mount config */
816        int ret = HandleSpecialAppMount(appProperty, srcPath, sandboxPath, mountConfig.fsType, mountFlags);
817        if (ret < 0) {
818            ret = DoAppSandboxMountOnce(srcPath.c_str(), sandboxPath.c_str(), mountConfig.fsType.c_str(),
819                                        mountFlags, mountConfig.optionsPoint.c_str(), mountSharedFlag);
820        }
821        if (ret) {
822            std::string actionStatus = g_statusCheck;
823            (void)JsonUtils::GetStringFromJson(mntPoint, g_actionStatuc, actionStatus);
824            if (actionStatus == g_statusCheck) {
825                APPSPAWN_LOGE("DoAppSandboxMountOnce section %{public}s failed, %{public}s",
826                    section.c_str(), sandboxPath.c_str());
827                return ret;
828            }
829        }
830
831        DoSandboxChmod(mntPoint, sandboxRoot);
832    }
833
834    return 0;
835}
836
837int32_t SandboxUtils::DoAddGid(AppSpawningCtx *appProperty, nlohmann::json &appConfig,
838                               const char* permissionName, const std::string &section)
839{
840    std::string bundleName = GetBundleName(appProperty);
841    if (appConfig.find(g_gidPrefix) == appConfig.end()) {
842        return 0;
843    }
844    AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO));
845    if (dacInfo == nullptr) {
846        return 0;
847    }
848
849    nlohmann::json& gids = appConfig[g_gidPrefix];
850    unsigned int gidSize = gids.size();
851    for (unsigned int i = 0; i < gidSize; i++) {
852        if (dacInfo->gidCount < APP_MAX_GIDS) {
853            APPSPAWN_LOGI("add gid to gitTable in %{public}s, permission is %{public}s, gid:%{public}u",
854                bundleName.c_str(), permissionName, gids[i].get<uint32_t>());
855            dacInfo->gidTable[dacInfo->gidCount++] = gids[i].get<uint32_t>();
856        }
857    }
858    return 0;
859}
860
861int SandboxUtils::DoAllSymlinkPointslink(const AppSpawningCtx *appProperty, nlohmann::json &appConfig)
862{
863    APPSPAWN_CHECK(appConfig.find(g_symlinkPrefix) != appConfig.end(), return 0, "symlink config is not found,"
864        "maybe result sandbox launch failed app name is %{public}s", GetBundleName(appProperty));
865
866    nlohmann::json& symlinkPoints = appConfig[g_symlinkPrefix];
867    std::string sandboxRoot = GetSbxPathByConfig(appProperty, appConfig);
868    unsigned int symlinkPointSize = symlinkPoints.size();
869
870    for (unsigned int i = 0; i < symlinkPointSize; i++) {
871        nlohmann::json& symPoint = symlinkPoints[i];
872
873        // Check the validity of the symlink configuration
874        if (symPoint.find(g_targetName) == symPoint.end() || (!symPoint[g_targetName].is_string()) ||
875            symPoint.find(g_linkName) == symPoint.end() || (!symPoint[g_linkName].is_string())) {
876            APPSPAWN_LOGE("read symlink config failed, app name is %{public}s", GetBundleName(appProperty));
877            continue;
878        }
879
880        std::string targetName = ConvertToRealPath(appProperty, symPoint[g_targetName].get<std::string>());
881        std::string linkName = sandboxRoot + ConvertToRealPath(appProperty, symPoint[g_linkName].get<std::string>());
882        APPSPAWN_LOGV("symlink, from %{public}s to %{public}s", targetName.c_str(), linkName.c_str());
883
884        int ret = symlink(targetName.c_str(), linkName.c_str());
885        if (ret && errno != EEXIST) {
886            APPSPAWN_LOGE("errno is %{public}d, symlink failed, %{public}s", errno, linkName.c_str());
887
888            std::string actionStatus = g_statusCheck;
889            (void)JsonUtils::GetStringFromJson(symPoint, g_actionStatuc, actionStatus);
890            if (actionStatus == g_statusCheck) {
891                return ret;
892            }
893        }
894
895        DoSandboxChmod(symPoint, sandboxRoot);
896    }
897
898    return 0;
899}
900
901int32_t SandboxUtils::DoSandboxFilePrivateBind(const AppSpawningCtx *appProperty,
902                                               nlohmann::json &wholeConfig)
903{
904    const char *bundleName = GetBundleName(appProperty);
905    nlohmann::json& privateAppConfig = wholeConfig[g_privatePrefix][0];
906    if (privateAppConfig.find(bundleName) != privateAppConfig.end()) {
907        APPSPAWN_LOGV("DoSandboxFilePrivateBind %{public}s", bundleName);
908        DoAddGid((AppSpawningCtx *)appProperty, privateAppConfig[bundleName][0], "", g_privatePrefix);
909        return DoAllMntPointsMount(appProperty, privateAppConfig[bundleName][0], nullptr, g_privatePrefix);
910    }
911
912    return 0;
913}
914
915int32_t SandboxUtils::DoSandboxFilePermissionBind(AppSpawningCtx *appProperty,
916                                                  nlohmann::json &wholeConfig)
917{
918    if (wholeConfig.find(g_permissionPrefix) == wholeConfig.end()) {
919        APPSPAWN_LOGV("DoSandboxFilePermissionBind not found permission information in config file");
920        return 0;
921    }
922    nlohmann::json& permissionAppConfig = wholeConfig[g_permissionPrefix][0];
923    for (nlohmann::json::iterator it = permissionAppConfig.begin(); it != permissionAppConfig.end(); ++it) {
924        const std::string permission = it.key();
925        int index = GetPermissionIndex(nullptr, permission.c_str());
926        APPSPAWN_LOGV("DoSandboxFilePermissionBind mountPermissionFlags %{public}d", index);
927        if (CheckAppPermissionFlagSet(appProperty, static_cast<uint32_t>(index))) {
928            DoAddGid(appProperty, permissionAppConfig[permission][0], permission.c_str(), g_permissionPrefix);
929            DoAllMntPointsMount(appProperty, permissionAppConfig[permission][0], permission.c_str(),
930                                g_permissionPrefix);
931        } else {
932            APPSPAWN_LOGV("DoSandboxFilePermissionBind false %{public}s permission %{public}s",
933                GetBundleName(appProperty), permission.c_str());
934        }
935    }
936    return 0;
937}
938
939std::set<std::string> SandboxUtils::GetMountPermissionNames()
940{
941    std::set<std::string> permissionSet;
942    for (auto& config : SandboxUtils::GetJsonConfig(SANBOX_APP_JSON_CONFIG)) {
943        if (config.find(g_permissionPrefix) == config.end()) {
944            continue;
945        }
946        nlohmann::json& permissionAppConfig = config[g_permissionPrefix][0];
947        for (auto it = permissionAppConfig.begin(); it != permissionAppConfig.end(); it++) {
948            permissionSet.insert(it.key());
949        }
950    }
951    APPSPAWN_LOGI("GetMountPermissionNames size: %{public}lu", static_cast<unsigned long>(permissionSet.size()));
952    return permissionSet;
953}
954
955int32_t SandboxUtils::DoSandboxFilePrivateSymlink(const AppSpawningCtx *appProperty,
956                                                  nlohmann::json &wholeConfig)
957{
958    const char *bundleName = GetBundleName(appProperty);
959    nlohmann::json& privateAppConfig = wholeConfig[g_privatePrefix][0];
960    if (privateAppConfig.find(bundleName) != privateAppConfig.end()) {
961        return DoAllSymlinkPointslink(appProperty, privateAppConfig[bundleName][0]);
962    }
963
964    return 0;
965}
966
967int32_t SandboxUtils::HandleFlagsPoint(const AppSpawningCtx *appProperty,
968                                       nlohmann::json &appConfig)
969{
970    if (appConfig.find(g_flagePoint) == appConfig.end()) {
971        return 0;
972    }
973
974    nlohmann::json& flagsPoints = appConfig[g_flagePoint];
975    unsigned int flagsPointSize = flagsPoints.size();
976
977    for (unsigned int i = 0; i < flagsPointSize; i++) {
978        nlohmann::json& flagPoint = flagsPoints[i];
979
980        if (flagPoint.find(g_flags) != flagPoint.end() && flagPoint[g_flags].is_string()) {
981            std::string flagsStr = flagPoint[g_flags].get<std::string>();
982            uint32_t flag = ConvertFlagStr(flagsStr);
983            if ((GetAppMsgFlags(appProperty) & flag) != 0) {
984                return DoAllMntPointsMount(appProperty, flagPoint, nullptr, g_flagePoint);
985            }
986        } else {
987            APPSPAWN_LOGE("read flags config failed, app name is %{public}s", GetBundleName(appProperty));
988        }
989    }
990
991    return 0;
992}
993
994int32_t SandboxUtils::DoSandboxFilePrivateFlagsPointHandle(const AppSpawningCtx *appProperty,
995                                                           nlohmann::json &wholeConfig)
996{
997    const char *bundleName = GetBundleName(appProperty);
998    nlohmann::json& privateAppConfig = wholeConfig[g_privatePrefix][0];
999    if (privateAppConfig.find(bundleName) != privateAppConfig.end()) {
1000        return HandleFlagsPoint(appProperty, privateAppConfig[bundleName][0]);
1001    }
1002
1003    return 0;
1004}
1005
1006int32_t SandboxUtils::DoSandboxFileCommonFlagsPointHandle(const AppSpawningCtx *appProperty,
1007                                                          nlohmann::json &wholeConfig)
1008{
1009    nlohmann::json& commonConfig = wholeConfig[g_commonPrefix][0];
1010    if (commonConfig.find(g_appResources) != commonConfig.end()) {
1011        return HandleFlagsPoint(appProperty, commonConfig[g_appResources][0]);
1012    }
1013
1014    return 0;
1015}
1016
1017int32_t SandboxUtils::DoSandboxFileCommonBind(const AppSpawningCtx *appProperty, nlohmann::json &wholeConfig)
1018{
1019    nlohmann::json& commonConfig = wholeConfig[g_commonPrefix][0];
1020    int ret = 0;
1021
1022    if (commonConfig.find(g_appBase) != commonConfig.end()) {
1023        ret = DoAllMntPointsMount(appProperty, commonConfig[g_appBase][0], nullptr, g_appBase);
1024        if (ret) {
1025            return ret;
1026        }
1027    }
1028
1029    if (commonConfig.find(g_appResources) != commonConfig.end()) {
1030        ret = DoAllMntPointsMount(appProperty, commonConfig[g_appResources][0], nullptr, g_appResources);
1031    }
1032
1033    return ret;
1034}
1035
1036int32_t SandboxUtils::DoSandboxFileCommonSymlink(const AppSpawningCtx *appProperty,
1037                                                 nlohmann::json &wholeConfig)
1038{
1039    nlohmann::json& commonConfig = wholeConfig[g_commonPrefix][0];
1040    int ret = 0;
1041
1042    if (commonConfig.find(g_appBase) != commonConfig.end()) {
1043        ret = DoAllSymlinkPointslink(appProperty, commonConfig[g_appBase][0]);
1044        if (ret) {
1045            return ret;
1046        }
1047    }
1048
1049    if (commonConfig.find(g_appResources) != commonConfig.end()) {
1050        ret = DoAllSymlinkPointslink(appProperty, commonConfig[g_appResources][0]);
1051    }
1052
1053    return ret;
1054}
1055
1056int32_t SandboxUtils::SetPrivateAppSandboxProperty_(const AppSpawningCtx *appProperty,
1057                                                    nlohmann::json &config)
1058{
1059    int ret = DoSandboxFilePrivateBind(appProperty, config);
1060    APPSPAWN_CHECK(ret == 0, return ret, "DoSandboxFilePrivateBind failed");
1061
1062    ret = DoSandboxFilePrivateSymlink(appProperty, config);
1063    APPSPAWN_CHECK_ONLY_LOG(ret == 0, "DoSandboxFilePrivateSymlink failed");
1064
1065    ret = DoSandboxFilePrivateFlagsPointHandle(appProperty, config);
1066    APPSPAWN_CHECK_ONLY_LOG(ret == 0, "DoSandboxFilePrivateFlagsPointHandle failed");
1067
1068    return ret;
1069}
1070
1071int32_t SandboxUtils::SetPermissionAppSandboxProperty_(AppSpawningCtx *appProperty,
1072                                                       nlohmann::json &config)
1073{
1074    int ret = DoSandboxFilePermissionBind(appProperty, config);
1075    APPSPAWN_CHECK(ret == 0, return ret, "DoSandboxFilePermissionBind failed");
1076    return ret;
1077}
1078
1079
1080int32_t SandboxUtils::SetRenderSandboxProperty(const AppSpawningCtx *appProperty,
1081                                               std::string &sandboxPackagePath)
1082{
1083    return 0;
1084}
1085
1086int32_t SandboxUtils::SetRenderSandboxPropertyNweb(const AppSpawningCtx *appProperty,
1087                                                   std::string &sandboxPackagePath)
1088{
1089    SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ?
1090        SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG;
1091
1092    for (auto& config : SandboxUtils::GetJsonConfig(type)) {
1093        nlohmann::json& privateAppConfig = config[g_privatePrefix][0];
1094        if (privateAppConfig.find(g_ohosRender) != privateAppConfig.end()) {
1095            int ret = DoAllMntPointsMount(appProperty, privateAppConfig[g_ohosRender][0], nullptr, g_ohosRender);
1096            APPSPAWN_CHECK(ret == 0, return ret, "DoAllMntPointsMount failed, %{public}s",
1097                GetBundleName(appProperty));
1098            ret = DoAllSymlinkPointslink(appProperty, privateAppConfig[g_ohosRender][0]);
1099            APPSPAWN_CHECK(ret == 0, return ret, "DoAllSymlinkPointslink failed, %{public}s",
1100                GetBundleName(appProperty));
1101            ret = HandleFlagsPoint(appProperty, privateAppConfig[g_ohosRender][0]);
1102            APPSPAWN_CHECK_ONLY_LOG(ret == 0, "HandleFlagsPoint for render-sandbox failed, %{public}s",
1103                GetBundleName(appProperty));
1104        }
1105    }
1106    return 0;
1107}
1108
1109int32_t SandboxUtils::SetPrivateAppSandboxProperty(const AppSpawningCtx *appProperty)
1110{
1111    int ret = 0;
1112    SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ?
1113        SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG;
1114
1115    for (auto& config : SandboxUtils::GetJsonConfig(type)) {
1116        ret = SetPrivateAppSandboxProperty_(appProperty, config);
1117        APPSPAWN_CHECK(ret == 0, return ret, "parse adddata-sandbox config failed");
1118    }
1119    return ret;
1120}
1121
1122static bool GetSandboxPrivateSharedStatus(const string &bundleName, AppSpawningCtx *appProperty)
1123{
1124    bool result = false;
1125    SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ?
1126        SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG;
1127
1128    for (auto& config : SandboxUtils::GetJsonConfig(type)) {
1129        nlohmann::json& privateAppConfig = config[g_privatePrefix][0];
1130        if (privateAppConfig.find(bundleName) != privateAppConfig.end() &&
1131            privateAppConfig[bundleName][0].find(g_sandBoxShared) !=
1132            privateAppConfig[bundleName][0].end()) {
1133            string sandboxSharedStatus =
1134                privateAppConfig[bundleName][0][g_sandBoxShared].get<std::string>();
1135            if (sandboxSharedStatus == g_statusCheck) {
1136                result = true;
1137            }
1138        }
1139    }
1140    return result;
1141}
1142
1143int32_t SandboxUtils::SetPermissionAppSandboxProperty(AppSpawningCtx *appProperty)
1144{
1145    int ret = 0;
1146    SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ?
1147        SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG;
1148
1149    for (auto& config : SandboxUtils::GetJsonConfig(type)) {
1150        ret = SetPermissionAppSandboxProperty_(appProperty, config);
1151        APPSPAWN_CHECK(ret == 0, return ret, "parse adddata-sandbox config failed");
1152    }
1153    return ret;
1154}
1155
1156
1157int32_t SandboxUtils::SetCommonAppSandboxProperty_(const AppSpawningCtx *appProperty,
1158                                                   nlohmann::json &config)
1159{
1160    int rc = 0;
1161
1162    rc = DoSandboxFileCommonBind(appProperty, config);
1163    APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxFileCommonBind failed, %{public}s", GetBundleName(appProperty));
1164
1165    // if sandbox switch is off, don't do symlink work again
1166    if (CheckAppSandboxSwitchStatus(appProperty) == true && (CheckTotalSandboxSwitchStatus(appProperty) == true)) {
1167        rc = DoSandboxFileCommonSymlink(appProperty, config);
1168        APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxFileCommonSymlink failed, %{public}s", GetBundleName(appProperty));
1169    }
1170
1171    rc = DoSandboxFileCommonFlagsPointHandle(appProperty, config);
1172    APPSPAWN_CHECK_ONLY_LOG(rc == 0, "DoSandboxFilePrivateFlagsPointHandle failed");
1173
1174    return rc;
1175}
1176
1177int32_t SandboxUtils::SetCommonAppSandboxProperty(const AppSpawningCtx *appProperty,
1178                                                  std::string &sandboxPackagePath)
1179{
1180    int ret = 0;
1181    SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ?
1182        SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG;
1183
1184    for (auto& jsonConfig : SandboxUtils::GetJsonConfig(type)) {
1185        ret = SetCommonAppSandboxProperty_(appProperty, jsonConfig);
1186        APPSPAWN_CHECK(ret == 0, return ret,
1187            "parse appdata config for common failed, %{public}s", sandboxPackagePath.c_str());
1188    }
1189
1190    ret = MountAllHsp(appProperty, sandboxPackagePath);
1191    APPSPAWN_CHECK(ret == 0, return ret, "mount extraInfo failed, %{public}s", sandboxPackagePath.c_str());
1192
1193    ret = MountAllGroup(appProperty, sandboxPackagePath);
1194    APPSPAWN_CHECK(ret == 0, return ret, "mount groupList failed, %{public}s", sandboxPackagePath.c_str());
1195
1196    AppSpawnMsgDomainInfo *info =
1197        reinterpret_cast<AppSpawnMsgDomainInfo *>(GetAppProperty(appProperty, TLV_DOMAIN_INFO));
1198    APPSPAWN_CHECK(info != nullptr, return -1, "No domain info %{public}s", sandboxPackagePath.c_str());
1199    if (strcmp(info->apl, APL_SYSTEM_BASIC.data()) == 0 ||
1200        strcmp(info->apl, APL_SYSTEM_CORE.data()) == 0 ||
1201        CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ACCESS_BUNDLE_DIR)) {
1202        // need permission check for system app here
1203        std::string destbundlesPath = sandboxPackagePath + g_dataBundles;
1204        DoAppSandboxMountOnce(g_physicalAppInstallPath.c_str(), destbundlesPath.c_str(), "", BASIC_MOUNT_FLAGS,
1205                              nullptr);
1206    }
1207
1208    return 0;
1209}
1210
1211static inline bool CheckPath(const std::string& name)
1212{
1213    return !name.empty() && name != "." && name != ".." && name.find("/") == std::string::npos;
1214}
1215
1216std::string SandboxUtils::GetExtraInfoByType(const AppSpawningCtx *appProperty, const std::string &type)
1217{
1218    uint32_t len = 0;
1219    char *info = reinterpret_cast<char *>(GetAppPropertyExt(appProperty, type.c_str(), &len));
1220    if (info == nullptr) {
1221        return "";
1222    }
1223    return std::string(info, len);
1224}
1225
1226int32_t SandboxUtils::MountAllHsp(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath)
1227{
1228    int ret = 0;
1229    string hspListInfo = GetExtraInfoByType(appProperty, HSPLIST_SOCKET_TYPE);
1230    if (hspListInfo.length() == 0) {
1231        return ret;
1232    }
1233
1234    nlohmann::json hsps = nlohmann::json::parse(hspListInfo.c_str(), nullptr, false);
1235    APPSPAWN_CHECK(!hsps.is_discarded() && hsps.contains(g_hspList_key_bundles) && hsps.contains(g_hspList_key_modules)
1236        && hsps.contains(g_hspList_key_versions), return -1, "MountAllHsp: json parse failed");
1237
1238    nlohmann::json& bundles = hsps[g_hspList_key_bundles];
1239    nlohmann::json& modules = hsps[g_hspList_key_modules];
1240    nlohmann::json& versions = hsps[g_hspList_key_versions];
1241    APPSPAWN_CHECK(bundles.is_array() && modules.is_array() && versions.is_array() && bundles.size() == modules.size()
1242        && bundles.size() == versions.size(), return -1, "MountAllHsp: value is not arrary or sizes are not same");
1243
1244    APPSPAWN_LOGI("MountAllHsp: app = %{public}s, cnt = %{public}lu",
1245        GetBundleName(appProperty), static_cast<unsigned long>(bundles.size()));
1246    for (uint32_t i = 0; i < bundles.size(); i++) {
1247        // elements in json arrary can be different type
1248        APPSPAWN_CHECK(bundles[i].is_string() && modules[i].is_string() && versions[i].is_string(),
1249            return -1, "MountAllHsp: element type error");
1250
1251        std::string libBundleName = bundles[i];
1252        std::string libModuleName = modules[i];
1253        std::string libVersion = versions[i];
1254        APPSPAWN_CHECK(CheckPath(libBundleName) && CheckPath(libModuleName) && CheckPath(libVersion),
1255            return -1, "MountAllHsp: path error");
1256
1257        std::string libPhysicalPath = g_physicalAppInstallPath + libBundleName + "/" + libVersion + "/" + libModuleName;
1258        std::string mntPath =  sandboxPackagePath + g_sandboxHspInstallPath + libBundleName + "/" + libModuleName;
1259        ret = DoAppSandboxMountOnce(libPhysicalPath.c_str(), mntPath.c_str(), "", BASIC_MOUNT_FLAGS, nullptr);
1260        APPSPAWN_CHECK(ret == 0, return ret, "mount library failed %{public}d", ret);
1261    }
1262    return ret;
1263}
1264
1265int32_t SandboxUtils::DoSandboxRootFolderCreateAdapt(std::string &sandboxPackagePath)
1266{
1267#ifndef APPSPAWN_TEST
1268    int rc = mount(nullptr, "/", nullptr, MS_REC | MS_SLAVE, nullptr);
1269    APPSPAWN_CHECK(rc == 0, return rc, "set propagation slave failed");
1270#endif
1271    MakeDirRecursive(sandboxPackagePath, FILE_MODE);
1272
1273    // bind mount "/" to /mnt/sandbox/<currentUserId>/<packageName> path
1274    // rootfs: to do more resources bind mount here to get more strict resources constraints
1275#ifndef APPSPAWN_TEST
1276    rc = mount("/", sandboxPackagePath.c_str(), nullptr, BASIC_MOUNT_FLAGS, nullptr);
1277    APPSPAWN_CHECK(rc == 0, return rc, "mount bind / failed, %{public}d", errno);
1278#endif
1279    return 0;
1280}
1281
1282int32_t SandboxUtils::MountAllGroup(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath)
1283{
1284    int ret = 0;
1285    string dataGroupInfo = GetExtraInfoByType(appProperty, DATA_GROUP_SOCKET_TYPE);
1286    if (dataGroupInfo.length() == 0) {
1287        return ret;
1288    }
1289
1290    nlohmann::json groups = nlohmann::json::parse(dataGroupInfo.c_str(), nullptr, false);
1291    APPSPAWN_CHECK(!groups.is_discarded() && groups.contains(g_groupList_key_dataGroupId)
1292        && groups.contains(g_groupList_key_gid) && groups.contains(g_groupList_key_dir), return -1,
1293            "MountAllGroup: json parse failed");
1294
1295    nlohmann::json& dataGroupIds = groups[g_groupList_key_dataGroupId];
1296    nlohmann::json& gids = groups[g_groupList_key_gid];
1297    nlohmann::json& dirs = groups[g_groupList_key_dir];
1298    APPSPAWN_CHECK(dataGroupIds.is_array() && gids.is_array() && dirs.is_array() && dataGroupIds.size() == gids.size()
1299        && dataGroupIds.size() == dirs.size(), return -1, "MountAllGroup: value is not arrary or sizes are not same");
1300    APPSPAWN_LOGI("MountAllGroup: app = %{public}s, cnt = %{public}lu",
1301        GetBundleName(appProperty), static_cast<unsigned long>(dataGroupIds.size()));
1302    for (uint32_t i = 0; i < dataGroupIds.size(); i++) {
1303        // elements in json arrary can be different type
1304        APPSPAWN_CHECK(dataGroupIds[i].is_string() && gids[i].is_string() && dirs[i].is_string(),
1305            return -1, "MountAllGroup: element type error");
1306
1307        std::string libPhysicalPath = dirs[i];
1308        APPSPAWN_CHECK(!CheckPath(libPhysicalPath), return -1, "MountAllGroup: path error");
1309
1310        size_t lastPathSplitPos = libPhysicalPath.find_last_of(g_fileSeparator);
1311        APPSPAWN_CHECK(lastPathSplitPos != std::string::npos, return -1, "MountAllGroup: path error");
1312
1313        std::string dataGroupUuid = libPhysicalPath.substr(lastPathSplitPos + 1);
1314        std::string mntPath = sandboxPackagePath + g_sandboxGroupPath + dataGroupUuid;
1315        mode_t mountFlags = MS_REC | MS_BIND;
1316        mode_t mountSharedFlag = MS_SLAVE;
1317        if (CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX)) {
1318            mountSharedFlag |= MS_REMOUNT | MS_NODEV | MS_RDONLY | MS_BIND;
1319        }
1320        ret = DoAppSandboxMountOnce(libPhysicalPath.c_str(), mntPath.c_str(), "", mountFlags, nullptr,
1321            mountSharedFlag);
1322        APPSPAWN_CHECK(ret == 0, return ret, "mount library failed %{public}d", ret);
1323    }
1324    return ret;
1325}
1326
1327int32_t SandboxUtils::DoSandboxRootFolderCreate(const AppSpawningCtx *appProperty,
1328                                                std::string &sandboxPackagePath)
1329{
1330#ifndef APPSPAWN_TEST
1331    int rc = mount(nullptr, "/", nullptr, MS_REC | MS_SLAVE, nullptr);
1332    if (rc) {
1333        return rc;
1334    }
1335#endif
1336    DoAppSandboxMountOnce(sandboxPackagePath.c_str(), sandboxPackagePath.c_str(), "",
1337                          BASIC_MOUNT_FLAGS, nullptr);
1338
1339    return 0;
1340}
1341
1342uint32_t SandboxUtils::GetSandboxNsFlags(bool isNweb)
1343{
1344    uint32_t nsFlags = 0;
1345    nlohmann::json appConfig;
1346    const std::map<std::string, uint32_t> NamespaceFlagsMap = { {"pid", CLONE_NEWPID},
1347                                                                {"net", CLONE_NEWNET} };
1348
1349    if (!CheckTotalSandboxSwitchStatus(nullptr)) {
1350        return nsFlags;
1351    }
1352
1353    for (auto& config : SandboxUtils::GetJsonConfig(SANBOX_APP_JSON_CONFIG)) {
1354        if (isNweb) {
1355            nlohmann::json& privateAppConfig = config[g_privatePrefix][0];
1356            if (privateAppConfig.find(g_ohosRender) == privateAppConfig.end()) {
1357                continue;
1358            }
1359            appConfig = privateAppConfig[g_ohosRender][0];
1360        } else {
1361            nlohmann::json& baseConfig = config[g_commonPrefix][0];
1362            if (baseConfig.find(g_appBase) == baseConfig.end()) {
1363                continue;
1364            }
1365            appConfig = baseConfig[g_appBase][0];
1366        }
1367        if (appConfig.find(g_sandBoxNsFlags) == appConfig.end()) {
1368            continue;
1369        }
1370        const auto vec = appConfig[g_sandBoxNsFlags].get<std::vector<std::string>>();
1371        for (unsigned int j = 0; j < vec.size(); j++) {
1372            if (NamespaceFlagsMap.count(vec[j])) {
1373                nsFlags |= NamespaceFlagsMap.at(vec[j]);
1374            }
1375        }
1376    }
1377
1378    if (!nsFlags) {
1379        APPSPAWN_LOGE("config is not found %{public}s ns config", isNweb ? "Nweb" : "App");
1380    }
1381    return nsFlags;
1382}
1383
1384bool SandboxUtils::CheckBundleNameForPrivate(const std::string &bundleName)
1385{
1386    if (bundleName.find(g_internal) != std::string::npos) {
1387        return false;
1388    }
1389    return true;
1390}
1391
1392bool SandboxUtils::CheckTotalSandboxSwitchStatus(const AppSpawningCtx *appProperty)
1393{
1394    SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ?
1395        SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG;
1396
1397    for (auto& wholeConfig : SandboxUtils::GetJsonConfig(type)) {
1398        if (wholeConfig.find(g_commonPrefix) == wholeConfig.end()) {
1399            continue;
1400        }
1401        nlohmann::json& commonAppConfig = wholeConfig[g_commonPrefix][0];
1402        if (commonAppConfig.find(g_topSandBoxSwitchPrefix) != commonAppConfig.end()) {
1403            std::string switchStatus = commonAppConfig[g_topSandBoxSwitchPrefix].get<std::string>();
1404            return switchStatus == g_sbxSwitchCheck;
1405        }
1406    }
1407    // default sandbox switch is on
1408    return true;
1409}
1410
1411bool SandboxUtils::CheckAppSandboxSwitchStatus(const AppSpawningCtx *appProperty)
1412{
1413    bool rc = true;
1414    SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ?
1415        SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG;
1416
1417    for (auto& wholeConfig : SandboxUtils::GetJsonConfig(type)) {
1418        if (wholeConfig.find(g_privatePrefix) == wholeConfig.end()) {
1419            continue;
1420        }
1421        nlohmann::json& privateAppConfig = wholeConfig[g_privatePrefix][0];
1422        if (privateAppConfig.find(GetBundleName(appProperty)) != privateAppConfig.end()) {
1423            nlohmann::json& appConfig = privateAppConfig[GetBundleName(appProperty)][0];
1424            rc = GetSbxSwitchStatusByConfig(appConfig);
1425            if (rc) {
1426                break;
1427            }
1428        }
1429    }
1430    // default sandbox switch is on
1431    return rc;
1432}
1433
1434static int CheckBundleName(const std::string &bundleName)
1435{
1436    if (bundleName.empty() || bundleName.size() > APP_LEN_BUNDLE_NAME) {
1437        return -1;
1438    }
1439    if (bundleName.find('\\') != std::string::npos || bundleName.find('/') != std::string::npos) {
1440        return -1;
1441    }
1442    return 0;
1443}
1444
1445int32_t SandboxUtils::SetOverlayAppSandboxProperty(const AppSpawningCtx *appProperty,
1446                                                   string &sandboxPackagePath)
1447{
1448    int ret = 0;
1449    if (!CheckAppMsgFlagsSet(appProperty, APP_FLAGS_OVERLAY)) {
1450        return ret;
1451    }
1452
1453    string overlayInfo = GetExtraInfoByType(appProperty, OVERLAY_SOCKET_TYPE);
1454    set<string> mountedSrcSet;
1455    vector<string> splits = split(overlayInfo, g_overlayDecollator);
1456    string sandboxOverlayPath = sandboxPackagePath + g_overlayPath;
1457    for (auto hapPath : splits) {
1458        size_t pathIndex = hapPath.find_last_of(g_fileSeparator);
1459        if (pathIndex == string::npos) {
1460            continue;
1461        }
1462        std::string srcPath = hapPath.substr(0, pathIndex);
1463        if (mountedSrcSet.find(srcPath) != mountedSrcSet.end()) {
1464            APPSPAWN_LOGV("%{public}s have mounted before, no need to mount twice.", srcPath.c_str());
1465            continue;
1466        }
1467
1468        auto bundleNameIndex = srcPath.find_last_of(g_fileSeparator);
1469        string destPath = sandboxOverlayPath + srcPath.substr(bundleNameIndex + 1, srcPath.length());
1470        int32_t retMount = DoAppSandboxMountOnce(srcPath.c_str(), destPath.c_str(),
1471                                                 nullptr, BASIC_MOUNT_FLAGS, nullptr);
1472        if (retMount != 0) {
1473            APPSPAWN_LOGE("fail to mount overlay path, src is %{public}s.", hapPath.c_str());
1474            ret = retMount;
1475        }
1476
1477        mountedSrcSet.emplace(srcPath);
1478    }
1479    return ret;
1480}
1481
1482int32_t SandboxUtils::SetBundleResourceAppSandboxProperty(const AppSpawningCtx *appProperty,
1483                                                          string &sandboxPackagePath)
1484{
1485    int ret = 0;
1486    if (!CheckAppMsgFlagsSet(appProperty, APP_FLAGS_BUNDLE_RESOURCES)) {
1487        return ret;
1488    }
1489
1490    string srcPath = g_bundleResourceSrcPath;
1491    string destPath = sandboxPackagePath + g_bundleResourceDestPath;
1492    ret = DoAppSandboxMountOnce(
1493        srcPath.c_str(), destPath.c_str(), nullptr, BASIC_MOUNT_FLAGS, nullptr);
1494    return ret;
1495}
1496
1497int32_t SandboxUtils::CheckAppFullMountEnable()
1498{
1499    if (deviceTypeEnable_ != -1) {
1500        return deviceTypeEnable_;
1501    }
1502
1503    char value[] = "false";
1504    int32_t ret = GetParameter("const.filemanager.full_mount.enable", "false", value, sizeof(value));
1505    if (ret > 0 && (strcmp(value, "true")) == 0) {
1506        deviceTypeEnable_ = FILE_CROSS_APP_STATUS;
1507    } else if (ret > 0 && (strcmp(value, "false")) == 0) {
1508        deviceTypeEnable_ = FILE_ACCESS_COMMON_DIR_STATUS;
1509    } else {
1510        deviceTypeEnable_ = -1;
1511    }
1512
1513    return deviceTypeEnable_;
1514}
1515
1516int32_t SandboxUtils::SetSandboxProperty(AppSpawningCtx *appProperty, std::string &sandboxPackagePath)
1517{
1518    int32_t ret = 0;
1519    const std::string bundleName = GetBundleName(appProperty);
1520    ret = SetCommonAppSandboxProperty(appProperty, sandboxPackagePath);
1521    APPSPAWN_CHECK(ret == 0, return ret, "SetCommonAppSandboxProperty failed, packagename is %{public}s",
1522                   bundleName.c_str());
1523    if (CheckBundleNameForPrivate(bundleName)) {
1524        ret = SetPrivateAppSandboxProperty(appProperty);
1525        APPSPAWN_CHECK(ret == 0, return ret, "SetPrivateAppSandboxProperty failed, packagename is %{public}s",
1526                       bundleName.c_str());
1527    }
1528    ret = SetPermissionAppSandboxProperty(appProperty);
1529    APPSPAWN_CHECK(ret == 0, return ret, "SetPermissionAppSandboxProperty failed, packagename is %{public}s",
1530                   bundleName.c_str());
1531
1532    ret = SetOverlayAppSandboxProperty(appProperty, sandboxPackagePath);
1533    APPSPAWN_CHECK(ret == 0, return ret, "SetOverlayAppSandboxProperty failed, packagename is %{public}s",
1534                   bundleName.c_str());
1535
1536    ret = SetBundleResourceAppSandboxProperty(appProperty, sandboxPackagePath);
1537    APPSPAWN_CHECK(ret == 0, return ret, "SetBundleResourceAppSandboxProperty failed, packagename is %{public}s",
1538                   bundleName.c_str());
1539    APPSPAWN_LOGI("Set appsandbox property success");
1540    return ret;
1541}
1542
1543int32_t SandboxUtils::ChangeCurrentDir(std::string &sandboxPackagePath, const std::string &bundleName,
1544                                       bool sandboxSharedStatus)
1545{
1546    int32_t ret = 0;
1547    ret = chdir(sandboxPackagePath.c_str());
1548    APPSPAWN_CHECK(ret == 0, return ret, "chdir failed, packagename is %{public}s, path is %{public}s",
1549        bundleName.c_str(), sandboxPackagePath.c_str());
1550
1551    if (sandboxSharedStatus) {
1552        ret = chroot(sandboxPackagePath.c_str());
1553        APPSPAWN_CHECK(ret == 0, return ret, "chroot failed, path is %{public}s errno is %{public}d",
1554            sandboxPackagePath.c_str(), errno);
1555        return ret;
1556    }
1557
1558    ret = syscall(SYS_pivot_root, sandboxPackagePath.c_str(), sandboxPackagePath.c_str());
1559    APPSPAWN_CHECK(ret == 0, return ret, "errno is %{public}d, pivot root failed, packagename is %{public}s",
1560        errno, bundleName.c_str());
1561
1562    ret = umount2(".", MNT_DETACH);
1563    APPSPAWN_CHECK(ret == 0, return ret, "MNT_DETACH failed, packagename is %{public}s", bundleName.c_str());
1564    return ret;
1565}
1566
1567static inline int EnableSandboxNamespace(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags)
1568{
1569    int rc = unshare(sandboxNsFlags);
1570    APPSPAWN_CHECK(rc == 0, return rc, "unshare failed, packagename is %{public}s", GetBundleName(appProperty));
1571
1572    if ((sandboxNsFlags & CLONE_NEWNET) == CLONE_NEWNET) {
1573        rc = EnableNewNetNamespace();
1574        APPSPAWN_CHECK(rc == 0, return rc, "Set new netnamespace failed %{public}s", GetBundleName(appProperty));
1575    }
1576    return 0;
1577}
1578
1579int32_t SandboxUtils::SetPermissionWithParam(AppSpawningCtx *appProperty)
1580{
1581    int32_t index = 0;
1582    int32_t appFullMountStatus = CheckAppFullMountEnable();
1583    if (appFullMountStatus == FILE_CROSS_APP_STATUS) {
1584        index = GetPermissionIndex(nullptr, FILE_CROSS_APP_MODE.c_str());
1585    } else if (appFullMountStatus == FILE_ACCESS_COMMON_DIR_STATUS) {
1586        index = GetPermissionIndex(nullptr, FILE_ACCESS_COMMON_DIR_MODE.c_str());
1587    }
1588
1589    int32_t fileMgrIndex = GetPermissionIndex(nullptr, FILE_ACCESS_MANAGER_MODE.c_str());
1590    if (index > 0 && fileMgrIndex > 0 &&
1591        (CheckAppPermissionFlagSet(appProperty, static_cast<uint32_t>(fileMgrIndex)) == 0)) {
1592        return SetAppPermissionFlags(appProperty, index);
1593    }
1594    return -1;
1595}
1596
1597#ifdef APPSPAWN_MOUNT_TMPSHM
1598void SandboxUtils::MountDevShmPath(std::string &sandboxPath)
1599{
1600    std::string sandboxDevShmPath = sandboxPath + DEV_SHM_DIR;
1601    int result = mount("tmpfs", sandboxDevShmPath.c_str(), "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV, "size=32M");
1602    if (result != 0) {
1603        APPSPAWN_LOGW("Error mounting %{public}s to tmpfs, errno %{public}d", sandboxDevShmPath.c_str(), errno);
1604    }
1605}
1606#endif
1607
1608int32_t SandboxUtils::SetAppSandboxProperty(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags)
1609{
1610    APPSPAWN_CHECK(appProperty != nullptr, return -1, "Invalid appspwn client");
1611    if (CheckBundleName(GetBundleName(appProperty)) != 0) {
1612        return -1;
1613    }
1614    AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO));
1615    if (dacInfo == nullptr) {
1616        return -1;
1617    }
1618
1619    std::string sandboxPackagePath = g_sandBoxRootDir + to_string(dacInfo->uid / UID_BASE) + "/";
1620    const std::string bundleName = GetBundleName(appProperty);
1621    bool sandboxSharedStatus = GetSandboxPrivateSharedStatus(bundleName, appProperty) ||
1622        (CheckAppPermissionFlagSet(appProperty, static_cast<uint32_t>(GetPermissionIndex(nullptr,
1623        ACCESS_DLP_FILE_MODE.c_str()))) != 0);
1624    sandboxPackagePath += CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? "isolated/" : "";
1625    sandboxPackagePath += bundleName;
1626    MakeDirRecursive(sandboxPackagePath.c_str(), FILE_MODE);
1627
1628    // add pid to a new mnt namespace
1629    int rc = EnableSandboxNamespace(appProperty, sandboxNsFlags);
1630    APPSPAWN_CHECK(rc == 0, return rc, "unshare failed, packagename is %{public}s", bundleName.c_str());
1631
1632    if (SetPermissionWithParam(appProperty) != 0) {
1633        APPSPAWN_LOGW("Set app permission flag fail.");
1634    }
1635
1636    // check app sandbox switch
1637    if ((CheckTotalSandboxSwitchStatus(appProperty) == false) ||
1638        (CheckAppSandboxSwitchStatus(appProperty) == false)) {
1639        rc = DoSandboxRootFolderCreateAdapt(sandboxPackagePath);
1640    } else if (!sandboxSharedStatus) {
1641        rc = DoSandboxRootFolderCreate(appProperty, sandboxPackagePath);
1642    }
1643    APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxRootFolderCreate failed, %{public}s", bundleName.c_str());
1644    rc = SetSandboxProperty(appProperty, sandboxPackagePath);
1645    APPSPAWN_CHECK(rc == 0, return rc, "SetSandboxProperty failed, %{public}s", bundleName.c_str());
1646
1647#ifdef APPSPAWN_MOUNT_TMPSHM
1648    MountDevShmPath(sandboxPackagePath);
1649#endif
1650
1651#ifndef APPSPAWN_TEST
1652    rc = ChangeCurrentDir(sandboxPackagePath, bundleName, sandboxSharedStatus);
1653    APPSPAWN_CHECK(rc == 0, return rc, "change current dir failed");
1654    APPSPAWN_LOGI("Change root dir success");
1655#if defined(APPSPAWN_MOUNT_TMPSHM) && defined(WITH_SELINUX)
1656    Restorecon(DEV_SHM_DIR);
1657#endif // APPSPAWN_MOUNT_TMPSHM && WITH_SELINUX
1658#endif // APPSPAWN_TEST
1659    return 0;
1660}
1661
1662int32_t SandboxUtils::SetAppSandboxPropertyNweb(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags)
1663{
1664    APPSPAWN_CHECK(appProperty != nullptr, return -1, "Invalid appspwn client");
1665    if (CheckBundleName(GetBundleName(appProperty)) != 0) {
1666        return -1;
1667    }
1668    std::string sandboxPackagePath = g_sandBoxRootDirNweb;
1669    const std::string bundleName = GetBundleName(appProperty);
1670    bool sandboxSharedStatus = GetSandboxPrivateSharedStatus(bundleName, appProperty);
1671    sandboxPackagePath += bundleName;
1672    MakeDirRecursive(sandboxPackagePath.c_str(), FILE_MODE);
1673
1674    // add pid to a new mnt namespace
1675    int rc = EnableSandboxNamespace(appProperty, sandboxNsFlags);
1676    APPSPAWN_CHECK(rc == 0, return rc, "unshare failed, packagename is %{public}s", bundleName.c_str());
1677
1678    // check app sandbox switch
1679    if ((CheckTotalSandboxSwitchStatus(appProperty) == false) ||
1680        (CheckAppSandboxSwitchStatus(appProperty) == false)) {
1681        rc = DoSandboxRootFolderCreateAdapt(sandboxPackagePath);
1682    } else if (!sandboxSharedStatus) {
1683        rc = DoSandboxRootFolderCreate(appProperty, sandboxPackagePath);
1684    }
1685    APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxRootFolderCreate failed, %{public}s", bundleName.c_str());
1686    // rendering process can be created by different apps,
1687    // and the bundle names of these apps are different,
1688    // so we can't use the method SetPrivateAppSandboxProperty
1689    // which mount dirs by using bundle name.
1690    rc = SetRenderSandboxPropertyNweb(appProperty, sandboxPackagePath);
1691    APPSPAWN_CHECK(rc == 0, return rc, "SetRenderSandboxPropertyNweb failed, packagename is %{public}s",
1692        sandboxPackagePath.c_str());
1693
1694    rc = SetOverlayAppSandboxProperty(appProperty, sandboxPackagePath);
1695    APPSPAWN_CHECK(rc == 0, return rc, "SetOverlayAppSandboxProperty failed, packagename is %{public}s",
1696        bundleName.c_str());
1697
1698    rc = SetBundleResourceAppSandboxProperty(appProperty, sandboxPackagePath);
1699    APPSPAWN_CHECK(rc == 0, return rc, "SetBundleResourceAppSandboxProperty failed, packagename is %{public}s",
1700        bundleName.c_str());
1701
1702#ifndef APPSPAWN_TEST
1703    rc = chdir(sandboxPackagePath.c_str());
1704    APPSPAWN_CHECK(rc == 0, return rc, "chdir failed, packagename is %{public}s, path is %{public}s",
1705        bundleName.c_str(), sandboxPackagePath.c_str());
1706
1707    if (sandboxSharedStatus) {
1708        rc = chroot(sandboxPackagePath.c_str());
1709        APPSPAWN_CHECK(rc == 0, return rc, "chroot failed, path is %{public}s errno is %{public}d",
1710            sandboxPackagePath.c_str(), errno);
1711        return 0;
1712    }
1713
1714    rc = syscall(SYS_pivot_root, sandboxPackagePath.c_str(), sandboxPackagePath.c_str());
1715    APPSPAWN_CHECK(rc == 0, return rc, "errno is %{public}d, pivot root failed, packagename is %{public}s",
1716        errno, bundleName.c_str());
1717
1718    rc = umount2(".", MNT_DETACH);
1719    APPSPAWN_CHECK(rc == 0, return rc, "MNT_DETACH failed, packagename is %{public}s", bundleName.c_str());
1720#endif
1721    return 0;
1722}
1723} // namespace AppSpawn
1724} // namespace OHOS
1725
1726static bool AppSandboxPidNsIsSupport(void)
1727{
1728    char buffer[10] = {0};
1729    uint32_t buffSize = sizeof(buffer);
1730
1731    if (SystemGetParameter("const.sandbox.pidns.support", buffer, &buffSize) != 0) {
1732        return true;
1733    }
1734    if (!strcmp(buffer, "false")) {
1735        return false;
1736    }
1737    return true;
1738}
1739
1740int LoadAppSandboxConfig(AppSpawnMgr *content)
1741{
1742    bool rc = true;
1743    // load sandbox config
1744    nlohmann::json appSandboxConfig;
1745    CfgFiles *files = GetCfgFiles("etc/sandbox");
1746    for (int i = 0; (files != nullptr) && (i < MAX_CFG_POLICY_DIRS_CNT); ++i) {
1747        if (files->paths[i] == nullptr) {
1748            continue;
1749        }
1750        std::string path = files->paths[i];
1751        std::string appPath = path + OHOS::AppSpawn::APP_JSON_CONFIG;
1752        APPSPAWN_LOGI("LoadAppSandboxConfig %{public}s", appPath.c_str());
1753        rc = OHOS::AppSpawn::JsonUtils::GetJsonObjFromJson(appSandboxConfig, appPath);
1754        APPSPAWN_CHECK(rc, continue, "Failed to load app data sandbox config %{public}s", appPath.c_str());
1755        OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(appSandboxConfig, SANBOX_APP_JSON_CONFIG);
1756
1757        std::string isolatedPath = path + OHOS::AppSpawn::APP_ISOLATED_JSON_CONFIG;
1758        APPSPAWN_LOGI("LoadAppSandboxConfig %{public}s", isolatedPath.c_str());
1759        rc = OHOS::AppSpawn::JsonUtils::GetJsonObjFromJson(appSandboxConfig, isolatedPath);
1760        APPSPAWN_CHECK(rc, continue, "Failed to load app data sandbox config %{public}s", isolatedPath.c_str());
1761        OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(appSandboxConfig, SANBOX_ISOLATED_JSON_CONFIG);
1762    }
1763    FreeCfgFiles(files);
1764    bool isNweb = IsNWebSpawnMode(content);
1765    if (!isNweb && !AppSandboxPidNsIsSupport()) {
1766        return 0;
1767    }
1768    content->content.sandboxNsFlags = OHOS::AppSpawn::SandboxUtils::GetSandboxNsFlags(isNweb);
1769    return 0;
1770}
1771
1772int32_t SetAppSandboxProperty(AppSpawnMgr *content, AppSpawningCtx *property)
1773{
1774    APPSPAWN_CHECK(property != nullptr, return -1, "Invalid appspwn client");
1775    APPSPAWN_CHECK(content != nullptr, return -1, "Invalid appspwn content");
1776    int ret = 0;
1777    // no sandbox
1778    if (CheckAppMsgFlagsSet(property, APP_FLAGS_NO_SANDBOX)) {
1779        return 0;
1780    }
1781    if ((content->content.sandboxNsFlags & CLONE_NEWPID) == CLONE_NEWPID) {
1782        ret = getprocpid();
1783        if (ret < 0) {
1784            return ret;
1785        }
1786    }
1787    uint32_t sandboxNsFlags = CLONE_NEWNS;
1788    if ((CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX) && !IsDeveloperModeOpen()) ||
1789        CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_NETWORK)) {
1790        sandboxNsFlags |= content->content.sandboxNsFlags & CLONE_NEWNET ? CLONE_NEWNET : 0;
1791    }
1792    APPSPAWN_LOGV("SetAppSandboxProperty sandboxNsFlags 0x%{public}x", sandboxNsFlags);
1793
1794    if (IsNWebSpawnMode(content)) {
1795        ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxPropertyNweb(property, sandboxNsFlags);
1796    } else {
1797        ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(property, sandboxNsFlags);
1798    }
1799    // for module test do not create sandbox, use APP_FLAGS_IGNORE_SANDBOX to ignore sandbox result
1800    if (CheckAppMsgFlagsSet(property, APP_FLAGS_IGNORE_SANDBOX)) {
1801        APPSPAWN_LOGW("Do not care sandbox result %{public}d", ret);
1802        return 0;
1803    }
1804    return ret;
1805}
1806
1807#define USER_ID_SIZE 16
1808#define DIR_MODE 0711
1809
1810#ifndef APPSPAWN_SANDBOX_NEW
1811static bool IsUnlockStatus(uint32_t uid, const char *bundleName, size_t bundleNameLen)
1812{
1813    const int userIdBase = 200000;
1814    uid = uid / userIdBase;
1815    if (uid == 0) {
1816        return true;
1817    }
1818
1819    const char rootPath[] = "/data/app/el2/";
1820    const char basePath[] = "/base/";
1821    size_t allPathSize = strlen(rootPath) + strlen(basePath) + 1 + USER_ID_SIZE + bundleNameLen;
1822    char *path = reinterpret_cast<char *>(malloc(sizeof(char) * allPathSize));
1823    APPSPAWN_CHECK(path != NULL, return true, "Failed to malloc path");
1824    int len = sprintf_s(path, allPathSize, "%s%u%s%s", rootPath, uid, basePath, bundleName);
1825    APPSPAWN_CHECK(len > 0 && ((size_t)len < allPathSize), free(path);
1826        return true, "Failed to get base path");
1827
1828    if (access(path, F_OK) == 0) {
1829        APPSPAWN_LOGI("this is unlock status");
1830        free(path);
1831        return true;
1832    }
1833    free(path);
1834    APPSPAWN_LOGI("this is lock status");
1835    return false;
1836}
1837
1838static void MountDir(const AppSpawningCtx *property, const char *rootPath, const char *srcPath, const char *targetPath)
1839{
1840    const int userIdBase = 200000;
1841    AppDacInfo *info = reinterpret_cast<AppDacInfo *>(GetAppProperty(property, TLV_DAC_INFO));
1842    const char *bundleName = GetBundleName(property);
1843    if (info == NULL || bundleName == NULL) {
1844        return;
1845    }
1846
1847    size_t allPathSize = strlen(rootPath) + strlen(targetPath) + strlen(bundleName) + 2;
1848    allPathSize += USER_ID_SIZE;
1849    char *path = reinterpret_cast<char *>(malloc(sizeof(char) * (allPathSize)));
1850    APPSPAWN_CHECK(path != NULL, return, "Failed to malloc path");
1851    int len = sprintf_s(path, allPathSize, "%s%u/%s%s", rootPath, info->uid / userIdBase, bundleName, targetPath);
1852    APPSPAWN_CHECK(len > 0 && ((size_t)len < allPathSize), free(path);
1853        return, "Failed to get sandbox path");
1854
1855    if (access(path, F_OK) == 0 && srcPath == nullptr) {
1856        free(path);
1857        return;
1858    }
1859
1860    MakeDirRec(path, DIR_MODE, 1);
1861    const char *sourcePath = (srcPath == nullptr) ? path : srcPath;
1862    if (srcPath != nullptr) {
1863        int ret = umount2(path, MNT_DETACH);
1864        APPSPAWN_CHECK_ONLY_LOG(ret == 0, "Failed to umount path %{public}s, errno %{public}d", path, errno);
1865    }
1866
1867    if (mount(sourcePath, path, nullptr, MS_BIND | MS_REC, nullptr) != 0) {
1868        APPSPAWN_LOGI("bind mount %{public}s to %{public}s failed, error %{public}d", sourcePath, path, errno);
1869        free(path);
1870        return;
1871    }
1872    if (mount(nullptr, path, nullptr, MS_SHARED, nullptr) != 0) {
1873        APPSPAWN_LOGI("mount path %{public}s to shared failed, errno %{public}d", path, errno);
1874        free(path);
1875        return;
1876    }
1877    APPSPAWN_LOGI("mount path %{public}s to shared success", path);
1878    free(path);
1879    return;
1880}
1881
1882static const MountSharedTemplate MOUNT_SHARED_MAP[] = {
1883    {"/data/storage/el2", nullptr},
1884    {"/data/storage/el3", nullptr},
1885    {"/data/storage/el4", nullptr},
1886    {"/data/storage/el5", "ohos.permission.PROTECT_SCREEN_LOCK_DATA"},
1887    {"/storage/Users", "ohos.permission.FILE_ACCESS_MANAGER"},
1888};
1889
1890static void MountDirToShared(const AppSpawningCtx *property)
1891{
1892    const char rootPath[] = "/mnt/sandbox/";
1893    const char el1Path[] = "/data/storage/el1/bundle";
1894    const char lockSuffix[] = "_locked";
1895    AppDacInfo *info = reinterpret_cast<AppDacInfo *>(GetAppProperty(property, TLV_DAC_INFO));
1896    const char *bundleName = GetBundleName(property);
1897    if (info == NULL || bundleName == NULL) {
1898        return;
1899    }
1900
1901    string sourcePath = "/data/app/el1/bundle/public/" + string(bundleName);
1902    MountDir(property, rootPath, sourcePath.c_str(), el1Path);
1903    size_t bundleNameLen = strlen(bundleName);
1904    if (IsUnlockStatus(info->uid, bundleName, bundleNameLen)) {
1905        return;
1906    }
1907
1908    int length = sizeof(MOUNT_SHARED_MAP) / sizeof(MOUNT_SHARED_MAP[0]);
1909    for (int i = 0; i < length; i++) {
1910        if (MOUNT_SHARED_MAP[i].permission == nullptr) {
1911            MountDir(property, rootPath, nullptr, MOUNT_SHARED_MAP[i].sandboxPath);
1912        } else {
1913            int index = GetPermissionIndex(nullptr, MOUNT_SHARED_MAP[i].permission);
1914            APPSPAWN_LOGV("mount dir on lock mountPermissionFlags %{public}d", index);
1915            if (CheckAppPermissionFlagSet(property, static_cast<uint32_t>(index))) {
1916                MountDir(property, rootPath, nullptr, MOUNT_SHARED_MAP[i].sandboxPath);
1917            }
1918        }
1919    }
1920
1921    std::string lockSbxPathStamp = rootPath + to_string(info->uid / UID_BASE) + "/";
1922    lockSbxPathStamp += CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? "isolated/" : "";
1923    lockSbxPathStamp += bundleName;
1924    lockSbxPathStamp += lockSuffix;
1925    OHOS::AppSpawn::MakeDirRecursive(lockSbxPathStamp.c_str(), OHOS::AppSpawn::FILE_MODE);
1926}
1927#endif
1928
1929static int SpawnMountDirToShared(AppSpawnMgr *content, AppSpawningCtx *property)
1930{
1931#ifndef APPSPAWN_SANDBOX_NEW
1932    // mount dynamic directory
1933    MountDirToShared(property);
1934#endif
1935    return 0;
1936}
1937
1938#ifndef APPSPAWN_SANDBOX_NEW
1939MODULE_CONSTRUCTOR(void)
1940{
1941    APPSPAWN_LOGV("Load sandbox module ...");
1942    (void)AddServerStageHook(STAGE_SERVER_PRELOAD, HOOK_PRIO_SANDBOX, LoadAppSandboxConfig);
1943    (void)AddAppSpawnHook(STAGE_PARENT_PRE_FORK, HOOK_PRIO_COMMON, SpawnMountDirToShared);
1944    (void)AddAppSpawnHook(STAGE_CHILD_EXECUTE, HOOK_PRIO_SANDBOX, SetAppSandboxProperty);
1945}
1946#endif
1947