• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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_common.h"
17 
18 #include <sys/stat.h>
19 #include <fcntl.h>
20 #include <fstream>
21 #include <fcntl.h>
22 #include <sstream>
23 #include <cerrno>
24 #include "appspawn_manager.h"
25 #include "appspawn_utils.h"
26 #include "sandbox_def.h"
27 #include "parameters.h"
28 #include "init_param.h"
29 #include "init_utils.h"
30 #include "parameter.h"
31 #include "config_policy_utils.h"
32 
33 #ifdef WITH_SELINUX
34 #include "hap_restorecon.h"
35 #ifdef APPSPAWN_MOUNT_TMPSHM
36 #include "policycoreutils.h"
37 #endif // APPSPAWN_MOUNT_TMPSHM
38 #endif // WITH_SELINUX
39 
40 namespace OHOS {
41 namespace AppSpawn {
42 
43 int32_t SandboxCommon::deviceTypeEnable_ = -1;
44 std::map<SandboxCommonDef::SandboxConfigType, std::vector<cJSON *>> SandboxCommon::appSandboxCJsonConfig_ = {};
45 
46 // 加载配置文件
GetSandboxNsFlags(bool isNweb)47 uint32_t SandboxCommon::GetSandboxNsFlags(bool isNweb)
48 {
49     uint32_t nsFlags = 0;
50     if (!IsTotalSandboxEnabled(nullptr)) {
51         return nsFlags;
52     }
53 
54     const std::map<std::string, uint32_t> NamespaceFlagsMap = { {"pid", CLONE_NEWPID},
55                                                                 {"net", CLONE_NEWNET} };
56     const char *prefixStr =
57         isNweb ? SandboxCommonDef::g_privatePrefix : SandboxCommonDef::g_commonPrefix;
58     const char *baseStr = isNweb ? SandboxCommonDef::g_ohosRender.c_str() : SandboxCommonDef::g_appBase;
59 
60     auto processor = [&baseStr, &NamespaceFlagsMap, &nsFlags](cJSON *item) {
61         cJSON *internal = cJSON_GetObjectItemCaseSensitive(item, baseStr);
62         if (!internal || !cJSON_IsArray(internal)) {
63             return 0;
64         }
65 
66         // 获取数组中第一个元素
67         cJSON *firstElem = cJSON_GetArrayItem(internal, 0);
68         if (!firstElem) {
69             return 0;
70         }
71 
72         // 获取 "sandbox-ns-flags" 数组
73         cJSON *nsFlagsJson = cJSON_GetObjectItemCaseSensitive(firstElem, SandboxCommonDef::g_sandBoxNsFlags);
74         if (!nsFlagsJson || !cJSON_IsArray(nsFlagsJson)) {
75             return 0;
76         }
77         cJSON *nsIte = nullptr;
78         cJSON_ArrayForEach(nsIte, nsFlagsJson) {
79             const char *sandboxNs = cJSON_GetStringValue(nsIte);
80             if (sandboxNs == nullptr) {
81                 continue;
82             }
83             std::string sandboxNsStr = sandboxNs;
84             if (!NamespaceFlagsMap.count(sandboxNsStr)) {
85                 continue;
86             }
87             nsFlags |= NamespaceFlagsMap.at(sandboxNsStr);
88         }
89         return 0;
90     };
91 
92     for (auto& config : GetCJsonConfig(SandboxCommonDef::SANDBOX_APP_JSON_CONFIG)) {
93         // 获取 "individual" 数组
94         cJSON *individual = cJSON_GetObjectItemCaseSensitive(config, prefixStr);
95         if (!individual || !cJSON_IsArray(individual)) {
96             return nsFlags;
97         }
98         (void)HandleArrayForeach(individual, processor);
99     }
100 
101     if (!nsFlags) {
102         APPSPAWN_LOGE("config is not found %{public}s ns config", isNweb ? "Nweb" : "App");
103     }
104     return nsFlags;
105 }
106 
AppSandboxPidNsIsSupport(void)107 bool SandboxCommon::AppSandboxPidNsIsSupport(void)
108 {
109     char buffer[10] = {0};
110     uint32_t buffSize = sizeof(buffer);
111 
112     if (SystemGetParameter("const.sandbox.pidns.support", buffer, &buffSize) != 0) {
113         return true;
114     }
115     if (!strcmp(buffer, "false")) {
116         return false;
117     }
118     return true;
119 }
120 
StoreCJsonConfig(cJSON * root,SandboxCommonDef::SandboxConfigType type)121 void SandboxCommon::StoreCJsonConfig(cJSON *root, SandboxCommonDef::SandboxConfigType type)
122 {
123     appSandboxCJsonConfig_[type].push_back(root);
124 }
125 
HandleArrayForeach(cJSON * arrayJson,ArrayItemProcessor processor)126 int32_t SandboxCommon::HandleArrayForeach(cJSON *arrayJson, ArrayItemProcessor processor)
127 {
128     if (!arrayJson || !cJSON_IsArray(arrayJson) || !processor) {
129         return APPSPAWN_ERROR_UTILS_DECODE_JSON_FAIL;
130     }
131 
132     int ret = 0;
133     cJSON *item;
134     cJSON_ArrayForEach(item, arrayJson) {
135         ret = processor(item);
136         if (ret != 0) {
137             return ret;
138         }
139     }
140     return ret;
141 }
142 
LoadAppSandboxConfigCJson(AppSpawnMgr * content)143 int SandboxCommon::LoadAppSandboxConfigCJson(AppSpawnMgr *content)
144 {
145     // load sandbox config
146     cJSON *sandboxCJsonRoot;
147     CfgFiles *files = GetCfgFiles("etc/sandbox");
148     for (int i = 0; (files != nullptr) && (i < MAX_CFG_POLICY_DIRS_CNT); ++i) {
149         if (files->paths[i] == nullptr) {
150             continue;
151         }
152         std::string path = files->paths[i];
153         std::string appPath = path + SandboxCommonDef::APP_JSON_CONFIG;
154         APPSPAWN_LOGI("LoadAppSandboxConfig %{public}s", appPath.c_str());
155         sandboxCJsonRoot = GetJsonObjFromFile(appPath.c_str());
156         APPSPAWN_CHECK((sandboxCJsonRoot != nullptr && cJSON_IsObject(sandboxCJsonRoot)), continue,
157                        "Failed to load app data sandbox config %{public}s", appPath.c_str());
158         StoreCJsonConfig(sandboxCJsonRoot, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG);
159 
160         std::string isolatedPath = path + SandboxCommonDef::APP_ISOLATED_JSON_CONFIG;
161         APPSPAWN_LOGI("LoadAppSandboxConfig %{public}s", isolatedPath.c_str());
162         sandboxCJsonRoot = GetJsonObjFromFile(isolatedPath.c_str());
163         APPSPAWN_CHECK((sandboxCJsonRoot != nullptr && cJSON_IsObject(sandboxCJsonRoot)), continue,
164                        "Failed to load app data sandbox config %{public}s", isolatedPath.c_str());
165         StoreCJsonConfig(sandboxCJsonRoot, SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG);
166     }
167     FreeCfgFiles(files);
168 
169     bool isNweb = IsNWebSpawnMode(content);
170     if (!isNweb && !AppSandboxPidNsIsSupport()) {
171         return 0;
172     }
173     content->content.sandboxNsFlags = GetSandboxNsFlags(isNweb);
174     return 0;
175 }
176 
FreeAppSandboxConfigCJson(AppSpawnMgr * content)177 int SandboxCommon::FreeAppSandboxConfigCJson(AppSpawnMgr *content)
178 {
179     UNUSED(content);
180     std::vector<cJSON *> &normalJsonVec = GetCJsonConfig(SandboxCommonDef::SANDBOX_APP_JSON_CONFIG);
181     for (auto& normal : normalJsonVec) {
182         if (normal == nullptr) {
183             continue;
184         }
185         cJSON_Delete(normal);
186         normal = nullptr;
187     }
188     normalJsonVec.clear();
189 
190     std::vector<cJSON *> &isolatedJsonVec = GetCJsonConfig(SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG);
191     for (auto& isolated : isolatedJsonVec) {
192         if (isolated == nullptr) {
193             continue;
194         }
195         cJSON_Delete(isolated);
196         isolated = nullptr;
197     }
198     isolatedJsonVec.clear();
199     return 0;
200 }
201 
GetCJsonConfig(SandboxCommonDef::SandboxConfigType type)202 std::vector<cJSON *> &SandboxCommon::GetCJsonConfig(SandboxCommonDef::SandboxConfigType type)
203 {
204     return appSandboxCJsonConfig_[type];
205 }
206 
207 // 获取应用信息
GetExtraInfoByType(const AppSpawningCtx * appProperty,const std::string & type)208 std::string SandboxCommon::GetExtraInfoByType(const AppSpawningCtx *appProperty, const std::string &type)
209 {
210     uint32_t len = 0;
211     char *info = reinterpret_cast<char *>(GetAppPropertyExt(appProperty, type.c_str(), &len));
212     if (info == nullptr) {
213         return "";
214     }
215     return std::string(info, len);
216 }
217 
GetSandboxRootPath(const AppSpawningCtx * appProperty,cJSON * config)218 std::string SandboxCommon::GetSandboxRootPath(const AppSpawningCtx *appProperty, cJSON *config)
219 {
220     AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO));
221     if (dacInfo == nullptr) {
222         return "";
223     }
224 
225     std::string sandboxRoot = "";
226     std::string isolatedFlagText = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? "isolated/" : "";
227     AppSpawnMsgBundleInfo *bundleInfo =
228         reinterpret_cast<AppSpawnMsgBundleInfo *>(GetAppProperty(appProperty, TLV_BUNDLE_INFO));
229     if (bundleInfo == nullptr) {
230         return "";
231     }
232     std::string tmpBundlePath = bundleInfo->bundleName;
233     std::ostringstream variablePackageName;
234     if (CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_CLONE_ENABLE)) {
235         variablePackageName << "+clone-" << bundleInfo->bundleIndex << "+" << bundleInfo->bundleName;
236         tmpBundlePath = variablePackageName.str();
237     }
238     const std::string variableSandboxRoot = SandboxCommonDef::g_sandBoxRootDir +
239         std::to_string(dacInfo->uid / UID_BASE) + "/" + isolatedFlagText.c_str() + tmpBundlePath;
240 
241     APPSPAWN_CHECK_ONLY_EXPER(config != nullptr, sandboxRoot = variableSandboxRoot;
242         return sandboxRoot);
243     const char *sandboxRootChr = GetStringFromJsonObj(config, SandboxCommonDef::g_sandboxRootPrefix);
244     if (sandboxRootChr != nullptr) {
245         sandboxRoot = sandboxRootChr;
246         if (sandboxRoot == SandboxCommonDef::g_originSandboxPath ||
247             sandboxRoot == SandboxCommonDef::g_sandboxRootPathTemplate) {
248             sandboxRoot = variableSandboxRoot;
249         } else {
250             sandboxRoot = ConvertToRealPath(appProperty, sandboxRoot);
251             APPSPAWN_LOGV("set sandbox-root name is %{public}s", sandboxRoot.c_str());
252         }
253     } else {
254         sandboxRoot = variableSandboxRoot;
255         APPSPAWN_LOGV("set sandbox-root to default rootapp name is %{public}s", GetBundleName(appProperty));
256     }
257 
258     return sandboxRoot;
259 }
260 
CreateDirRecursive(const std::string & path,mode_t mode)261 int SandboxCommon::CreateDirRecursive(const std::string &path, mode_t mode)
262 {
263     return MakeDirRec(path.c_str(), mode, 1);
264 }
265 
CreateDirRecursiveWithClock(const std::string & path,mode_t mode)266 void SandboxCommon::CreateDirRecursiveWithClock(const std::string &path, mode_t mode)
267 {
268     size_t size = path.size();
269     if (size == 0) {
270         return;
271     }
272 #ifdef APPSPAWN_HISYSEVENT
273     struct timespec startClock = {0};
274     clock_gettime(CLOCK_MONOTONIC, &startClock);
275 #endif
276     size_t index = 0;
277     do {
278         size_t pathIndex = path.find_first_of('/', index);
279         index = pathIndex == std::string::npos ? size : pathIndex + 1;
280         std::string dir = path.substr(0, index);
281 #ifndef APPSPAWN_TEST
282         APPSPAWN_CHECK(!(access(dir.c_str(), F_OK) < 0 && mkdir(dir.c_str(), mode) < 0),
283                        return, "errno is %{public}d, mkdir %{public}s failed", errno, dir.c_str());
284 #endif
285     } while (index < size);
286 
287 #ifdef APPSPAWN_HISYSEVENT
288     struct timespec endClock = {0};
289     clock_gettime(CLOCK_MONOTONIC, &endClock);
290     uint64_t diff = DiffTime(&startClock, &endClock);
291 
292     APPSPAWN_CHECK_ONLY_EXPER(diff < FUNC_REPORT_DURATION,
293                               ReportAbnormalDuration("MakeDirRecursive", diff));
294 #endif
295 }
296 
VerifyDirRecursive(const std::string & path)297 bool SandboxCommon::VerifyDirRecursive(const std::string &path)
298 {
299     size_t size = path.size();
300     if (size == 0) {
301         return false;
302     }
303     size_t index = 0;
304     do {
305         size_t pathIndex = path.find_first_of('/', index);
306         index = pathIndex == std::string::npos ? size : pathIndex + 1;
307         std::string dir = path.substr(0, index);
308 #ifndef APPSPAWN_TEST
309         APPSPAWN_CHECK_LOGW(access(dir.c_str(), F_OK) == 0,
310             return false, "check dir %{public}s failed, strerror: %{public}s", dir.c_str(), strerror(errno));
311 #endif
312     } while (index < size);
313     return true;
314 }
315 
CreateFileIfNotExist(const char * file)316 void SandboxCommon::CreateFileIfNotExist(const char *file)
317 {
318     if (access(file, F_OK) == 0) {
319         APPSPAWN_LOGI("file %{public}s already exist", file);
320         return;
321     }
322     std::string path = file;
323     auto pos = path.find_last_of('/');
324     APPSPAWN_CHECK(pos != std::string::npos, return, "file %{public}s error", file);
325     std::string dir = path.substr(0, pos);
326     (void)CreateDirRecursive(dir, SandboxCommonDef::FILE_MODE);
327     int fd = open(file, O_CREAT, SandboxCommonDef::FILE_MODE);
328     if (fd < 0) {
329         APPSPAWN_LOGW("failed create %{public}s, err=%{public}d", file, errno);
330     } else {
331         close(fd);
332     }
333     return;
334 }
335 
SetSandboxPathChmod(cJSON * jsonConfig,std::string & sandboxRoot)336 void SandboxCommon::SetSandboxPathChmod(cJSON *jsonConfig, std::string &sandboxRoot)
337 {
338     const std::map<std::string, mode_t> modeMap = {{"S_IRUSR", S_IRUSR}, {"S_IWUSR", S_IWUSR}, {"S_IXUSR", S_IXUSR},
339                                                    {"S_IRGRP", S_IRGRP}, {"S_IWGRP", S_IWGRP}, {"S_IXGRP", S_IXGRP},
340                                                    {"S_IROTH", S_IROTH}, {"S_IWOTH", S_IWOTH}, {"S_IXOTH", S_IXOTH},
341                                                    {"S_IRWXU", S_IRWXU}, {"S_IRWXG", S_IRWXG}, {"S_IRWXO", S_IRWXO}};
342     const char *fileMode = GetStringFromJsonObj(jsonConfig, SandboxCommonDef::g_destMode);
343     if (fileMode == nullptr) {
344         return;
345     }
346 
347     mode_t mode = 0;
348     std::string fileModeStr = fileMode;
349     std::vector<std::string> modeVec = SplitString(fileModeStr, "|");
350     for (unsigned int i = 0; i < modeVec.size(); i++) {
351         if (modeMap.count(modeVec[i])) {
352             mode |= modeMap.at(modeVec[i]);
353         }
354     }
355 
356     chmod(sandboxRoot.c_str(), mode);
357 }
358 
359 // 获取挂载配置参数信息
GetMountFlagsFromConfig(const std::vector<std::string> & vec)360 unsigned long SandboxCommon::GetMountFlagsFromConfig(const std::vector<std::string> &vec)
361 {
362     const std::map<std::string, mode_t> MountFlagsMap = { {"rec", MS_REC}, {"MS_REC", MS_REC},
363                                                           {"bind", MS_BIND}, {"MS_BIND", MS_BIND},
364                                                           {"move", MS_MOVE}, {"MS_MOVE", MS_MOVE},
365                                                           {"slave", MS_SLAVE}, {"MS_SLAVE", MS_SLAVE},
366                                                           {"rdonly", MS_RDONLY}, {"MS_RDONLY", MS_RDONLY},
367                                                           {"shared", MS_SHARED}, {"MS_SHARED", MS_SHARED},
368                                                           {"unbindable", MS_UNBINDABLE},
369                                                           {"MS_UNBINDABLE", MS_UNBINDABLE},
370                                                           {"remount", MS_REMOUNT}, {"MS_REMOUNT", MS_REMOUNT},
371                                                           {"nosuid", MS_NOSUID}, {"MS_NOSUID", MS_NOSUID},
372                                                           {"nodev", MS_NODEV}, {"MS_NODEV", MS_NODEV},
373                                                           {"noexec", MS_NOEXEC}, {"MS_NOEXEC", MS_NOEXEC},
374                                                           {"noatime", MS_NOATIME}, {"MS_NOATIME", MS_NOATIME},
375                                                           {"lazytime", MS_LAZYTIME}, {"MS_LAZYTIME", MS_LAZYTIME}};
376 
377     unsigned long mountFlags = 0;
378     for (unsigned int i = 0; i < vec.size(); i++) {
379         if (MountFlagsMap.count(vec[i])) {
380             mountFlags |= MountFlagsMap.at(vec[i]);
381         }
382     }
383     return mountFlags;
384 }
385 
IsDacOverrideEnabled(cJSON * config)386 bool SandboxCommon::IsDacOverrideEnabled(cJSON *config) // GetSandboxDacOverrideEnable
387 {
388     return GetBoolValueFromJsonObj(config, SandboxCommonDef::g_dacOverrideSensitive, false);
389 }
390 
GetSwitchStatus(cJSON * config)391 bool SandboxCommon::GetSwitchStatus(cJSON *config) // GetSbxSwitchStatusByConfig
392 {
393     // if not find sandbox-switch node, default switch status is true
394     return GetBoolValueFromJsonObj(config, SandboxCommonDef::g_sandBoxSwitchPrefix, true);
395 }
396 
ConvertFlagStr(const std::string & flagStr)397 uint32_t SandboxCommon::ConvertFlagStr(const std::string &flagStr)
398 {
399     const std::map<std::string, int> flagsMap = {{"START_FLAGS_BACKUP", APP_FLAGS_BACKUP_EXTENSION},
400                                                  {"DLP_MANAGER", APP_FLAGS_DLP_MANAGER},
401                                                  {"DEVELOPER_MODE", APP_FLAGS_DEVELOPER_MODE},
402                                                  {"PREINSTALLED_HAP", APP_FLAGS_PRE_INSTALLED_HAP},
403                                                  {"CUSTOM_SANDBOX_HAP", APP_FLAGS_CUSTOM_SANDBOX},
404                                                  {"FILE_CROSS_APP", APP_FLAGS_FILE_CROSS_APP},
405                                                  {"FILE_ACCESS_COMMON_DIR", APP_FLAGS_FILE_ACCESS_COMMON_DIR}};
406 
407     if (flagsMap.count(flagStr)) {
408         return flagsMap.at(flagStr);
409     }
410     return 0;
411 }
412 
GetMountFlags(cJSON * config)413 unsigned long SandboxCommon::GetMountFlags(cJSON *config) // GetSandboxMountFlags
414 {
415     unsigned long mountFlags = SandboxCommonDef::BASIC_MOUNT_FLAGS;
416     std::vector<std::string> vec;
417     cJSON *customizedFlags = IsDacOverrideEnabled(config) ?
418         cJSON_GetObjectItemCaseSensitive(config, SandboxCommonDef::g_sandBoxFlagsCustomized) :
419         cJSON_GetObjectItemCaseSensitive(config, SandboxCommonDef::g_sandBoxFlags);
420 
421     if (!customizedFlags) {
422         customizedFlags = cJSON_GetObjectItemCaseSensitive(config, SandboxCommonDef::g_sandBoxFlags);
423     }
424     if (customizedFlags == nullptr || !cJSON_IsArray(customizedFlags)) {
425         return mountFlags;
426     }
427 
428     auto processor = [&vec](cJSON *item) {
429         const char *strItem = cJSON_GetStringValue(item);
430         if (strItem == nullptr) {
431             return -1;
432         }
433         vec.emplace_back(strItem);
434         return 0;
435     };
436 
437     if (HandleArrayForeach(customizedFlags, processor) != 0) {
438         return mountFlags;
439     }
440     return GetMountFlagsFromConfig(vec);
441 }
442 
GetFsType(cJSON * config)443 std::string SandboxCommon::GetFsType(cJSON *config) // GetSandboxFsType
444 {
445     std::string fsType = "";
446     const char *fsTypeChr = GetStringFromJsonObj(config, SandboxCommonDef::g_fsType);
447     if (fsTypeChr == nullptr) {
448         return fsType;
449     }
450     fsType = fsTypeChr;
451     return fsType;
452 }
453 
GetOptions(const AppSpawningCtx * appProperty,cJSON * config)454 std::string SandboxCommon::GetOptions(const AppSpawningCtx *appProperty, cJSON *config) // GetSandboxOptions
455 {
456     AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO));
457     if (dacInfo == nullptr) {
458         return "";
459     }
460 
461     std::string options = "";
462     const char *optionsChr = GetStringFromJsonObj(config, SandboxCommonDef::g_sandBoxOptions);
463     if (optionsChr == nullptr) {
464         return options;
465     }
466     options = optionsChr;
467     options += ",user_id=" + std::to_string(dacInfo->uid / UID_BASE);
468     return options;
469 }
470 
GetDecPath(const AppSpawningCtx * appProperty,cJSON * config)471 std::vector<std::string> SandboxCommon::GetDecPath(const AppSpawningCtx *appProperty, cJSON *config)
472 {
473     AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO));
474     if (dacInfo == nullptr) {
475         return {};
476     }
477 
478     std::vector<std::string> decPaths = {};
479     cJSON *decPathJson = cJSON_GetObjectItemCaseSensitive(config, SandboxCommonDef::g_sandBoxDecPath);
480     if (decPathJson == nullptr || !cJSON_IsArray(decPathJson)) {
481         return {};
482     }
483 
484     auto processor = [&appProperty, &decPaths](cJSON *item) {
485         const char *strItem = cJSON_GetStringValue(item);
486         if (strItem == nullptr) {
487             return -1;
488         }
489         std::string decPath = ConvertToRealPathWithPermission(appProperty, strItem);
490         decPaths.emplace_back(std::move(decPath));
491         return 0;
492     };
493     if (HandleArrayForeach(decPathJson, processor) != 0) {
494         return {};
495     }
496     return decPaths;
497 }
498 
IsCreateSandboxPathEnabled(cJSON * json,std::string srcPath)499 bool SandboxCommon::IsCreateSandboxPathEnabled(cJSON *json, std::string srcPath) // GetCreateSandboxPath
500 {
501     bool isRet = GetBoolValueFromJsonObj(json, SandboxCommonDef::CREATE_SANDBOX_PATH, false);
502     if (isRet && access(srcPath.c_str(), F_OK) != 0) {
503         return false;
504     }
505     return true;
506 }
507 
IsTotalSandboxEnabled(const AppSpawningCtx * appProperty)508 bool SandboxCommon::IsTotalSandboxEnabled(const AppSpawningCtx *appProperty) // CheckTotalSandboxSwitchStatus
509 {
510     SandboxCommonDef::SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ?
511         SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG : SandboxCommonDef::SANDBOX_APP_JSON_CONFIG;
512 
513     for (auto& wholeConfig : GetCJsonConfig(type)) {
514         // 获取 "common" 数组
515         cJSON *common = cJSON_GetObjectItemCaseSensitive(wholeConfig, SandboxCommonDef::g_commonPrefix);
516         if (!common || !cJSON_IsArray(common)) {
517             continue;
518         }
519         // 获取第一个字段
520         cJSON *firstCommon = cJSON_GetArrayItem(common, 0);
521         if (!firstCommon) {
522             continue;
523         }
524         return GetBoolValueFromJsonObj(firstCommon, SandboxCommonDef::g_topSandBoxSwitchPrefix, true);
525     }
526     // default sandbox switch is on
527     return true;
528 }
529 
IsAppSandboxEnabled(const AppSpawningCtx * appProperty)530 bool SandboxCommon::IsAppSandboxEnabled(const AppSpawningCtx *appProperty) // CheckAppSandboxSwitchStatus
531 {
532     SandboxCommonDef::SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ?
533         SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG : SandboxCommonDef::SANDBOX_APP_JSON_CONFIG;
534 
535     bool ret = true;
536     for (auto& wholeConfig : GetCJsonConfig(type)) {
537         // 获取 "individual" 数组
538         cJSON *individual = cJSON_GetObjectItemCaseSensitive(wholeConfig, SandboxCommonDef::g_privatePrefix);
539         if (!individual || !cJSON_IsArray(individual)) {
540             continue;
541         }
542         cJSON *bundleNameInfo = cJSON_GetObjectItemCaseSensitive(individual, GetBundleName(appProperty));
543         if (!bundleNameInfo || !cJSON_IsArray(bundleNameInfo)) {
544             continue;
545         }
546         // 获取第一个字段
547         cJSON *firstCommon = cJSON_GetArrayItem(bundleNameInfo, 0);
548         if (!firstCommon) {
549             continue;
550         }
551         ret = GetSwitchStatus(firstCommon);
552         if (ret) {
553             break;
554         }
555     }
556     // default sandbox switch is on
557     return ret;
558 }
559 
GetSandboxMountConfig(const AppSpawningCtx * appProperty,const std::string & section,cJSON * mntPoint,SandboxMountConfig & mountConfig)560 void SandboxCommon::GetSandboxMountConfig(const AppSpawningCtx *appProperty, const std::string &section,
561                                           cJSON *mntPoint, SandboxMountConfig &mountConfig)
562 {
563     if (section.compare(SandboxCommonDef::g_permissionPrefix) == 0 ||
564         section.compare(SandboxCommonDef::g_flagePoint) == 0 ||
565         section.compare(SandboxCommonDef::g_debughap) == 0) {
566         mountConfig.optionsPoint = GetOptions(appProperty, mntPoint);
567         mountConfig.fsType = GetFsType(mntPoint);
568         mountConfig.decPaths = GetDecPath(appProperty, mntPoint);
569     } else {
570         mountConfig.fsType = GetFsType(mntPoint);
571         mountConfig.optionsPoint = "";
572         mountConfig.decPaths = {};
573     }
574     return;
575 }
576 
577 // 校验操作
IsNeededCheckPathStatus(const AppSpawningCtx * appProperty,const char * path)578 bool SandboxCommon::IsNeededCheckPathStatus(const AppSpawningCtx *appProperty, const char *path)
579 {
580     if (strstr(path, "data/app/el1/") || strstr(path, "data/app/el2/")) {
581         return true;
582     }
583     if ((strstr(path, "data/app/el3/") || strstr(path, "data/app/el4/") || strstr(path, "data/app/el5/")) &&
584         CheckAppMsgFlagsSet(appProperty, APP_FLAGS_UNLOCKED_STATUS)) {
585         return true;
586     }
587     return false;
588 }
589 
CheckMountStatus(const std::string & path)590 void SandboxCommon::CheckMountStatus(const std::string &path)
591 {
592     std::ifstream file("/proc/self/mountinfo");
593     if (!file.is_open()) {
594         APPSPAWN_LOGE("Failed to open /proc/self/mountinfo errno %{public}d", errno);
595         return;
596     }
597 
598     bool flag = false;
599     std::string line;
600     while (std::getline(file, line)) {
601         if (line.find(path) != std::string::npos) {
602             flag = true;
603             APPSPAWN_LOGI("Current mountinfo %{public}s", line.c_str());
604         }
605     }
606     file.close();
607     APPSPAWN_CHECK_ONLY_LOG(flag, "Mountinfo not contains %{public}s", path.c_str());
608 }
609 
HasPrivateInBundleName(const std::string & bundleName)610 bool SandboxCommon::HasPrivateInBundleName(const std::string &bundleName) // CheckBundleNameForPrivate
611 {
612     if (bundleName.find(SandboxCommonDef::g_internal) != std::string::npos) {
613         return false;
614     }
615     return true;
616 }
617 
IsMountSuccessful(cJSON * mntPoint)618 bool SandboxCommon::IsMountSuccessful(cJSON *mntPoint) // GetCheckStatus
619 {
620     // default false
621     return GetBoolValueFromJsonObj(mntPoint, SandboxCommonDef::g_actionStatuc, false);
622 }
623 
CheckBundleName(const std::string & bundleName)624 int SandboxCommon::CheckBundleName(const std::string &bundleName)
625 {
626     if (bundleName.empty() || bundleName.size() > APP_LEN_BUNDLE_NAME) {
627         return -1;
628     }
629     if (bundleName.find('\\') != std::string::npos || bundleName.find('/') != std::string::npos) {
630         return -1;
631     }
632     return 0;
633 }
634 
CheckAppFullMountEnable()635 int32_t SandboxCommon::CheckAppFullMountEnable()
636 {
637     if (deviceTypeEnable_ != -1) {
638         return deviceTypeEnable_;
639     }
640 
641     char value[] = "false";
642     int32_t ret = GetParameter("const.filemanager.full_mount.enable", "false", value, sizeof(value));
643     if (ret > 0 && (strcmp(value, "true")) == 0) {
644         deviceTypeEnable_ = SandboxCommonDef::FILE_CROSS_APP_STATUS;
645     } else if (ret > 0 && (strcmp(value, "false")) == 0) {
646         deviceTypeEnable_ = SandboxCommonDef::FILE_ACCESS_COMMON_DIR_STATUS;
647     } else {
648         deviceTypeEnable_ = -1;
649     }
650 
651     return deviceTypeEnable_;
652 }
653 
IsPrivateSharedStatus(const std::string & bundleName,AppSpawningCtx * appProperty)654 bool SandboxCommon::IsPrivateSharedStatus(const std::string &bundleName, AppSpawningCtx *appProperty)
655 {
656     bool result = false;
657     SandboxCommonDef::SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ?
658         SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG : SandboxCommonDef::SANDBOX_APP_JSON_CONFIG;
659 
660     for (auto& config : GetCJsonConfig(type)) {
661         // 获取 "individual" 数组
662         cJSON *individual = cJSON_GetObjectItemCaseSensitive(config, SandboxCommonDef::g_privatePrefix);
663         if (!individual || !cJSON_IsArray(individual)) {
664             return result;
665         }
666         cJSON *bundleNameInfo = cJSON_GetObjectItemCaseSensitive(individual, bundleName.c_str());
667         if (!bundleNameInfo || !cJSON_IsArray(bundleNameInfo)) {
668             return result;
669         }
670         result = GetBoolValueFromJsonObj(bundleNameInfo, SandboxCommonDef::g_sandBoxShared, false);
671     }
672     return result;
673 }
674 
IsValidMountConfig(cJSON * mntPoint,const AppSpawningCtx * appProperty,bool checkFlag)675 bool SandboxCommon::IsValidMountConfig(cJSON *mntPoint, const AppSpawningCtx *appProperty, bool checkFlag)
676 {
677     const char *srcPath = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_srcPath);
678     const char *sandboxPath = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_sandBoxPath);
679     cJSON *customizedFlags = cJSON_GetObjectItemCaseSensitive(mntPoint, SandboxCommonDef::g_sandBoxFlagsCustomized);
680     cJSON *flags = cJSON_GetObjectItemCaseSensitive(mntPoint, SandboxCommonDef::g_sandBoxFlags);
681     if (srcPath == nullptr || sandboxPath == nullptr || (customizedFlags == nullptr && flags == nullptr)) {
682         APPSPAWN_LOGE("read mount config failed, app name is %{public}s", GetBundleName(appProperty));
683         return false;
684     }
685 
686     AppSpawnMsgDomainInfo *info =
687         reinterpret_cast<AppSpawnMsgDomainInfo *>(GetAppProperty(appProperty, TLV_DOMAIN_INFO));
688     APPSPAWN_CHECK(info != nullptr, return false, "Filed to get domain info %{public}s", GetBundleName(appProperty));
689     const char *appAplName = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_appAplName);
690     if (appAplName != nullptr) {
691         if (!strcmp(appAplName, info->apl)) {
692             return false;
693         }
694     }
695 
696     const std::string configSrcPath = srcPath;
697     // special handle wps and don't use /data/app/xxx/<Package> config
698     if (checkFlag && (configSrcPath.find("/data/app") != std::string::npos &&
699         (configSrcPath.find("/base") != std::string::npos ||
700          configSrcPath.find("/database") != std::string::npos
701         ) && configSrcPath.find(SandboxCommonDef::g_packageName) != std::string::npos)) {
702         return false;
703     }
704 
705     return true;
706 }
707 
708 // 路径处理
ReplaceAllVariables(std::string str,const std::string & from,const std::string & to)709 std::string SandboxCommon::ReplaceAllVariables(std::string str, const std::string& from, const std::string& to)
710 {
711     while (true) {
712         std::string::size_type pos(0);
713         if ((pos = str.find(from)) != std::string::npos) {
714             str.replace(pos, from.length(), to);
715         } else {
716             break;
717         }
718     }
719     return str;
720 }
721 
SplitString(std::string & str,const std::string & delimiter)722 std::vector<std::string> SandboxCommon::SplitString(std::string &str, const std::string &delimiter)
723 {
724     std::string::size_type pos;
725     std::vector<std::string> result;
726     str += delimiter;
727     size_t size = str.size();
728     for (unsigned int i = 0; i < size; i++) {
729         pos = str.find(delimiter, i);
730         if (pos < size) {
731             std::string s = str.substr(i, pos - i);
732             result.push_back(s);
733             i = pos + delimiter.size() - 1;
734         }
735     }
736 
737     return result;
738 }
739 
MakeAtomicServiceDir(const AppSpawningCtx * appProperty,std::string path,std::string variablePackageName)740 void SandboxCommon::MakeAtomicServiceDir(const AppSpawningCtx *appProperty, std::string path,
741                                          std::string variablePackageName)
742 {
743     AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO));
744     APPSPAWN_CHECK(dacInfo != nullptr, return, "No dac info in msg app property");
745     if (path.find("/mnt/share") != std::string::npos) {
746         path = "/data/service/el2/" + std::to_string(dacInfo->uid / UID_BASE) + "/share/" + variablePackageName;
747     }
748     struct stat st = {};
749     if (stat(path.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) {
750         return;
751     }
752 
753     int ret = mkdir(path.c_str(), S_IRWXU);
754     APPSPAWN_CHECK(ret == 0, return, "mkdir %{public}s failed, errno %{public}d", path.c_str(), errno);
755 
756     if (path.find("/database") != std::string::npos || path.find("/data/service/el2") != std::string::npos) {
757         ret = chmod(path.c_str(), S_IRWXU | S_IRWXG | S_ISGID);
758     } else if (path.find("/log") != std::string::npos) {
759         ret = chmod(path.c_str(), S_IRWXU | S_IRWXG);
760     }
761     APPSPAWN_CHECK(ret == 0, return, "chmod %{public}s failed, errno %{public}d", path.c_str(), errno);
762 
763 #ifdef WITH_SELINUX
764     AppSpawnMsgDomainInfo *msgDomainInfo =
765         reinterpret_cast<AppSpawnMsgDomainInfo *>(GetAppProperty(appProperty, TLV_DOMAIN_INFO));
766     APPSPAWN_CHECK(msgDomainInfo != nullptr, return, "No domain info for %{public}s", GetProcessName(appProperty));
767     HapContext hapContext;
768     HapFileInfo hapFileInfo;
769     hapFileInfo.pathNameOrig.push_back(path);
770     hapFileInfo.apl = msgDomainInfo->apl;
771     hapFileInfo.packageName = GetBundleName(appProperty);
772     hapFileInfo.hapFlags = msgDomainInfo->hapFlags;
773     if (CheckAppMsgFlagsSet(appProperty, APP_FLAGS_DEBUGGABLE)) {
774         hapFileInfo.hapFlags |= SELINUX_HAP_DEBUGGABLE;
775     }
776     if ((path.find("/base") != std::string::npos) || (path.find("/database") != std::string::npos)) {
777         ret = hapContext.HapFileRestorecon(hapFileInfo);
778         APPSPAWN_CHECK(ret == 0, return, "set dir %{public}s selinuxLabel failed, apl %{public}s, ret %{public}d",
779             path.c_str(), hapFileInfo.apl.c_str(), ret);
780     }
781 #endif
782     if (path.find("/base") != std::string::npos || path.find("/data/service/el2") != std::string::npos) {
783         ret = chown(path.c_str(), dacInfo->uid, dacInfo->gid);
784     } else if (path.find("/database") != std::string::npos) {
785         ret = chown(path.c_str(), dacInfo->uid, DecodeGid("ddms"));
786     } else if (path.find("/log") != std::string::npos) {
787         ret = chown(path.c_str(), dacInfo->uid, DecodeGid("log"));
788     }
789     APPSPAWN_CHECK(ret == 0, return, "chown %{public}s failed, errno %{public}d", path.c_str(), errno);
790     return;
791 }
792 
ReplaceVariablePackageName(const AppSpawningCtx * appProperty,const std::string & path)793 std::string SandboxCommon::ReplaceVariablePackageName(const AppSpawningCtx *appProperty, const std::string &path)
794 {
795     std::string tmpSandboxPath = path;
796     AppSpawnMsgBundleInfo *bundleInfo =
797         reinterpret_cast<AppSpawnMsgBundleInfo *>(GetAppProperty(appProperty, TLV_BUNDLE_INFO));
798     APPSPAWN_CHECK(bundleInfo != nullptr, return "", "No bundle info in msg %{public}s", GetBundleName(appProperty));
799 
800     char *extension;
801     uint32_t flags = CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_ATOMIC_SERVICE) ? 0x4 : 0;
802     if (flags == 0) {
803         flags = (CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_CLONE_ENABLE) &&
804             bundleInfo->bundleIndex > 0) ? 0x1 : 0;
805         flags |= CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_EXTENSION_SANDBOX) ? 0x2 : 0;
806         extension = reinterpret_cast<char *>(
807             GetAppSpawnMsgExtInfo(appProperty->message, MSG_EXT_NAME_APP_EXTENSION, nullptr));
808     }
809     std::ostringstream variablePackageName;
810     switch (flags) {
811         case SANDBOX_PACKAGENAME_DEFAULT:    // 0 default
812             variablePackageName << bundleInfo->bundleName;
813             break;
814         case SANDBOX_PACKAGENAME_CLONE:    // 1 +clone-bundleIndex+packageName
815             variablePackageName << "+clone-" << bundleInfo->bundleIndex << "+" << bundleInfo->bundleName;
816             break;
817         case SANDBOX_PACKAGENAME_EXTENSION: {  // 2 +extension-<extensionType>+packageName
818             APPSPAWN_CHECK(extension != nullptr, return "", "Invalid extension data ");
819             variablePackageName << "+extension-" << extension << "+" << bundleInfo->bundleName;
820             break;
821         }
822         case SANDBOX_PACKAGENAME_CLONE_AND_EXTENSION: {  // 3 +clone-bundleIndex+extension-<extensionType>+packageName
823             APPSPAWN_CHECK(extension != nullptr, return "", "Invalid extension data ");
824             variablePackageName << "+clone-" << bundleInfo->bundleIndex << "+extension" << "-" <<
825                 extension << "+" << bundleInfo->bundleName;
826             break;
827         }
828         case SANDBOX_PACKAGENAME_ATOMIC_SERVICE: {  // 4 +auid-<accountId>+packageName
829             std::string accountId = GetExtraInfoByType(appProperty, MSG_EXT_NAME_ACCOUNT_ID);
830             variablePackageName << "+auid-" << accountId << "+" << bundleInfo->bundleName;
831             std::string atomicServicePath = path;
832             atomicServicePath = ReplaceAllVariables(atomicServicePath, SandboxCommonDef::g_variablePackageName,
833                                                     variablePackageName.str());
834             MakeAtomicServiceDir(appProperty, atomicServicePath, variablePackageName.str());
835             break;
836         }
837         default:
838             variablePackageName << bundleInfo->bundleName;
839             break;
840     }
841     tmpSandboxPath = ReplaceAllVariables(tmpSandboxPath, SandboxCommonDef::g_variablePackageName,
842                                          variablePackageName.str());
843     return tmpSandboxPath;
844 }
845 
ReplaceHostUserId(const AppSpawningCtx * appProperty,const std::string & path)846 std::string SandboxCommon::ReplaceHostUserId(const AppSpawningCtx *appProperty, const std::string &path)
847 {
848     std::string tmpSandboxPath = path;
849     int32_t uid = 0;
850     const char *userId =
851         (const char *)(GetAppSpawnMsgExtInfo(appProperty->message, MSG_EXT_NAME_PARENT_UID, nullptr));
852     if (userId != nullptr) {
853         uid = atoi(userId);
854     }
855     tmpSandboxPath = ReplaceAllVariables(tmpSandboxPath, SandboxCommonDef::g_hostUserId,
856                                                         std::to_string(uid / UID_BASE));
857     APPSPAWN_LOGV("tmpSandboxPath %{public}s", tmpSandboxPath.c_str());
858     return tmpSandboxPath;
859 }
860 
ReplaceClonePackageName(const AppSpawningCtx * appProperty,const std::string & path)861 std::string SandboxCommon::ReplaceClonePackageName(const AppSpawningCtx *appProperty, const std::string &path)
862 {
863     std::string tmpSandboxPath = path;
864     AppSpawnMsgBundleInfo *bundleInfo =
865         reinterpret_cast<AppSpawnMsgBundleInfo *>(GetAppProperty(appProperty, TLV_BUNDLE_INFO));
866     APPSPAWN_CHECK(bundleInfo != nullptr, return "", "No bundle info in msg %{public}s", GetBundleName(appProperty));
867 
868     std::string tmpBundlePath = bundleInfo->bundleName;
869     std::ostringstream variablePackageName;
870     if (CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_CLONE_ENABLE)) {
871         variablePackageName << "+clone-" << bundleInfo->bundleIndex << "+" << bundleInfo->bundleName;
872         tmpBundlePath = variablePackageName.str();
873     }
874 
875     tmpSandboxPath = ReplaceAllVariables(tmpSandboxPath, SandboxCommonDef::g_clonePackageName, tmpBundlePath);
876     APPSPAWN_LOGV("tmpSandboxPath %{public}s", tmpSandboxPath.c_str());
877     return tmpSandboxPath;
878 }
879 
GetArkWebPackageName(void)880 const std::string& SandboxCommon::GetArkWebPackageName(void)
881 {
882     static std::string arkWebPackageName;
883     if (arkWebPackageName.empty()) {
884         arkWebPackageName = system::GetParameter(SandboxCommonDef::ARK_WEB_PERSIST_PACKAGE_NAME, "");
885     }
886     return arkWebPackageName;
887 }
888 
GetDevModel(void)889 const std::string& SandboxCommon::GetDevModel(void)
890 {
891     static std::string devModel;
892     if (devModel.empty()) {
893         devModel = system::GetParameter(SandboxCommonDef::DEVICE_MODEL_NAME_PARAM, "");
894     }
895     return devModel;
896 }
897 
ConvertToRealPathWithPermission(const AppSpawningCtx * appProperty,std::string path)898 std::string SandboxCommon::ConvertToRealPathWithPermission(const AppSpawningCtx *appProperty, std::string path)
899 {
900     AppSpawnMsgBundleInfo *info =
901         reinterpret_cast<AppSpawnMsgBundleInfo *>(GetAppProperty(appProperty, TLV_BUNDLE_INFO));
902     AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO));
903     APPSPAWN_CHECK((info != nullptr && dacInfo != nullptr), return "", "Invalid params");
904 
905     if (path.find(SandboxCommonDef::g_packageNameIndex) != std::string::npos) {
906         std::string bundleNameWithIndex = info->bundleName;
907         if (info->bundleIndex != 0) {
908             bundleNameWithIndex = std::to_string(info->bundleIndex) + "_" + bundleNameWithIndex;
909         }
910         path = ReplaceAllVariables(path, SandboxCommonDef::g_packageNameIndex, bundleNameWithIndex);
911     }
912 
913     if (path.find(SandboxCommonDef::g_packageName) != std::string::npos) {
914         path = ReplaceAllVariables(path, SandboxCommonDef::g_packageName, info->bundleName);
915     }
916 
917     if (path.find(SandboxCommonDef::g_userId) != std::string::npos) {
918         path = ReplaceAllVariables(path, SandboxCommonDef::g_userId, "currentUser");
919     }
920 
921     if (path.find(SandboxCommonDef::g_permissionUserId) != std::string::npos) {
922         path = ReplaceAllVariables(path, SandboxCommonDef::g_permissionUserId, std::to_string(dacInfo->uid / UID_BASE));
923     }
924     return path;
925 }
926 
ConvertToRealPath(const AppSpawningCtx * appProperty,std::string path)927 std::string SandboxCommon::ConvertToRealPath(const AppSpawningCtx *appProperty, std::string path)
928 {
929     AppSpawnMsgBundleInfo *info =
930         reinterpret_cast<AppSpawnMsgBundleInfo *>(GetAppProperty(appProperty, TLV_BUNDLE_INFO));
931     AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO));
932     if (info == nullptr || dacInfo == nullptr) {
933         return "";
934     }
935     if (path.find(SandboxCommonDef::g_packageNameIndex) != std::string::npos) {
936         std::string bundleNameWithIndex = info->bundleName;
937         if (info->bundleIndex != 0) {
938             bundleNameWithIndex = std::to_string(info->bundleIndex) + "_" + bundleNameWithIndex;
939         }
940         path = ReplaceAllVariables(path, SandboxCommonDef::g_packageNameIndex, bundleNameWithIndex);
941     }
942 
943     if (path.find(SandboxCommonDef::g_packageName) != std::string::npos) {
944         path = ReplaceAllVariables(path, SandboxCommonDef::g_packageName, info->bundleName);
945     }
946 
947     if (path.find(SandboxCommonDef::g_userId) != std::string::npos) {
948         path = ReplaceAllVariables(path, SandboxCommonDef::g_userId, std::to_string(dacInfo->uid / UID_BASE));
949     }
950 
951     if (path.find(SandboxCommonDef::g_hostUserId) != std::string::npos) {
952         path = ReplaceHostUserId(appProperty, path);
953     }
954 
955     if (path.find(SandboxCommonDef::g_variablePackageName) != std::string::npos) {
956         path = ReplaceVariablePackageName(appProperty, path);
957     }
958 
959     if (path.find(SandboxCommonDef::g_clonePackageName) != std::string::npos) {
960         path = ReplaceClonePackageName(appProperty, path);
961     }
962 
963     if (path.find(SandboxCommonDef::g_arkWebPackageName) != std::string::npos) {
964         path = ReplaceAllVariables(path, SandboxCommonDef::g_arkWebPackageName, GetArkWebPackageName());
965         APPSPAWN_LOGV("arkWeb sandbox, path %{public}s, package:%{public}s",
966                       path.c_str(), GetArkWebPackageName().c_str());
967     }
968 
969     if (path.find(SandboxCommonDef::g_devModel) != std::string::npos) {
970         path = ReplaceAllVariables(path, SandboxCommonDef::g_devModel, GetDevModel());
971     }
972 
973     return path;
974 }
975 
976 // 挂载操作
DoAppSandboxMountOnce(const AppSpawningCtx * appProperty,const SharedMountArgs * arg)977 int32_t SandboxCommon::DoAppSandboxMountOnce(const AppSpawningCtx *appProperty, const SharedMountArgs *arg)
978 {
979     if (!(arg && arg->srcPath && arg->destPath && arg->srcPath[0] != '\0' && arg->destPath[0] != '\0')) {
980         return 0;
981     }
982     if (strstr(arg->srcPath, "system/etc/hosts") != nullptr || strstr(arg->srcPath, "system/etc/profile") != nullptr) {
983         CreateFileIfNotExist(arg->destPath);
984     } else {
985         (void)CreateDirRecursive(arg->destPath, SandboxCommonDef::FILE_MODE);
986     }
987 
988     int ret = 0;
989     // to mount fs and bind mount files or directory
990     struct timespec mountStart = {0};
991     clock_gettime(CLOCK_MONOTONIC_COARSE, &mountStart);
992     APPSPAWN_LOGV("Bind mount %{public}s to %{public}s '%{public}s' '%{public}lu' '%{public}s' '%{public}u'",
993         arg->srcPath, arg->destPath, arg->fsType, arg->mountFlags, arg->options, arg->mountSharedFlag);
994     ret = mount(arg->srcPath, arg->destPath, arg->fsType, arg->mountFlags, arg->options);
995     struct timespec mountEnd = {0};
996     clock_gettime(CLOCK_MONOTONIC_COARSE, &mountEnd);
997     uint64_t diff = DiffTime(&mountStart, &mountEnd);
998     APPSPAWN_CHECK_ONLY_LOGW(diff < SandboxCommonDef::MAX_MOUNT_TIME, "mount %{public}s time %{public}" PRId64 " us",
999                             arg->srcPath, diff);
1000 #ifdef APPSPAWN_HISYSEVENT
1001     APPSPAWN_CHECK_ONLY_EXPER(diff < FUNC_REPORT_DURATION, ReportAbnormalDuration(arg->srcPath, diff));
1002 #endif
1003     if (ret != 0) {
1004         APPSPAWN_LOGI("errno is: %{public}d, bind mount %{public}s to %{public}s", errno, arg->srcPath, arg->destPath);
1005         if (errno == ENOENT && IsNeededCheckPathStatus(appProperty, arg->srcPath)) {
1006             VerifyDirRecursive(arg->srcPath);
1007         }
1008         return ret;
1009     }
1010 
1011     ret = mount(nullptr, arg->destPath, nullptr, arg->mountSharedFlag, nullptr);
1012     if (ret != 0) {
1013         APPSPAWN_LOGI("errno is: %{public}d, private mount to %{public}s '%{public}u' failed",
1014             errno, arg->destPath, arg->mountSharedFlag);
1015         if (errno == EINVAL) {
1016             CheckMountStatus(arg->destPath);
1017         }
1018         return ret;
1019     }
1020     return 0;
1021 }
1022 
1023 } // namespace AppSpawn
1024 } // namespace OHOS