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