已开启
提供跨应用通信功能 #2950
斌创建于 8 天前
提供跨应用通信功能 #2950
已开启
共 5 个文件变更+801-37
| @@ -322,6 +322,7 @@ int AppSpawnClientAddPermission(AppSpawnClientHandle handle, AppSpawnReqMsgHandl | |||
| 322 | 322 | ||
| 323 | 323 | ||
| 324 | 324 | ||
| 325 | + | ||
| 325 | 326 | ||
| 326 | int AppSpawnReqMsgAddExtInfo(AppSpawnReqMsgHandle reqHandle, const char *name, const uint8_t *value, uint32_t valueLen); | 327 | int AppSpawnReqMsgAddExtInfo(AppSpawnReqMsgHandle reqHandle, const char *name, const uint8_t *value, uint32_t valueLen); |
| 327 | 328 | ||
| @@ -484,6 +484,36 @@ static inline cJSON *GetJsonObjFromProperty(const AppSpawningCtx *appProperty, c | |||
| 484 | return root; | 484 | return root; |
| 485 | } | 485 | } |
| 486 | 486 | ||
| 487 | +static int EnsureDirWithMode(const std::string &path, uid_t uid, gid_t gid, mode_t mode, bool restorecon = false) | ||
| 488 | +{ | ||
| 489 | + struct stat statBuff; | ||
| 490 | + if (stat(path.c_str(), &statBuff) == 0 && | ||
| 491 | + statBuff.st_uid == uid && statBuff.st_gid == gid && | ||
| 492 | + (statBuff.st_mode & SandboxCommonDef::ALL_FILE_MODE_BITS) == mode) { | ||
| 493 | + return 0; | ||
| 494 | + } | ||
| 495 | + int ret = SandboxCommon::CreateDirRecursive(path, SandboxCommonDef::FILE_MODE); | ||
| 496 | + if (ret != 0) { | ||
| 497 | + APPSPAWN_LOGE("mkdir %{public}s failed, errno %{public}d", path.c_str(), errno); | ||
| 498 | + return -1; | ||
| 499 | + } | ||
| 500 | + if (restorecon && RestoreconRecurse(path.c_str()) != 0) { | ||
| 501 | + APPSPAWN_LOGW("restorecon failed for %{public}s", path.c_str()); | ||
| 502 | + } | ||
| 503 | + if (chmod(path.c_str(), mode) < 0 || chown(path.c_str(), uid, gid) < 0) { | ||
| 504 | + APPSPAWN_LOGE("chmod or chown failed for %{public}s, errno %{public}d", path.c_str(), errno); | ||
| 505 | + if (stat(path.c_str(), &statBuff) < 0) { | ||
| 506 | + APPSPAWN_LOGE("stat %{public}s failed", path.c_str()); | ||
| 507 | + } else if (statBuff.st_uid != uid || statBuff.st_gid != gid || | ||
| 508 | + (statBuff.st_mode & SandboxCommonDef::ALL_FILE_MODE_BITS) != mode) { | ||
| 509 | + APPSPAWN_LOGE("chmod or chown mismatch for %{public}s, expected uid=%{public}d, " | ||
| 510 | + "gid=%{public}d, mode=%{public}d; actual uid=%{public}d, gid=%{public}d, mode=%{public}d", | ||
| 511 | + path.c_str(), uid, gid, mode, statBuff.st_uid, statBuff.st_gid, statBuff.st_mode); | ||
| 512 | + } | ||
| 513 | + } | ||
| 514 | + return 0; | ||
| 515 | +} | ||
| 516 | + | ||
| 487 | int32_t SandboxCore::MountAllHsp(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath, cJSON *hspRoot) | 517 | int32_t SandboxCore::MountAllHsp(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath, cJSON *hspRoot) |
| 488 | { | 518 | { |
| 489 | if (appProperty == nullptr || sandboxPackagePath == "") { | 519 | if (appProperty == nullptr || sandboxPackagePath == "") { |
| @@ -756,6 +786,65 @@ int32_t SandboxCore::DoAllMntPointsMountNocheck(const AppSpawningCtx *appPropert | |||
| 756 | return SandboxCommon::HandleArrayForeach(mountPoints, processor); | 786 | return SandboxCommon::HandleArrayForeach(mountPoints, processor); |
| 757 | } | 787 | } |
| 758 | 788 | ||
| 789 | +static int32_t ProcessIPCGroupItem(cJSON *groupItem, const AppSpawningCtx *appProperty, | ||
| 790 | + const std::string &sandboxPackagePath, const std::string &userId) | ||
| 791 | +{ | ||
| 792 | + cJSON *groupIdItem = cJSON_GetObjectItemCaseSensitive( | ||
| 793 | + groupItem, SandboxCommonDef::g_ipcGroupList_key_groupId.c_str()); | ||
| 794 | + if (groupIdItem == nullptr || !cJSON_IsString(groupIdItem) || strlen(groupIdItem->valuestring) == 0) { | ||
| 795 | + APPSPAWN_LOGI("IPCGroup item missing or empty groupId"); | ||
| 796 | + return -1; | ||
| 797 | + } | ||
| 798 | + std::string groupId(groupIdItem->valuestring); | ||
| 799 | + if (groupId.find_first_not_of("0123456789") != std::string::npos) { | ||
| 800 | + APPSPAWN_LOGI("IPCGroup item invalid groupId"); | ||
| 801 | + return -1; | ||
| 802 | + } | ||
| 803 | + cJSON *groupGidItem = cJSON_GetObjectItemCaseSensitive( | ||
| 804 | + groupItem, SandboxCommonDef::g_ipcGroupList_key_groupGid.c_str()); | ||
| 805 | + if (groupGidItem == nullptr || !cJSON_IsString(groupGidItem)) { | ||
| 806 | + APPSPAWN_LOGI("IPCGroup item missing or invalid groupGid"); | ||
| 807 | + return -1; | ||
| 808 | + } | ||
| 809 | + gid_t groupGid = static_cast<gid_t>(atoi(groupGidItem->valuestring)); | ||
| 810 | + if (groupGid == 0) { | ||
| 811 | + APPSPAWN_LOGI("IPCGroup item invalid groupGid value"); | ||
| 812 | + return -1; | ||
| 813 | + } | ||
| 814 | + std::string srcPath = SandboxCommonDef::g_ipcGroupSrcPathPrefix + userId + "/group/" + groupId; | ||
| 815 | + if (EnsureDirWithMode(srcPath, 0, groupGid, SandboxCommonDef::IPC_GROUP_SRC_PATH_MODE) != 0) { | ||
| 816 | + return 0; | ||
| 817 | + } | ||
| 818 | + std::string sandboxPath = sandboxPackagePath + SandboxCommonDef::g_ipcGroupSandboxPathPrefix + groupId; | ||
| 819 | + SharedMountArgs arg = {.srcPath = srcPath.c_str(), .destPath = sandboxPath.c_str()}; | ||
| 820 | + int32_t mountRet = SandboxCommon::DoAppSandboxMountOnce(appProperty, &arg); | ||
| 821 | + APPSPAWN_CHECK_ONLY_LOG(mountRet == 0, "mount ipcGroup %{public}s failed, ret %{public}d", | ||
| 822 | + srcPath.c_str(), mountRet); | ||
| 823 | + return 0; | ||
| 824 | +} | ||
| 825 | + | ||
| 826 | +int32_t SandboxCore::MountIPCGroup(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath) | ||
| 827 | +{ | ||
| 828 | + if (appProperty == nullptr || sandboxPackagePath == "") { | ||
| 829 | + return 0; | ||
| 830 | + } | ||
| 831 | + cJSON *ipcGroupRoot = GetJsonObjFromProperty(appProperty, MSG_EXT_NAME_IPC_GROUP); | ||
| 832 | + APPSPAWN_CHECK_ONLY_EXPER(ipcGroupRoot != nullptr, return 0); | ||
| 833 | + APPSPAWN_CHECK(cJSON_IsArray(ipcGroupRoot), cJSON_Delete(ipcGroupRoot); return 0, "ipcGroupRoot is not array"); | ||
| 834 | + AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO)); | ||
| 835 | + if (dacInfo == nullptr) { | ||
| 836 | + cJSON_Delete(ipcGroupRoot); | ||
| 837 | + return 0; | ||
| 838 | + } | ||
| 839 | + std::string userId = std::to_string(dacInfo->uid / UID_BASE); | ||
| 840 | + auto processor = [&appProperty, &sandboxPackagePath, &userId](cJSON *item) { | ||
| 841 | + return ProcessIPCGroupItem(item, appProperty, sandboxPackagePath, userId); | ||
| 842 | + }; | ||
| 843 | + int32_t ret = SandboxCommon::HandleArrayForeach(ipcGroupRoot, processor); | ||
| 844 | + cJSON_Delete(ipcGroupRoot); | ||
low 问题:EnsureDirWithMode 失败(mkdir 失败路径)时 continue,该项 IPC 组不挂载但整体 ret=0,应用启动成功,直到运行时通信失败才暴露。与数据非法(ret=-1 启动失败)的容错策略不一致。 证据:if (EnsureDirWithMode(...) != 0) { continue; } 不置 ret。 建议:建议区分环境错误与数据错误的日志级别,或确认该容错策略是有意设计并在注释中说明。 ![]() ![]() | |||
| 845 | + return ret; | ||
| 846 | +} | ||
| 847 | + | ||
| 759 | int32_t SandboxCore::ProcessCreateOnDaemonMount(cJSON *mntPoint, MountPointProcessParams ¶ms) | 848 | int32_t SandboxCore::ProcessCreateOnDaemonMount(cJSON *mntPoint, MountPointProcessParams ¶ms) |
| 760 | { | 849 | { |
| 761 | const char *srcPathChr = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_srcPath); | 850 | const char *srcPathChr = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_srcPath); |
| @@ -789,21 +878,8 @@ int32_t SandboxCore::ProcessCreateOnDaemonMount(cJSON *mntPoint, MountPointProce | |||
| 789 | mode = (mode_t)cJSON_GetNumberValue(item); | 878 | mode = (mode_t)cJSON_GetNumberValue(item); |
| 790 | } | 879 | } |
| 791 | 880 | ||
| 792 | - struct stat statBuff; | 881 | + if (EnsureDirWithMode(srcPath, uid, gid, mode) != 0) { |
| 793 | - int ret = stat(srcPath.c_str(), &statBuff); | 882 | + return 0; |
| 794 | - if (ret < 0 || statBuff.st_uid != uid || statBuff.st_gid != gid || | ||
| 795 | - (statBuff.st_mode & SandboxCommonDef::ALL_FILE_MODE_BITS) != mode) { | ||
| 796 | - ret = SandboxCommon::CreateDirRecursive(srcPath, SandboxCommonDef::FILE_MODE); | ||
| 797 | - APPSPAWN_CHECK(ret == 0, return 0, "mkdir %{public}s failed, errno %{public}d", srcPath.c_str(), errno); | ||
| 798 | - if (chmod(srcPath.c_str(), mode) < 0 || chown(srcPath.c_str(), uid, gid) < 0) { | ||
| 799 | - if (stat(srcPath.c_str(), &statBuff) < 0) { | ||
| 800 | - APPSPAWN_LOGI("stat srcPath failed, path: %{public}s", srcPath.c_str()); | ||
| 801 | - } else if (statBuff.st_uid != uid || statBuff.st_gid != gid || | ||
| 802 | - (statBuff.st_mode & SandboxCommonDef::ALL_FILE_MODE_BITS) != mode) { | ||
| 803 | - APPSPAWN_LOGI("chmod or chown failed. statBuff.st_uid = %{public}d, statBuff.st_gid = %{public}d, \ | ||
| 804 | - statBuff.st_mode = %{public}d", statBuff.st_uid, statBuff.st_gid, statBuff.st_mode); | ||
| 805 | - } | ||
| 806 | - } | ||
| 807 | } | 883 | } |
| 808 | return ProcessMountPoint(mntPoint, params); | 884 | return ProcessMountPoint(mntPoint, params); |
| 809 | } | 885 | } |
| @@ -919,28 +995,7 @@ int32_t SandboxCore::ProcessCreateOnlyOnDaemon(cJSON *pathItem, MountPointProces | |||
| 919 | APPSPAWN_CHECK(ParseSrcPathInfo(pathItem, uid, gid, mode, restorecon), return 0, | 995 | APPSPAWN_CHECK(ParseSrcPathInfo(pathItem, uid, gid, mode, restorecon), return 0, |
| 920 | "ProcessCreateOnlyOnDaemon: Invalid json object"); | 996 | "ProcessCreateOnlyOnDaemon: Invalid json object"); |
| 921 | 997 | ||
| 922 | - struct stat statBuff; | 998 | + (void)EnsureDirWithMode(srcPath, uid, gid, mode, restorecon); |
| 923 | - int ret = stat(srcPath.c_str(), &statBuff); | ||
| 924 | - if (ret < 0 || statBuff.st_uid != uid || statBuff.st_gid != gid || | ||
| 925 | - (statBuff.st_mode & SandboxCommonDef::ALL_FILE_MODE_BITS) != mode) { | ||
| 926 | - ret = SandboxCommon::CreateDirRecursive(srcPath, SandboxCommonDef::FILE_MODE); | ||
| 927 | - APPSPAWN_CHECK(ret == 0, return 0, "ProcessCreateOnlyOnDaemon: mkdir failed, errno %{public}d", errno); | ||
| 928 | - if (restorecon && RestoreconRecurse(srcPath.c_str())) { | ||
| 929 | - APPSPAWN_LOGW("ProcessCreateOnlyOnDaemon: restorecon failed for %{public}s", srcPath.c_str()); | ||
| 930 | - } | ||
| 931 | - if (chmod(srcPath.c_str(), mode) < 0 || chown(srcPath.c_str(), uid, gid) < 0) { | ||
| 932 | - APPSPAWN_LOGE("ProcessCreateOnlyOnDaemon: chmod or chown failed for %{public}s, errno %{public}d", | ||
| 933 | - srcPath.c_str(), errno); | ||
| 934 | - if (stat(srcPath.c_str(), &statBuff) < 0) { | ||
| 935 | - APPSPAWN_LOGE("ProcessCreateOnlyOnDaemon: stat srcPath failed, path: %{public}s", srcPath.c_str()); | ||
| 936 | - } else if (statBuff.st_uid != uid || statBuff.st_gid != gid || | ||
| 937 | - (statBuff.st_mode & SandboxCommonDef::ALL_FILE_MODE_BITS) != mode) { | ||
| 938 | - APPSPAWN_LOGE("ProcessCreateOnlyOnDaemon: chmod or chown mismatch, expected uid=%{public}d, \ | ||
| 939 | - gid=%{public}d, mode=%{public}d; actual uid=%{public}d, gid=%{public}d, mode=%{public}d", | ||
| 940 | - uid, gid, mode, statBuff.st_uid, statBuff.st_gid, statBuff.st_mode); | ||
| 941 | - } | ||
| 942 | - } | ||
| 943 | - } | ||
| 944 | return 0; | 999 | return 0; |
| 945 | } | 1000 | } |
| 946 | 1001 | ||
| @@ -1201,6 +1256,9 @@ int32_t SandboxCore::SetCommonAppSandboxProperty(const AppSpawningCtx *appProper | |||
| 1201 | ret = MountAllGroup(appProperty, sandboxPackagePath); | 1256 | ret = MountAllGroup(appProperty, sandboxPackagePath); |
| 1202 | APPSPAWN_CHECK(ret == 0, return ret, "mount groupList failed, %{public}s", sandboxPackagePath.c_str()); | 1257 | APPSPAWN_CHECK(ret == 0, return ret, "mount groupList failed, %{public}s", sandboxPackagePath.c_str()); |
| 1203 | 1258 | ||
| 1259 | + ret = MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 1260 | + APPSPAWN_CHECK(ret == 0, return ret, "mount ipcGroup failed, %{public}s", sandboxPackagePath.c_str()); | ||
| 1261 | + | ||
| 1204 | AppSpawnMsgDomainInfo *info = | 1262 | AppSpawnMsgDomainInfo *info = |
| 1205 | reinterpret_cast<AppSpawnMsgDomainInfo *>(GetAppProperty(appProperty, TLV_DOMAIN_INFO)); | 1263 | reinterpret_cast<AppSpawnMsgDomainInfo *>(GetAppProperty(appProperty, TLV_DOMAIN_INFO)); |
| 1206 | APPSPAWN_CHECK(info != nullptr, return -1, "No domain info %{public}s", sandboxPackagePath.c_str()); | 1264 | APPSPAWN_CHECK(info != nullptr, return -1, "No domain info %{public}s", sandboxPackagePath.c_str()); |
| @@ -121,6 +121,7 @@ private: | |||
| 121 | // 处理可变参数的挂载 | 121 | // 处理可变参数的挂载 |
| 122 | static int32_t MountAllHsp(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath, cJSON *hspRoot); | 122 | static int32_t MountAllHsp(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath, cJSON *hspRoot); |
| 123 | static int32_t MountAllGroup(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath); | 123 | static int32_t MountAllGroup(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath); |
| 124 | + static int32_t MountIPCGroup(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath); | ||
| 124 | 125 | ||
| 125 | // 沙箱回调函数 | 126 | // 沙箱回调函数 |
| 126 | static int32_t ProcessMountPoint(cJSON *mntPoint, MountPointProcessParams ¶ms); | 127 | static int32_t ProcessMountPoint(cJSON *mntPoint, MountPointProcessParams ¶ms); |
| @@ -34,6 +34,7 @@ constexpr static mode_t BASIC_MOUNT_FLAGS = MS_REC | MS_BIND; | |||
| 34 | constexpr int32_t MAX_MOUNT_TIME = 5000; // 5000us | 34 | constexpr int32_t MAX_MOUNT_TIME = 5000; // 5000us |
| 35 | constexpr int32_t LOCK_STATUS_SIZE = 16; | 35 | constexpr int32_t LOCK_STATUS_SIZE = 16; |
| 36 | constexpr mode_t ALL_FILE_MODE_BITS = 07777; | 36 | constexpr mode_t ALL_FILE_MODE_BITS = 07777; |
| 37 | +constexpr mode_t IPC_GROUP_SRC_PATH_MODE = 01771; | ||
| 37 | constexpr int32_t MAX_MOUNT_INVALID_COUNT = 8; | 38 | constexpr int32_t MAX_MOUNT_INVALID_COUNT = 8; |
| 38 | constexpr int32_t MIN_PARAM_SRC_PATH_LEN = 2; | 39 | constexpr int32_t MIN_PARAM_SRC_PATH_LEN = 2; |
| 39 | 40 | ||
| @@ -126,6 +127,12 @@ const std::string g_hspList_key_modules = "modules"; | |||
| 126 | const std::string g_hspList_key_versions = "versions"; | 127 | const std::string g_hspList_key_versions = "versions"; |
| 127 | const std::string g_sandboxHspInstallPath = "/data/storage/el1/bundle/"; | 128 | const std::string g_sandboxHspInstallPath = "/data/storage/el1/bundle/"; |
| 128 | 129 | ||
| 130 | +/* IPCGroup */ | ||
| 131 | +const std::string g_ipcGroupSrcPathPrefix = "/mnt/sandbox/shm/"; | ||
| 132 | +const std::string g_ipcGroupSandboxPathPrefix = "/dev/group/shm/"; | ||
| 133 | +const std::string g_ipcGroupList_key_groupId = "ipcGroupId"; | ||
| 134 | +const std::string g_ipcGroupList_key_groupGid = "ipcGroupGid"; | ||
| 135 | + | ||
| 129 | /* DataGroup */ | 136 | /* DataGroup */ |
| 130 | const std::string DATA_GROUP_SOCKET_TYPE = "DataGroup"; | 137 | const std::string DATA_GROUP_SOCKET_TYPE = "DataGroup"; |
| 131 | const std::string g_groupList_key_dataGroupId = "dataGroupId"; | 138 | const std::string g_groupList_key_dataGroupId = "dataGroupId"; |
Mtest/unittest/app_spawn_standard_test/app_spawn_sandbox_normal_test/app_spawn_sandbox_core_test.cpp+697-0
| @@ -18,6 +18,7 @@ | |||
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | + | ||
| 21 | 22 | ||
| 22 | 23 | ||
| 23 | 24 | ||
| @@ -541,4 +542,700 @@ HWTEST_F(AppSpawnSandboxCoreTest, SetPermissionAppSandboxProperty_01, TestSize.L | |||
| 541 | DeleteAppSpawningCtx(appProperty); | 542 | DeleteAppSpawningCtx(appProperty); |
| 542 | } | 543 | } |
| 543 | 544 | ||
| 545 | +/** | ||
low 问题:测试 10/11/15-18 真实创建 /mnt/sandbox/shm/100/group/* 且可能真实 bind mount(设备 root 下 DoAppSandboxMountOnce 非 stub 路径会成功),但仅 rmdir 一层且无 umount,重复执行残留挂载点与父目录。另外测试用硬编码 "IPCGroup" 字符串而非 MSG_EXT_NAME_IPC_GROUP 宏。 证据:MountIPCGroup_10/11 注释自述 mount will likely fail in test env,但设备 root 环境下路径可达时实际会成功。 建议:teardown 中 umount 沙箱内挂载点并递归清理父目录;字符串统一使用宏。 ![]() ![]() | |||
| 546 | + * @tc.name: MountIPCGroup_01 | ||
| 547 | + * @tc.desc: Test MountIPCGroup with appProperty nullptr | ||
| 548 | + * Branch: appProperty == nullptr → return 0 | ||
| 549 | + * @tc.type: FUNC | ||
| 550 | + * @tc.require: issueI5NTX6 | ||
| 551 | + */ | ||
| 552 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_01, TestSize.Level0) | ||
| 553 | +{ | ||
| 554 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 555 | + int ret = AppSpawn::SandboxCore::MountIPCGroup(nullptr, sandboxPackagePath); | ||
| 556 | + EXPECT_EQ(ret, 0); | ||
| 557 | +} | ||
| 558 | + | ||
| 559 | +/** | ||
| 560 | + * @tc.name: MountIPCGroup_02 | ||
| 561 | + * @tc.desc: Test MountIPCGroup with empty sandboxPackagePath | ||
| 562 | + * Branch: sandboxPackagePath == "" → return 0 | ||
| 563 | + * @tc.type: FUNC | ||
| 564 | + * @tc.require: issueI5NTX6 | ||
| 565 | + */ | ||
| 566 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_02, TestSize.Level0) | ||
| 567 | +{ | ||
| 568 | + g_testHelperCore.SetProcessName("com.ohos.test.app"); | ||
| 569 | + g_testHelperCore.SetTestApl("normal"); | ||
| 570 | + | ||
| 571 | + AppSpawningCtx *appProperty = GetTestAppPropertyCore(); | ||
| 572 | + ASSERT_NE(appProperty, nullptr); | ||
| 573 | + | ||
| 574 | + std::string sandboxPackagePath = ""; | ||
| 575 | + int ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 576 | + EXPECT_EQ(ret, 0); | ||
| 577 | + | ||
| 578 | + DeleteAppSpawningCtx(appProperty); | ||
| 579 | +} | ||
| 580 | + | ||
| 581 | +/** | ||
| 582 | + * @tc.name: MountIPCGroup_03 | ||
| 583 | + * @tc.desc: Test MountIPCGroup with no IPCGroup ext info | ||
| 584 | + * Branch: ipcGroupRoot == nullptr → return 0 | ||
| 585 | + * @tc.type: FUNC | ||
| 586 | + * @tc.require: issueI5NTX6 | ||
| 587 | + */ | ||
| 588 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_03, TestSize.Level0) | ||
| 589 | +{ | ||
| 590 | + g_testHelperCore.SetProcessName("com.ohos.test.app"); | ||
| 591 | + g_testHelperCore.SetTestApl("normal"); | ||
| 592 | + | ||
| 593 | + AppSpawningCtx *appProperty = GetTestAppPropertyCore(); | ||
| 594 | + ASSERT_NE(appProperty, nullptr); | ||
| 595 | + | ||
| 596 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 597 | + int ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 598 | + EXPECT_EQ(ret, 0); | ||
| 599 | + | ||
| 600 | + DeleteAppSpawningCtx(appProperty); | ||
| 601 | +} | ||
| 602 | + | ||
| 603 | +/** | ||
| 604 | + * @tc.name: MountIPCGroup_04 | ||
| 605 | + * @tc.desc: Test MountIPCGroup with empty IPCGroup array | ||
| 606 | + * Branch: HandleArrayForeach iterates nothing → return 0 | ||
| 607 | + * @tc.type: FUNC | ||
| 608 | + * @tc.require: issueI5NTX6 | ||
| 609 | + */ | ||
| 610 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_04, TestSize.Level0) | ||
| 611 | +{ | ||
| 612 | + AppSpawnClientHandle clientHandle = nullptr; | ||
| 613 | + int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); | ||
| 614 | + ASSERT_EQ(ret, 0); | ||
| 615 | + AppSpawnReqMsgHandle reqHandle = g_testHelperCore.CreateMsg( | ||
| 616 | + clientHandle, MSG_APP_SPAWN, 0); | ||
| 617 | + ASSERT_NE(reqHandle, INVALID_REQ_HANDLE); | ||
| 618 | + | ||
| 619 | + const char *appGroupInfo = R"([])"; | ||
| 620 | + ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_IPC_GROUP, appGroupInfo); | ||
| 621 | + ASSERT_EQ(ret, 0); | ||
| 622 | + | ||
| 623 | + AppSpawningCtx *appProperty = g_testHelperCore.GetAppProperty( | ||
| 624 | + clientHandle, reqHandle); | ||
| 625 | + ASSERT_NE(appProperty, nullptr); | ||
| 626 | + | ||
| 627 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 628 | + ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 629 | + EXPECT_EQ(ret, 0); | ||
| 630 | + | ||
| 631 | + DeleteAppSpawningCtx(appProperty); | ||
| 632 | +} | ||
| 633 | + | ||
| 634 | +/** | ||
| 635 | + * @tc.name: MountIPCGroup_05 | ||
| 636 | + * @tc.desc: Test MountIPCGroup with array item missing ipcGroupId | ||
| 637 | + * Branch: ProcessIPCGroupItem groupIdItem == nullptr → return -1, abort | ||
| 638 | + * @tc.type: FUNC | ||
| 639 | + * @tc.require: issueI5NTX6 | ||
| 640 | + */ | ||
| 641 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_05, TestSize.Level0) | ||
| 642 | +{ | ||
| 643 | + AppSpawnClientHandle clientHandle = nullptr; | ||
| 644 | + int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); | ||
| 645 | + ASSERT_EQ(ret, 0); | ||
| 646 | + AppSpawnReqMsgHandle reqHandle = g_testHelperCore.CreateMsg( | ||
| 647 | + clientHandle, MSG_APP_SPAWN, 0); | ||
| 648 | + ASSERT_NE(reqHandle, INVALID_REQ_HANDLE); | ||
| 649 | + | ||
| 650 | + const char *appGroupInfo = R"([{"ipcGroupGid":"3000"}])"; | ||
| 651 | + ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_IPC_GROUP, appGroupInfo); | ||
| 652 | + ASSERT_EQ(ret, 0); | ||
| 653 | + | ||
| 654 | + AppSpawningCtx *appProperty = g_testHelperCore.GetAppProperty( | ||
| 655 | + clientHandle, reqHandle); | ||
| 656 | + ASSERT_NE(appProperty, nullptr); | ||
| 657 | + | ||
| 658 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 659 | + ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 660 | + // ProcessIPCGroupItem: groupIdItem == nullptr → return -1, abort | ||
| 661 | + EXPECT_EQ(ret, -1); | ||
| 662 | + | ||
| 663 | + DeleteAppSpawningCtx(appProperty); | ||
| 664 | +} | ||
| 665 | + | ||
| 666 | +/** | ||
| 667 | + * @tc.name: MountIPCGroup_06 | ||
| 668 | + * @tc.desc: Test MountIPCGroup with ipcGroupId as non-string type (number) | ||
| 669 | + * Branch: ProcessIPCGroupItem !cJSON_IsString(groupIdItem) → return -1, abort | ||
| 670 | + * @tc.type: FUNC | ||
| 671 | + * @tc.require: issueI5NTX6 | ||
| 672 | + */ | ||
| 673 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_06, TestSize.Level0) | ||
| 674 | +{ | ||
| 675 | + AppSpawnClientHandle clientHandle = nullptr; | ||
| 676 | + int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); | ||
| 677 | + ASSERT_EQ(ret, 0); | ||
| 678 | + AppSpawnReqMsgHandle reqHandle = g_testHelperCore.CreateMsg( | ||
| 679 | + clientHandle, MSG_APP_SPAWN, 0); | ||
| 680 | + ASSERT_NE(reqHandle, INVALID_REQ_HANDLE); | ||
| 681 | + | ||
| 682 | + const char *appGroupInfo = R"([{"ipcGroupId":12345,"ipcGroupGid":"3000"}])"; | ||
| 683 | + ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_IPC_GROUP, appGroupInfo); | ||
| 684 | + ASSERT_EQ(ret, 0); | ||
| 685 | + | ||
| 686 | + AppSpawningCtx *appProperty = g_testHelperCore.GetAppProperty( | ||
| 687 | + clientHandle, reqHandle); | ||
| 688 | + ASSERT_NE(appProperty, nullptr); | ||
| 689 | + | ||
| 690 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 691 | + ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 692 | + // ProcessIPCGroupItem: !cJSON_IsString → return -1, abort | ||
| 693 | + EXPECT_EQ(ret, -1); | ||
| 694 | + | ||
| 695 | + DeleteAppSpawningCtx(appProperty); | ||
| 696 | +} | ||
| 697 | + | ||
| 698 | +/** | ||
| 699 | + * @tc.name: MountIPCGroup_07 | ||
| 700 | + * @tc.desc: Test MountIPCGroup with empty string ipcGroupId | ||
| 701 | + * Branch: ProcessIPCGroupItem strlen == 0 → return -1, abort | ||
| 702 | + * @tc.type: FUNC | ||
| 703 | + * @tc.require: issueI5NTX6 | ||
| 704 | + */ | ||
| 705 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_07, TestSize.Level0) | ||
| 706 | +{ | ||
| 707 | + AppSpawnClientHandle clientHandle = nullptr; | ||
| 708 | + int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); | ||
| 709 | + ASSERT_EQ(ret, 0); | ||
| 710 | + AppSpawnReqMsgHandle reqHandle = g_testHelperCore.CreateMsg( | ||
| 711 | + clientHandle, MSG_APP_SPAWN, 0); | ||
| 712 | + ASSERT_NE(reqHandle, INVALID_REQ_HANDLE); | ||
| 713 | + | ||
| 714 | + const char *appGroupInfo = R"([{"ipcGroupId":"","ipcGroupGid":"3000"}])"; | ||
| 715 | + ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_IPC_GROUP, appGroupInfo); | ||
| 716 | + ASSERT_EQ(ret, 0); | ||
| 717 | + | ||
| 718 | + AppSpawningCtx *appProperty = g_testHelperCore.GetAppProperty( | ||
| 719 | + clientHandle, reqHandle); | ||
| 720 | + ASSERT_NE(appProperty, nullptr); | ||
| 721 | + | ||
| 722 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 723 | + ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 724 | + // ProcessIPCGroupItem: strlen == 0 → return -1, abort | ||
| 725 | + EXPECT_EQ(ret, -1); | ||
| 726 | + | ||
| 727 | + DeleteAppSpawningCtx(appProperty); | ||
| 728 | +} | ||
| 729 | + | ||
| 730 | +/** | ||
| 731 | + * @tc.name: MountIPCGroup_08 | ||
| 732 | + * @tc.desc: Test MountIPCGroup with array item missing ipcGroupGid | ||
| 733 | + * Branch: ProcessIPCGroupItem groupGidItem == nullptr → return -1, abort | ||
| 734 | + * @tc.type: FUNC | ||
| 735 | + * @tc.require: issueI5NTX6 | ||
| 736 | + */ | ||
| 737 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_08, TestSize.Level0) | ||
| 738 | +{ | ||
| 739 | + AppSpawnClientHandle clientHandle = nullptr; | ||
| 740 | + int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); | ||
| 741 | + ASSERT_EQ(ret, 0); | ||
| 742 | + AppSpawnReqMsgHandle reqHandle = g_testHelperCore.CreateMsg( | ||
| 743 | + clientHandle, MSG_APP_SPAWN, 0); | ||
| 744 | + ASSERT_NE(reqHandle, INVALID_REQ_HANDLE); | ||
| 745 | + | ||
| 746 | + const char *appGroupInfo = R"([{"ipcGroupId":"308"}])"; | ||
| 747 | + ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_IPC_GROUP, appGroupInfo); | ||
| 748 | + ASSERT_EQ(ret, 0); | ||
| 749 | + | ||
| 750 | + AppSpawningCtx *appProperty = g_testHelperCore.GetAppProperty( | ||
| 751 | + clientHandle, reqHandle); | ||
| 752 | + ASSERT_NE(appProperty, nullptr); | ||
| 753 | + | ||
| 754 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 755 | + ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 756 | + // ProcessIPCGroupItem: groupGidItem == nullptr → return -1, abort | ||
| 757 | + EXPECT_EQ(ret, -1); | ||
| 758 | + | ||
| 759 | + DeleteAppSpawningCtx(appProperty); | ||
| 760 | +} | ||
| 761 | + | ||
| 762 | +/** | ||
| 763 | + * @tc.name: MountIPCGroup_09 | ||
| 764 | + * @tc.desc: Test MountIPCGroup with ipcGroupGid as non-string type (number) | ||
| 765 | + * Branch: ProcessIPCGroupItem !cJSON_IsString(groupGidItem) → return -1, abort | ||
| 766 | + * @tc.type: FUNC | ||
| 767 | + * @tc.require: issueI5NTX6 | ||
| 768 | + */ | ||
| 769 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_09, TestSize.Level0) | ||
| 770 | +{ | ||
| 771 | + AppSpawnClientHandle clientHandle = nullptr; | ||
| 772 | + int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); | ||
| 773 | + ASSERT_EQ(ret, 0); | ||
| 774 | + AppSpawnReqMsgHandle reqHandle = g_testHelperCore.CreateMsg( | ||
| 775 | + clientHandle, MSG_APP_SPAWN, 0); | ||
| 776 | + ASSERT_NE(reqHandle, INVALID_REQ_HANDLE); | ||
| 777 | + | ||
| 778 | + const char *appGroupInfo = R"([{"ipcGroupId":"309","ipcGroupGid":3000}])"; | ||
| 779 | + ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_IPC_GROUP, appGroupInfo); | ||
| 780 | + ASSERT_EQ(ret, 0); | ||
| 781 | + | ||
| 782 | + AppSpawningCtx *appProperty = g_testHelperCore.GetAppProperty( | ||
| 783 | + clientHandle, reqHandle); | ||
| 784 | + ASSERT_NE(appProperty, nullptr); | ||
| 785 | + | ||
| 786 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 787 | + ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 788 | + // ProcessIPCGroupItem: !cJSON_IsString(groupGidItem) → return -1, abort | ||
| 789 | + EXPECT_EQ(ret, -1); | ||
| 790 | + | ||
| 791 | + DeleteAppSpawningCtx(appProperty); | ||
| 792 | +} | ||
| 793 | + | ||
| 794 | +/** | ||
| 795 | + * @tc.name: MountIPCGroup_10 | ||
| 796 | + * @tc.desc: Test MountIPCGroup with valid single-element IPCGroup array | ||
| 797 | + * Branch: ProcessIPCGroupItem valid → EnsureDirWithMode + mount → return 0 | ||
| 798 | + * @tc.type: FUNC | ||
| 799 | + * @tc.require: issueI5NTX6 | ||
| 800 | + */ | ||
| 801 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_10, TestSize.Level0) | ||
| 802 | +{ | ||
| 803 | + AppSpawnClientHandle clientHandle = nullptr; | ||
| 804 | + int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); | ||
| 805 | + ASSERT_EQ(ret, 0); | ||
| 806 | + AppSpawnReqMsgHandle reqHandle = g_testHelperCore.CreateMsg( | ||
| 807 | + clientHandle, MSG_APP_SPAWN, 0); | ||
| 808 | + ASSERT_NE(reqHandle, INVALID_REQ_HANDLE); | ||
| 809 | + | ||
| 810 | + const char *appGroupInfo = | ||
| 811 | + R"([{"ipcGroupId":"123","ipcGroupGid":"3000"}])"; | ||
| 812 | + ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_IPC_GROUP, appGroupInfo); | ||
| 813 | + ASSERT_EQ(ret, 0); | ||
| 814 | + | ||
| 815 | + AppSpawningCtx *appProperty = g_testHelperCore.GetAppProperty( | ||
| 816 | + clientHandle, reqHandle); | ||
| 817 | + ASSERT_NE(appProperty, nullptr); | ||
| 818 | + | ||
| 819 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 820 | + ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 821 | + // Valid data: srcPath = /mnt/sandbox/shm/100/group/123 | ||
| 822 | + EXPECT_EQ(ret, 0); | ||
| 823 | + | ||
| 824 | + rmdir("/mnt/sandbox/shm/100/group/123"); | ||
| 825 | + DeleteAppSpawningCtx(appProperty); | ||
| 826 | +} | ||
| 827 | + | ||
| 828 | +/** | ||
| 829 | + * @tc.name: MountIPCGroup_11 | ||
| 830 | + * @tc.desc: Test MountIPCGroup with multi-element IPCGroup array | ||
| 831 | + * Branch: HandleArrayForeach iterates all items, all valid → return 0 | ||
| 832 | + * @tc.type: FUNC | ||
| 833 | + * @tc.require: issueI5NTX6 | ||
| 834 | + */ | ||
| 835 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_11, TestSize.Level0) | ||
| 836 | +{ | ||
| 837 | + AppSpawnClientHandle clientHandle = nullptr; | ||
| 838 | + int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); | ||
| 839 | + ASSERT_EQ(ret, 0); | ||
| 840 | + AppSpawnReqMsgHandle reqHandle = g_testHelperCore.CreateMsg( | ||
| 841 | + clientHandle, MSG_APP_SPAWN, 0); | ||
| 842 | + ASSERT_NE(reqHandle, INVALID_REQ_HANDLE); | ||
| 843 | + | ||
| 844 | + const char *appGroupInfo = | ||
| 845 | + R"([{"ipcGroupId":"133","ipcGroupGid":"3000"},)" | ||
| 846 | + R"({"ipcGroupId":"456","ipcGroupGid":"4000"}])"; | ||
| 847 | + ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_IPC_GROUP, appGroupInfo); | ||
| 848 | + ASSERT_EQ(ret, 0); | ||
| 849 | + | ||
| 850 | + AppSpawningCtx *appProperty = g_testHelperCore.GetAppProperty( | ||
| 851 | + clientHandle, reqHandle); | ||
| 852 | + ASSERT_NE(appProperty, nullptr); | ||
| 853 | + | ||
| 854 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 855 | + ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 856 | + EXPECT_EQ(ret, 0); | ||
| 857 | + | ||
| 858 | + rmdir("/mnt/sandbox/shm/100/group/133"); | ||
| 859 | + rmdir("/mnt/sandbox/shm/100/group/456"); | ||
| 860 | + DeleteAppSpawningCtx(appProperty); | ||
| 861 | +} | ||
| 862 | + | ||
| 863 | +/** | ||
| 864 | + * @tc.name: MountIPCGroup_12 | ||
| 865 | + * @tc.desc: Test MountIPCGroup with first item valid, second item invalid | ||
| 866 | + * Branch: HandleArrayForeach aborts on second item → return -1 | ||
| 867 | + * @tc.type: FUNC | ||
| 868 | + * @tc.require: issueI5NTX6 | ||
| 869 | + */ | ||
| 870 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_12, TestSize.Level0) | ||
| 871 | +{ | ||
| 872 | + AppSpawnClientHandle clientHandle = nullptr; | ||
| 873 | + int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); | ||
| 874 | + ASSERT_EQ(ret, 0); | ||
| 875 | + AppSpawnReqMsgHandle reqHandle = g_testHelperCore.CreateMsg( | ||
| 876 | + clientHandle, MSG_APP_SPAWN, 0); | ||
| 877 | + ASSERT_NE(reqHandle, INVALID_REQ_HANDLE); | ||
| 878 | + | ||
| 879 | + const char *appGroupInfo = | ||
| 880 | + R"([{"ipcGroupId":"140","ipcGroupGid":"3000"},)" | ||
| 881 | + R"({"ipcGroupId":"abc","ipcGroupGid":"4000"}])"; | ||
| 882 | + ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_IPC_GROUP, appGroupInfo); | ||
| 883 | + ASSERT_EQ(ret, 0); | ||
| 884 | + | ||
| 885 | + AppSpawningCtx *appProperty = g_testHelperCore.GetAppProperty( | ||
| 886 | + clientHandle, reqHandle); | ||
| 887 | + ASSERT_NE(appProperty, nullptr); | ||
| 888 | + | ||
| 889 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 890 | + ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 891 | + // item 0 valid → return 0, item 1 non-numeric groupId → return -1 → abort | ||
| 892 | + EXPECT_EQ(ret, -1); | ||
| 893 | + | ||
| 894 | + rmdir("/mnt/sandbox/shm/100/group/140"); | ||
| 895 | + DeleteAppSpawningCtx(appProperty); | ||
| 896 | +} | ||
| 897 | + | ||
| 898 | +/** | ||
| 899 | + * @tc.name: MountIPCGroup_13 | ||
| 900 | + * @tc.desc: Test MountIPCGroup with ipcGroupGid as non-numeric string | ||
| 901 | + * Branch: ProcessIPCGroupItem atoi == 0 → groupGid == 0 → return -1, abort | ||
| 902 | + * @tc.type: FUNC | ||
| 903 | + * @tc.require: issueI5NTX6 | ||
| 904 | + */ | ||
| 905 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_13, TestSize.Level0) | ||
| 906 | +{ | ||
| 907 | + AppSpawnClientHandle clientHandle = nullptr; | ||
| 908 | + int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); | ||
| 909 | + ASSERT_EQ(ret, 0); | ||
| 910 | + AppSpawnReqMsgHandle reqHandle = g_testHelperCore.CreateMsg( | ||
| 911 | + clientHandle, MSG_APP_SPAWN, 0); | ||
| 912 | + ASSERT_NE(reqHandle, INVALID_REQ_HANDLE); | ||
| 913 | + | ||
| 914 | + const char *appGroupInfo = | ||
| 915 | + R"([{"ipcGroupId":"312","ipcGroupGid":"not_a_number"}])"; | ||
| 916 | + ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_IPC_GROUP, appGroupInfo); | ||
| 917 | + ASSERT_EQ(ret, 0); | ||
| 918 | + | ||
| 919 | + AppSpawningCtx *appProperty = g_testHelperCore.GetAppProperty( | ||
| 920 | + clientHandle, reqHandle); | ||
| 921 | + ASSERT_NE(appProperty, nullptr); | ||
| 922 | + | ||
| 923 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 924 | + ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 925 | + // ProcessIPCGroupItem: atoi == 0 → groupGid == 0 → return -1, abort | ||
| 926 | + EXPECT_EQ(ret, -1); | ||
| 927 | + | ||
| 928 | + DeleteAppSpawningCtx(appProperty); | ||
| 929 | +} | ||
| 930 | + | ||
| 931 | +/** | ||
| 932 | + * @tc.name: MountIPCGroup_14 | ||
| 933 | + * @tc.desc: Test MountIPCGroup with non-numeric ipcGroupId | ||
| 934 | + * Branch: ProcessIPCGroupItem find_first_not_of != npos → return -1, abort | ||
| 935 | + * @tc.type: FUNC | ||
| 936 | + * @tc.require: issueI5NTX6 | ||
| 937 | + */ | ||
| 938 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_14, TestSize.Level0) | ||
| 939 | +{ | ||
| 940 | + AppSpawnClientHandle clientHandle = nullptr; | ||
| 941 | + int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); | ||
| 942 | + ASSERT_EQ(ret, 0); | ||
| 943 | + AppSpawnReqMsgHandle reqHandle = g_testHelperCore.CreateMsg( | ||
| 944 | + clientHandle, MSG_APP_SPAWN, 0); | ||
| 945 | + ASSERT_NE(reqHandle, INVALID_REQ_HANDLE); | ||
| 946 | + | ||
| 947 | + const char *appGroupInfo = | ||
| 948 | + R"([{"ipcGroupId":"123abc","ipcGroupGid":"3000"}])"; | ||
| 949 | + ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_IPC_GROUP, appGroupInfo); | ||
| 950 | + ASSERT_EQ(ret, 0); | ||
| 951 | + | ||
| 952 | + AppSpawningCtx *appProperty = g_testHelperCore.GetAppProperty( | ||
| 953 | + clientHandle, reqHandle); | ||
| 954 | + ASSERT_NE(appProperty, nullptr); | ||
| 955 | + | ||
| 956 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 957 | + ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 958 | + // ProcessIPCGroupItem: non-numeric groupId → return -1, abort | ||
| 959 | + EXPECT_EQ(ret, -1); | ||
| 960 | + | ||
| 961 | + DeleteAppSpawningCtx(appProperty); | ||
| 962 | +} | ||
| 963 | + | ||
| 964 | +/** | ||
| 965 | + * @tc.name: MountIPCGroup_15 | ||
| 966 | + * @tc.desc: Test MountIPCGroup with appProperty missing DAC info | ||
| 967 | + * Branch: dacInfo == nullptr → cJSON_Delete + return 0 | ||
| 968 | + * @tc.type: FUNC | ||
| 969 | + * @tc.require: issueI5NTX6 | ||
| 970 | + */ | ||
| 971 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_15, TestSize.Level0) | ||
| 972 | +{ | ||
| 973 | + AppSpawnClientHandle clientHandle = nullptr; | ||
| 974 | + int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); | ||
| 975 | + ASSERT_EQ(ret, 0); | ||
| 976 | + // MSG_DUMP: valid msgType but not spawn type → CreateMsg skips AddDacInfo → no TLV_DAC_INFO | ||
| 977 | + AppSpawnReqMsgHandle reqHandle = g_testHelperCore.CreateMsg( | ||
| 978 | + clientHandle, MSG_DUMP, 0); | ||
| 979 | + ASSERT_NE(reqHandle, INVALID_REQ_HANDLE); | ||
| 980 | + | ||
| 981 | + const char *appGroupInfo = | ||
| 982 | + R"([{"ipcGroupId":"316","ipcGroupGid":"3000"}])"; | ||
| 983 | + ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_IPC_GROUP, appGroupInfo); | ||
| 984 | + ASSERT_EQ(ret, 0); | ||
| 985 | + | ||
| 986 | + AppSpawningCtx *appProperty = g_testHelperCore.GetAppProperty( | ||
| 987 | + clientHandle, reqHandle); | ||
| 988 | + ASSERT_NE(appProperty, nullptr); | ||
| 989 | + | ||
| 990 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 991 | + ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 992 | + // dacInfo == nullptr → cJSON_Delete + return 0, HandleArrayForeach not reached | ||
| 993 | + EXPECT_EQ(ret, 0); | ||
| 994 | + | ||
| 995 | + DeleteAppSpawningCtx(appProperty); | ||
| 996 | +} | ||
| 997 | + | ||
| 998 | +/** | ||
| 999 | + * @tc.name: MountIPCGroup_16 | ||
| 1000 | + * @tc.desc: Test MountIPCGroup with pre-existing src dir owned by non-root | ||
| 1001 | + * Branch: EnsureDirWithMode stat ok, uid mismatch → recreate → mount → return 0 | ||
| 1002 | + * @tc.type: FUNC | ||
| 1003 | + * @tc.require: issueI5NTX6 | ||
| 1004 | + */ | ||
| 1005 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_16, TestSize.Level0) | ||
| 1006 | +{ | ||
| 1007 | + AppSpawnClientHandle clientHandle = nullptr; | ||
| 1008 | + int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); | ||
| 1009 | + ASSERT_EQ(ret, 0); | ||
| 1010 | + AppSpawnReqMsgHandle reqHandle = g_testHelperCore.CreateMsg( | ||
| 1011 | + clientHandle, MSG_APP_SPAWN, 0); | ||
| 1012 | + ASSERT_NE(reqHandle, INVALID_REQ_HANDLE); | ||
| 1013 | + | ||
| 1014 | + const char *appGroupInfo = | ||
| 1015 | + R"([{"ipcGroupId":"3017","ipcGroupGid":"3000"}])"; | ||
| 1016 | + ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_IPC_GROUP, appGroupInfo); | ||
| 1017 | + ASSERT_EQ(ret, 0); | ||
| 1018 | + | ||
| 1019 | + AppSpawningCtx *appProperty = g_testHelperCore.GetAppProperty( | ||
| 1020 | + clientHandle, reqHandle); | ||
| 1021 | + ASSERT_NE(appProperty, nullptr); | ||
| 1022 | + | ||
| 1023 | + // Pre-create src dir with wrong owner (uid=1000, not root) | ||
| 1024 | + std::string srcPath = "/mnt/sandbox/shm/100/group/3017"; | ||
| 1025 | + SandboxCommon::CreateDirRecursive(srcPath, SandboxCommonDef::FILE_MODE); | ||
| 1026 | + chown(srcPath.c_str(), 1000, 1000); | ||
| 1027 | + | ||
| 1028 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 1029 | + ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 1030 | + // EnsureDirWithMode: stat ok, uid=1000 != 0 → recreate → mount → ret=0 | ||
| 1031 | + EXPECT_EQ(ret, 0); | ||
| 1032 | + | ||
| 1033 | + rmdir(srcPath.c_str()); | ||
| 1034 | + DeleteAppSpawningCtx(appProperty); | ||
| 1035 | +} | ||
| 1036 | + | ||
| 1037 | +/** | ||
| 1038 | + * @tc.name: MountIPCGroup_17 | ||
| 1039 | + * @tc.desc: Test MountIPCGroup with pre-existing src dir, correct uid but wrong gid | ||
| 1040 | + * Branch: EnsureDirWithMode stat ok, gid mismatch → recreate → mount → return 0 | ||
| 1041 | + * @tc.type: FUNC | ||
| 1042 | + * @tc.require: issueI5NTX6 | ||
| 1043 | + */ | ||
| 1044 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_17, TestSize.Level0) | ||
| 1045 | +{ | ||
| 1046 | + AppSpawnClientHandle clientHandle = nullptr; | ||
| 1047 | + int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); | ||
| 1048 | + ASSERT_EQ(ret, 0); | ||
| 1049 | + AppSpawnReqMsgHandle reqHandle = g_testHelperCore.CreateMsg( | ||
| 1050 | + clientHandle, MSG_APP_SPAWN, 0); | ||
| 1051 | + ASSERT_NE(reqHandle, INVALID_REQ_HANDLE); | ||
| 1052 | + | ||
| 1053 | + const char *appGroupInfo = | ||
| 1054 | + R"([{"ipcGroupId":"3018","ipcGroupGid":"3000"}])"; | ||
| 1055 | + ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_IPC_GROUP, appGroupInfo); | ||
| 1056 | + ASSERT_EQ(ret, 0); | ||
| 1057 | + | ||
| 1058 | + AppSpawningCtx *appProperty = g_testHelperCore.GetAppProperty( | ||
| 1059 | + clientHandle, reqHandle); | ||
| 1060 | + ASSERT_NE(appProperty, nullptr); | ||
| 1061 | + | ||
| 1062 | + // Pre-create src dir as root → uid=0, gid=0 (gid != groupGid 3000) | ||
| 1063 | + std::string srcPath = "/mnt/sandbox/shm/100/group/3018"; | ||
| 1064 | + SandboxCommon::CreateDirRecursive(srcPath, SandboxCommonDef::FILE_MODE); | ||
| 1065 | + | ||
| 1066 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 1067 | + ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 1068 | + // EnsureDirWithMode: stat ok, uid==0, gid=0 != 3000 → recreate → mount → ret=0 | ||
| 1069 | + EXPECT_EQ(ret, 0); | ||
| 1070 | + | ||
| 1071 | + rmdir(srcPath.c_str()); | ||
| 1072 | + DeleteAppSpawningCtx(appProperty); | ||
| 1073 | +} | ||
| 1074 | + | ||
| 1075 | +/** | ||
| 1076 | + * @tc.name: MountIPCGroup_18 | ||
| 1077 | + * @tc.desc: Test MountIPCGroup with pre-existing src dir, correct owner but wrong mode | ||
| 1078 | + * Branch: EnsureDirWithMode stat ok, mode mismatch → recreate → mount → return 0 | ||
| 1079 | + * @tc.type: FUNC | ||
| 1080 | + * @tc.require: issueI5NTX6 | ||
| 1081 | + */ | ||
| 1082 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_18, TestSize.Level0) | ||
| 1083 | +{ | ||
| 1084 | + AppSpawnClientHandle clientHandle = nullptr; | ||
| 1085 | + int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); | ||
| 1086 | + ASSERT_EQ(ret, 0); | ||
| 1087 | + AppSpawnReqMsgHandle reqHandle = g_testHelperCore.CreateMsg( | ||
| 1088 | + clientHandle, MSG_APP_SPAWN, 0); | ||
| 1089 | + ASSERT_NE(reqHandle, INVALID_REQ_HANDLE); | ||
| 1090 | + | ||
| 1091 | + const char *appGroupInfo = | ||
| 1092 | + R"([{"ipcGroupId":"3019","ipcGroupGid":"3000"}])"; | ||
| 1093 | + ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_IPC_GROUP, appGroupInfo); | ||
| 1094 | + ASSERT_EQ(ret, 0); | ||
| 1095 | + | ||
| 1096 | + AppSpawningCtx *appProperty = g_testHelperCore.GetAppProperty( | ||
| 1097 | + clientHandle, reqHandle); | ||
| 1098 | + ASSERT_NE(appProperty, nullptr); | ||
| 1099 | + | ||
| 1100 | + // Pre-create src dir with correct owner but wrong mode | ||
| 1101 | + std::string srcPath = "/mnt/sandbox/shm/100/group/3019"; | ||
| 1102 | + SandboxCommon::CreateDirRecursive(srcPath, SandboxCommonDef::FILE_MODE); | ||
| 1103 | + chown(srcPath.c_str(), 0, 3000); | ||
| 1104 | + chmod(srcPath.c_str(), 0755); | ||
| 1105 | + | ||
| 1106 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 1107 | + ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 1108 | + // EnsureDirWithMode: stat ok, uid==0, gid==3000, mode=0755 != 01771 → recreate → mount → ret=0 | ||
| 1109 | + EXPECT_EQ(ret, 0); | ||
| 1110 | + | ||
| 1111 | + rmdir(srcPath.c_str()); | ||
| 1112 | + DeleteAppSpawningCtx(appProperty); | ||
| 1113 | +} | ||
| 1114 | + | ||
| 1115 | +/** | ||
| 1116 | + * @tc.name: MountIPCGroup_19 | ||
| 1117 | + * @tc.desc: Test MountIPCGroup with pre-existing src dir, all metadata correct | ||
| 1118 | + * Branch: EnsureDirWithMode stat ok, all match → skip creation → mount → return 0 | ||
| 1119 | + * @tc.type: FUNC | ||
| 1120 | + * @tc.require: issueI5NTX6 | ||
| 1121 | + */ | ||
| 1122 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_19, TestSize.Level0) | ||
| 1123 | +{ | ||
| 1124 | + AppSpawnClientHandle clientHandle = nullptr; | ||
| 1125 | + int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); | ||
| 1126 | + ASSERT_EQ(ret, 0); | ||
| 1127 | + AppSpawnReqMsgHandle reqHandle = g_testHelperCore.CreateMsg( | ||
| 1128 | + clientHandle, MSG_APP_SPAWN, 0); | ||
| 1129 | + ASSERT_NE(reqHandle, INVALID_REQ_HANDLE); | ||
| 1130 | + | ||
| 1131 | + const char *appGroupInfo = | ||
| 1132 | + R"([{"ipcGroupId":"3020","ipcGroupGid":"3000"}])"; | ||
| 1133 | + ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_IPC_GROUP, appGroupInfo); | ||
| 1134 | + ASSERT_EQ(ret, 0); | ||
| 1135 | + | ||
| 1136 | + AppSpawningCtx *appProperty = g_testHelperCore.GetAppProperty( | ||
| 1137 | + clientHandle, reqHandle); | ||
| 1138 | + ASSERT_NE(appProperty, nullptr); | ||
| 1139 | + | ||
| 1140 | + // Pre-create src dir with fully correct metadata | ||
| 1141 | + std::string srcPath = "/mnt/sandbox/shm/100/group/3020"; | ||
| 1142 | + SandboxCommon::CreateDirRecursive(srcPath, SandboxCommonDef::FILE_MODE); | ||
| 1143 | + chown(srcPath.c_str(), 0, 3000); | ||
| 1144 | + chmod(srcPath.c_str(), SandboxCommonDef::IPC_GROUP_SRC_PATH_MODE); | ||
| 1145 | + | ||
| 1146 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 1147 | + ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 1148 | + // EnsureDirWithMode: stat ok, all match → skip creation → mount → ret=0 | ||
| 1149 | + EXPECT_EQ(ret, 0); | ||
| 1150 | + | ||
| 1151 | + rmdir(srcPath.c_str()); | ||
| 1152 | + DeleteAppSpawningCtx(appProperty); | ||
| 1153 | +} | ||
| 1154 | + | ||
| 1155 | +/** | ||
| 1156 | + * @tc.name: MountIPCGroup_20 | ||
| 1157 | + * @tc.desc: Test MountIPCGroup with mount failure (non-fatal) | ||
| 1158 | + * Branch: ProcessIPCGroupItem mount fails → log only, return 0 (continue) | ||
| 1159 | + * @tc.type: FUNC | ||
| 1160 | + * @tc.require: issueI5NTX6 | ||
| 1161 | + */ | ||
| 1162 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_20, TestSize.Level0) | ||
| 1163 | +{ | ||
| 1164 | + AppSpawnClientHandle clientHandle = nullptr; | ||
| 1165 | + int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); | ||
| 1166 | + ASSERT_EQ(ret, 0); | ||
| 1167 | + AppSpawnReqMsgHandle reqHandle = g_testHelperCore.CreateMsg( | ||
| 1168 | + clientHandle, MSG_APP_SPAWN, 0); | ||
| 1169 | + ASSERT_NE(reqHandle, INVALID_REQ_HANDLE); | ||
| 1170 | + | ||
| 1171 | + const char *appGroupInfo = | ||
| 1172 | + R"([{"ipcGroupId":"3021","ipcGroupGid":"3000"}])"; | ||
| 1173 | + ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_IPC_GROUP, appGroupInfo); | ||
| 1174 | + ASSERT_EQ(ret, 0); | ||
| 1175 | + | ||
| 1176 | + AppSpawningCtx *appProperty = g_testHelperCore.GetAppProperty( | ||
| 1177 | + clientHandle, reqHandle); | ||
| 1178 | + ASSERT_NE(appProperty, nullptr); | ||
| 1179 | + | ||
| 1180 | + // Configure MountStub to return failure: | ||
| 1181 | + // originPath must MATCH the actual srcPath so the if-check passes, | ||
| 1182 | + // then destinationPath mismatches → result=0 → errno=-EINVAL → mount fails | ||
| 1183 | + StubNode *node = GetStubNode(STUB_MOUNT); | ||
| 1184 | + MountTestArg mountArg = { | ||
| 1185 | + "/mnt/sandbox/shm/100/group/3021", // matches actual srcPath | ||
| 1186 | + "/wrong_dest", // mismatches actual destPath → failure | ||
| 1187 | + "", // fsType (non-NULL, printf-safe) | ||
| 1188 | + 0, // mountFlags (mismatches MS_REC|MS_BIND) | ||
| 1189 | + "", // options (non-NULL, printf-safe) | ||
| 1190 | + 0 // mountSharedFlag | ||
| 1191 | + }; | ||
| 1192 | + node->arg = &mountArg; | ||
| 1193 | + node->flags |= STUB_NEED_CHECK; | ||
| 1194 | + | ||
| 1195 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 1196 | + ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 1197 | + // mount fails → log only, return 0 (continue) → ret stays 0 | ||
| 1198 | + EXPECT_EQ(ret, 0); | ||
| 1199 | + | ||
| 1200 | + // Restore MountStub | ||
| 1201 | + node->flags &= ~STUB_NEED_CHECK; | ||
| 1202 | + node->arg = nullptr; | ||
| 1203 | + | ||
| 1204 | + // Cleanup | ||
| 1205 | + rmdir("/mnt/sandbox/shm/100/group/3021"); | ||
| 1206 | + DeleteAppSpawningCtx(appProperty); | ||
| 1207 | +} | ||
| 1208 | + | ||
| 1209 | +/** | ||
| 1210 | + * @tc.name: MountIPCGroup_21 | ||
| 1211 | + * @tc.desc: Test MountIPCGroup with IPCGroup ext info not an array | ||
| 1212 | + * Branch: !cJSON_IsArray(ipcGroupRoot) → cJSON_Delete + return 0 | ||
| 1213 | + * @tc.type: FUNC | ||
| 1214 | + * @tc.require: issueI5NTX6 | ||
| 1215 | + */ | ||
| 1216 | +HWTEST_F(AppSpawnSandboxCoreTest, MountIPCGroup_21, TestSize.Level0) | ||
| 1217 | +{ | ||
| 1218 | + AppSpawnClientHandle clientHandle = nullptr; | ||
| 1219 | + int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); | ||
| 1220 | + ASSERT_EQ(ret, 0); | ||
| 1221 | + AppSpawnReqMsgHandle reqHandle = g_testHelperCore.CreateMsg( | ||
| 1222 | + clientHandle, MSG_APP_SPAWN, 0); | ||
| 1223 | + ASSERT_NE(reqHandle, INVALID_REQ_HANDLE); | ||
| 1224 | + | ||
| 1225 | + const char *appGroupInfo = R"({})"; | ||
| 1226 | + ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_IPC_GROUP, appGroupInfo); | ||
| 1227 | + ASSERT_EQ(ret, 0); | ||
| 1228 | + | ||
| 1229 | + AppSpawningCtx *appProperty = g_testHelperCore.GetAppProperty( | ||
| 1230 | + clientHandle, reqHandle); | ||
| 1231 | + ASSERT_NE(appProperty, nullptr); | ||
| 1232 | + | ||
| 1233 | + std::string sandboxPackagePath = "/mnt/sandbox/100/com.test.app"; | ||
| 1234 | + ret = AppSpawn::SandboxCore::MountIPCGroup(appProperty, sandboxPackagePath); | ||
| 1235 | + // !cJSON_IsArray → cJSON_Delete + return 0 | ||
| 1236 | + EXPECT_EQ(ret, 0); | ||
| 1237 | + | ||
| 1238 | + DeleteAppSpawningCtx(appProperty); | ||
| 1239 | +} | ||
| 1240 | + | ||
| 544 | } // namespace OHOS | 1241 | } // namespace OHOS |


medium
modules/sandbox/normal/sandbox_core.cpp:507问题:EnsureDirWithMode 中 chmod/chown 失败仅打日志后 return 0。IPCGroup 目录权限为 01771(sticky+setgid),属主/属组错误意味着共享内存的组内互访边界被破坏,但挂载照常完成,应用无感知。
证据:失败分支只 LOGE 后落到 return 0,调用方 EnsureDirWithMode(...) != 0 的检查在该路径永远不触发。
建议:IPCGroup 场景下 chmod/chown 失败应返回错误并跳过该项挂载,或至少提供可观测的上报手段。