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 §ion,
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