diff --git a/modules/sandbox/normal/sandbox_common.cpp b/modules/sandbox/normal/sandbox_common.cpp index 9eca40fcceac87c6e97377e583ce1b45db680cfa..81b4a29b0538a32fce3e90b9a509f22a7c7ce294 100644 --- a/modules/sandbox/normal/sandbox_common.cpp +++ b/modules/sandbox/normal/sandbox_common.cpp @@ -41,6 +41,7 @@ namespace OHOS { namespace AppSpawn { int32_t SandboxCommon::deviceTypeEnable_ = -1; +int32_t SandboxCommon::mountFailedCount = 0; std::map> SandboxCommon::appSandboxCJsonConfig_ = {}; // 加载配置文件 @@ -607,6 +608,29 @@ void SandboxCommon::CheckMountStatus(const std::string &path) APPSPAWN_CHECK_ONLY_LOG(flag, "Mountinfo not contains %{public}s", path.c_str()); } +std::string SandboxCommon::CollectMountInfo(void) +{ + pid_t pid = getppid(); + APPSPAWN_CHECK(pid > 0, return "", "Failed to get parent pid errno %{public}d", errno); + + std::string path = "/proc/" + std::to_string(pid) + "/mountinfo"; + std::ifstream file(path); + APPSPAWN_CHECK(file.is_open(), return "", "Failed to open %{public}s errno %{public}d", path.c_str(), errno); + + int count = 0; + std::string line; + std::ostringstream mountInfo; + while (std::getline(file, line)) { + mountInfo << line << "; "; + ++count; + } + mountInfo << "count:" << count; + APPSPAWN_LOGI("The count of %{public}s for the root namespace is %{public}d", path.c_str(), count); + + file.close(); + return mountInfo.str(); +} + bool SandboxCommon::HasPrivateInBundleName(const std::string &bundleName) // CheckBundleNameForPrivate { if (bundleName.find(SandboxCommonDef::g_internal) != std::string::npos) { @@ -996,13 +1020,20 @@ int32_t SandboxCommon::DoAppSandboxMountOnce(const AppSpawningCtx *appProperty, struct timespec mountEnd = {0}; clock_gettime(CLOCK_MONOTONIC_COARSE, &mountEnd); uint64_t diff = DiffTime(&mountStart, &mountEnd); - APPSPAWN_CHECK_ONLY_LOGW(diff < SandboxCommonDef::MAX_MOUNT_TIME, "mount %{public}s time %{public}" PRId64 " us", - arg->srcPath, diff); + APPSPAWN_CHECK_ONLY_LOGW(diff < SandboxCommonDef::MAX_MOUNT_TIME, + "ret %{public}d mount %{public}s time use %{public}" PRId64 " us", ret, arg->srcPath, diff); #ifdef APPSPAWN_HISYSEVENT APPSPAWN_CHECK_ONLY_EXPER(diff < FUNC_REPORT_DURATION, ReportAbnormalDuration(arg->srcPath, diff)); #endif if (ret != 0) { APPSPAWN_LOGI("errno is: %{public}d, bind mount %{public}s to %{public}s", errno, arg->srcPath, arg->destPath); +#ifdef APPSPAWN_HISYSEVENT + if (errno == EINVAL && ++mountFailedCount == SandboxCommonDef::MAX_MOUNT_INVAILD_COUNT) { + std::string mountInfo = CollectMountInfo(); + ReportMountFail("appspawn", "mountinfo", mountInfo.c_str(), errno); + return APPSPAWN_SANDBOX_MOUNT_FULL; + } +#endif if (errno == ENOENT && IsNeededCheckPathStatus(appProperty, arg->srcPath)) { VerifyDirRecursive(arg->srcPath); } @@ -1013,9 +1044,7 @@ int32_t SandboxCommon::DoAppSandboxMountOnce(const AppSpawningCtx *appProperty, if (ret != 0) { APPSPAWN_LOGI("errno is: %{public}d, private mount to %{public}s '%{public}u' failed", errno, arg->destPath, arg->mountSharedFlag); - if (errno == EINVAL) { - CheckMountStatus(arg->destPath); - } + APPSPAWN_ONLY_EXPER(errno == EINVAL, CheckMountStatus(arg->destPath)); return ret; } return 0; diff --git a/modules/sandbox/normal/sandbox_common.h b/modules/sandbox/normal/sandbox_common.h index 9d34623d05d1529bb5b6f91003b87e111e65e0b1..8ec1296d801d2af33509317d8a37483459feb23f 100644 --- a/modules/sandbox/normal/sandbox_common.h +++ b/modules/sandbox/normal/sandbox_common.h @@ -119,6 +119,7 @@ private: // 校验操作 static bool IsNeededCheckPathStatus(const AppSpawningCtx *appProperty, const char *path); static void CheckMountStatus(const std::string &path); + static std::string CollectMountInfo(void); // 路径处理 static std::string ReplaceVariablePackageName(const AppSpawningCtx *appProperty, const std::string &path); @@ -131,6 +132,7 @@ private: private: static int32_t deviceTypeEnable_; + static int32_t mountFailedCount; static std::map> appSandboxCJsonConfig_; typedef enum { SANDBOX_PACKAGENAME_DEFAULT = 0, diff --git a/modules/sandbox/normal/sandbox_core.cpp b/modules/sandbox/normal/sandbox_core.cpp index 524053a7d7bc984afe5f3965d20d1475c18c9704..5b5330a92f6ebb049ed73b4f38962444de346035 100644 --- a/modules/sandbox/normal/sandbox_core.cpp +++ b/modules/sandbox/normal/sandbox_core.cpp @@ -559,6 +559,7 @@ int32_t SandboxCore::ProcessMountPoint(cJSON *mntPoint, MountPointProcessParams if (ret < 0) { ret = SandboxCommon::DoAppSandboxMountOnce(params.appProperty, &arg); } + APPSPAWN_ONLY_EXPER(ret == APPSPAWN_SANDBOX_MOUNT_FULL, return APPSPAWN_SANDBOX_MOUNT_FULL); APPSPAWN_CHECK(ret == 0 || !SandboxCommon::IsMountSuccessful(mntPoint), #ifdef APPSPAWN_HISYSEVENT ReportMountFail(params.bundleName.c_str(), arg.srcPath, arg.destPath, errno); diff --git a/modules/sandbox/normal/sandbox_def.h b/modules/sandbox/normal/sandbox_def.h index e0dcfdc8c797c68fd03a01bcf0c69858b0e188bb..f65121bf29a74336d4227276c22d480873531159 100644 --- a/modules/sandbox/normal/sandbox_def.h +++ b/modules/sandbox/normal/sandbox_def.h @@ -32,6 +32,7 @@ constexpr static mode_t FILE_MODE = 0711; constexpr static mode_t BASIC_MOUNT_FLAGS = MS_REC | MS_BIND; constexpr int32_t MAX_MOUNT_TIME = 500; // 500us constexpr int32_t LOCK_STATUS_SIZE = 16; +constexpr int32_t MAX_MOUNT_INVAILD_COUNT = 8; // 沙盒配置文件 const std::string APP_JSON_CONFIG = "/appdata-sandbox.json"; diff --git a/modules/sysevent/hisysevent_adapter.cpp b/modules/sysevent/hisysevent_adapter.cpp index 78711cf7444787a7a03c1ba41571e0dad4c07cd2..d428eb4f47f96017c66902cf2a555b1432d96aef 100644 --- a/modules/sysevent/hisysevent_adapter.cpp +++ b/modules/sysevent/hisysevent_adapter.cpp @@ -155,7 +155,7 @@ void ReportMountFail(const char* bundleName, const char* srcPath, const char* ta int32_t spawnResult) { if (srcPath == nullptr || (strstr(srcPath, "data/app/el1/") == nullptr && - strstr(srcPath, "data/app/el2/") == nullptr)) { + strstr(srcPath, "data/app/el2/") == nullptr && strstr(srcPath, "mountinfo") == nullptr)) { return; } int ret = HiSysEventWrite(HiSysEvent::Domain::APPSPAWN, SPAWN_CHILD_PROCESS_FAIL, @@ -182,7 +182,7 @@ void ReportKeyEvent(const char *eventName) void ReportAbnormalDuration(const char* scene, uint64_t duration) { - APPSPAWN_LOGI("ReportAbnormalDuration %{public}d with %{public}s %{public}" PRId64 " us", + APPSPAWN_LOGI("ReportAbnormalDuration %{public}d with %{public}s %{public}" PRId64 " us", getpid(), scene, duration); int ret = HiSysEventWrite(HiSysEvent::Domain::APPSPAWN, SPAWN_ABNORMAL_DURATION, HiSysEvent::EventType::BEHAVIOR, diff --git a/test/unittest/app_spawn_standard_test/app_spawn_sandbox_test.cpp b/test/unittest/app_spawn_standard_test/app_spawn_sandbox_test.cpp index 1d488af14a3f2d4cebd995b58ed1d161feeacd34..78b382f4d87c58785cc46b3c4cd1a3754abf657f 100644 --- a/test/unittest/app_spawn_standard_test/app_spawn_sandbox_test.cpp +++ b/test/unittest/app_spawn_standard_test/app_spawn_sandbox_test.cpp @@ -2440,4 +2440,16 @@ HWTEST_F(AppSpawnSandboxTest, Handle_Flag_Point_PreInstall_Shell_Hap_002, TestSi EXPECT_EQ(res, 0); DeleteAppSpawningCtx(appProperty); } + +/** + * @tc.name: App_Spawn_Sandbox_Collect_MountInfo_01 + * @tc.desc: [CollectMountInfo] collect the mountinfo of the current namespace + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Collect_MountInfo_01, TestSize.Level0) +{ + std::string mountinfo = AppSpawn::SandboxCommon::CollectMountInfo(); + EXPECT_GT(mountinfo.size(), 0); +} } // namespace OHOS diff --git a/util/include/appspawn_utils.h b/util/include/appspawn_utils.h index 7ce58c6d08016ba393c05b5ef3c1a673960eb954..9fdb7c2fa5a42a36f688d111bc67d09fbabc285c 100644 --- a/util/include/appspawn_utils.h +++ b/util/include/appspawn_utils.h @@ -138,6 +138,7 @@ typedef enum { APPSPAWN_SANDBOX_ERROR_MOUNT_FAIL, APPSPAWN_SANDBOX_ERROR_SET_PERMISSION_FLAG_FAIL, APPSPAWN_NODE_EXIST, + APPSPAWN_SANDBOX_MOUNT_FULL, /* devicedebug errno */ APPSPAWN_DEVICEDEBUG_ERROR_APP_NOT_EXIST, APPSPAWN_DEVICEDEBUG_ERROR_APP_NOT_DEBUGGABLE,