diff --git a/appdata-sandbox.json b/appdata-sandbox.json index 0df25f75577ffff22aafb88ce3f7342fa374941c..5f020c72ac0c827850be30352ce932c9248f4cb8 100755 --- a/appdata-sandbox.json +++ b/appdata-sandbox.json @@ -1090,6 +1090,21 @@ "sandbox-path": "/storage/hmdfs", "sandbox-flags": ["bind", "rec"], "check-action-status": "false" + }, + { + "src-path": "", + "sandbox-path": "", + "sandbox-flags": [], + "deny-paths": [ + "/storage/Users//Download", + "/storage/Users//Desktop", + "/storage/Users//Documents" + ], + "deny-perm-deps": [ + "ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY", + "ohos.permission.READ_WRITE_DESKTOP_DIRECTORY", + "ohos.permission.READ_WRITE_DOCUMENTS_DIRECTORY" + ] } ] }], diff --git a/modules/sandbox/sandbox_dec.c b/modules/sandbox/sandbox_dec.c index 1a00b622bff4bcef365b72ddbee90f962bc87013..cc1e74eba50e22a971e164d311c0fb2000c0603d 100644 --- a/modules/sandbox/sandbox_dec.c +++ b/modules/sandbox/sandbox_dec.c @@ -89,7 +89,7 @@ void SetDecPolicyInfos(DecPolicyInfo *decPolicyInfos) return; } pathInfo.pathLen = (uint32_t)strlen(pathInfo.path); - pathInfo.mode = SANDBOX_MODE_WRITE | SANDBOX_MODE_READ; + pathInfo.mode = decPolicyInfos->path[i].mode; uint32_t index = g_decPolicyInfos->pathNum + i; g_decPolicyInfos->path[index] = pathInfo; } @@ -191,7 +191,8 @@ void SetDecPolicy(void) } else { APPSPAWN_LOGI("set SET_DEC_POLICY_CMD sandbox policy success. timestamp:%{public}" PRId64 "", timestamp); for (uint32_t i = 0; i < g_decPolicyInfos->pathNum; i++) { - APPSPAWN_LOGI("policy info: %{public}s", g_decPolicyInfos->path[i].path); + APPSPAWN_LOGI("policy info: path %{public}s, mode 0x%{public}x", + g_decPolicyInfos->path[i].path, g_decPolicyInfos->path[i].mode); } } close(fd); diff --git a/modules/sandbox/sandbox_dec.h b/modules/sandbox/sandbox_dec.h index eda4d839ed364d28c168170cd9c1ff2d5a59373f..b65a4ea4229be01ebc590777623ac5d35e1bb304 100644 --- a/modules/sandbox/sandbox_dec.h +++ b/modules/sandbox/sandbox_dec.h @@ -51,6 +51,8 @@ extern "C" { #define MAX_POLICY_NUM 8 #define SANDBOX_MODE_READ 0x00000001 #define SANDBOX_MODE_WRITE (SANDBOX_MODE_READ << 1) +#define DEC_MODE_DENY_READ (1 << 5) +#define DEC_MODE_DENY_WRITE (1 << 6) #define DEC_POLICY_HEADER_RESERVED 64 diff --git a/modules/sandbox/sandbox_utils.cpp b/modules/sandbox/sandbox_utils.cpp index 1187e9e46a7c9c7b8cecac04ea441f91426540ea..2ee57c9af89aa33e330dab8fcdb7e210c87e0d36 100644 --- a/modules/sandbox/sandbox_utils.cpp +++ b/modules/sandbox/sandbox_utils.cpp @@ -125,6 +125,8 @@ namespace { const char *g_sandBoxShared = "sandbox-shared"; const char *g_sandBoxSwitchPrefix = "sandbox-switch"; const char *g_sandBoxDecPath = "dec-paths"; + const char *g_sandBoxDenyPath = "deny-paths"; + const char *g_sandBoxDenyPermDeps = "deny-perm-deps"; const char *g_symlinkPrefix = "symbol-links"; const char *g_sandboxRootPrefix = "sandbox-root"; const char *g_topSandBoxSwitchPrefix = "top-sandbox-switch"; @@ -906,6 +908,34 @@ std::vector SandboxUtils::GetSandboxDecPath(const AppSpawningCtx *a return decPaths; } +std::vector SandboxUtils::GetSandboxDenyPath(const AppSpawningCtx *appProperty, nlohmann::json &config) +{ + AppSpawnMsgDacInfo *dacInfo = reinterpret_cast(GetAppProperty(appProperty, TLV_DAC_INFO)); + if (dacInfo == nullptr) { + return {}; + } + + std::vector denyPaths = {}; + if (config.find(g_sandBoxDenyPath) != config.end()) { + for (auto denyPath : config[g_sandBoxDenyPath].get>()) { + denyPath = ConvertToRealPathWithPermission(appProperty, denyPath); + denyPaths.push_back(denyPath); + } + } + return denyPaths; +} + +std::vector SandboxUtils::GetSandboxDenyPermDeps(const AppSpawningCtx *appProperty, nlohmann::json &config) +{ + std::vector denyPermDeps = {}; + if (config.find(g_sandBoxDenyPermDeps) != config.end()) { + for (auto denyPermDep : config[g_sandBoxDenyPermDeps].get>()) { + denyPermDeps.push_back(denyPermDep); + } + } + return denyPermDeps; +} + void SandboxUtils::GetSandboxMountConfig(const AppSpawningCtx *appProperty, const std::string §ion, nlohmann::json &mntPoint, SandboxMountConfig &mountConfig) { @@ -913,6 +943,8 @@ void SandboxUtils::GetSandboxMountConfig(const AppSpawningCtx *appProperty, cons mountConfig.optionsPoint = GetSandboxOptions(appProperty, mntPoint); mountConfig.fsType = GetSandboxFsType(mntPoint); mountConfig.decPaths = GetSandboxDecPath(appProperty, mntPoint); + mountConfig.denyPaths = GetSandboxDenyPath(appProperty, mntPoint); + mountConfig.denyPermDeps = GetSandboxDenyPermDeps(appProperty, mntPoint); } else { mountConfig.fsType = (mntPoint.find(g_fsType) != mntPoint.end()) ? mntPoint[g_fsType].get() : ""; mountConfig.optionsPoint = ""; @@ -1027,6 +1059,45 @@ EXIT: return ret; } +void SandboxUtils::SetDecDenyWithPermission(const AppSpawningCtx *appProperty, SandboxMountConfig &mountConfig) +{ + unsigned int denyPathSize = mountConfig.denyPaths.size(); + unsigned int permDepSize = mountConfig.denyPermDeps.size(); + if (denyPathSize == 0) { + return; + } + if (permDepSize != 0 && permDepSize != denyPathSize) { + APPSPAWN_LOGW("deny-perm-deps is configured, but the numbers of deny-perm-deps and deny-paths are not equal"); + return; + } + + AppSpawnMsgAccessToken *tokenInfo = + reinterpret_cast(GetAppProperty(appProperty, TLV_ACCESS_TOKEN_INFO)); + APPSPAWN_CHECK(tokenInfo != NULL, return, "Get token id failed"); + + DecPolicyInfo decPolicyInfo = {0}; + decPolicyInfo.pathNum = 0; + for (uint32_t i = 0, j = 0; i < denyPathSize; i++) { + // If deny-perm-deps is configured, set deny rules only when the app doesn't have the corresponding permission + if (permDepSize != 0 && permDepSize == denyPathSize) { + int32_t index = GetPermissionIndex(nullptr, mountConfig.denyPermDeps[i].c_str()); + if (index > 0 && CheckAppPermissionFlagSet(appProperty, static_cast(index))) { + APPSPAWN_LOGV("The app has %{public}s, don't set deny rules", mountConfig.denyPermDeps[i].c_str()); + continue; + } + } + PathInfo pathInfo = {0}; + pathInfo.path = const_cast(mountConfig.denyPaths[i].c_str()); + pathInfo.pathLen = static_cast(strlen(pathInfo.path)); + pathInfo.mode = DEC_MODE_DENY_READ | DEC_MODE_DENY_WRITE; + decPolicyInfo.path[j++] = pathInfo; + decPolicyInfo.pathNum += 1; + } + decPolicyInfo.tokenId = tokenInfo->accessTokenIdEx; + decPolicyInfo.flag = true; + SetDecPolicyInfos(&decPolicyInfo); +} + static bool GetCheckStatus(nlohmann::json &mntPoint) { std::string value = g_statusCheck; @@ -1095,6 +1166,7 @@ int SandboxUtils::DoAllMntPointsMount(const AppSpawningCtx *appProperty, return ret, "DoAppSandboxMountOnce section %{public}s failed, %{public}s", section.c_str(), arg.destPath); SetDecPolicyWithPermission(appProperty, mountConfig); + SetDecDenyWithPermission(appProperty, mountConfig); DoSandboxChmod(mntPoint, sandboxRoot); } return 0; @@ -1189,14 +1261,15 @@ int32_t SandboxUtils::DoSandboxFilePermissionBind(AppSpawningCtx *appProperty, for (nlohmann::json::iterator it = permissionAppConfig.begin(); it != permissionAppConfig.end(); ++it) { const std::string permission = it.key(); int index = GetPermissionIndex(nullptr, permission.c_str()); - APPSPAWN_LOGV("DoSandboxFilePermissionBind mountPermissionFlags %{public}d", index); if (CheckAppPermissionFlagSet(appProperty, static_cast(index))) { + APPSPAWN_LOGV("DoSandboxFilePermissionBind true %{public}s has %{public}s permIndex %{public}d", + GetBundleName(appProperty), permission.c_str(), index); DoAddGid(appProperty, permissionAppConfig[permission][0], permission.c_str(), g_permissionPrefix); DoAllMntPointsMount(appProperty, permissionAppConfig[permission][0], permission.c_str(), g_permissionPrefix); } else { - APPSPAWN_LOGV("DoSandboxFilePermissionBind false %{public}s permission %{public}s", - GetBundleName(appProperty), permission.c_str()); + APPSPAWN_LOGV("DoSandboxFilePermissionBind false %{public}s doesn't have %{public}s permIndex %{public}d", + GetBundleName(appProperty), permission.c_str(), index); } } return 0; diff --git a/modules/sandbox/sandbox_utils.h b/modules/sandbox/sandbox_utils.h index 145e75337c93f64728c97e6398f3c55b426d3dba..f24695e424b5523ba7fa46386e5a4b6ab5fbb122 100755 --- a/modules/sandbox/sandbox_utils.h +++ b/modules/sandbox/sandbox_utils.h @@ -48,6 +48,8 @@ public: std::string fsType; std::string sandboxPath; std::vector decPaths; + std::vector denyPaths; + std::vector denyPermDeps; } SandboxMountConfig; #ifndef APPSPAWN_TEST @@ -75,6 +77,7 @@ private: static int32_t DoSandboxRootFolderCreate(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath); static int32_t SetDecPolicyWithPermission(const AppSpawningCtx *appProperty, SandboxMountConfig &mountConfig); + static void SetDecDenyWithPermission(const AppSpawningCtx *appProperty, SandboxMountConfig &mountConfig); static int32_t SetDecWithDir(const AppSpawningCtx *appProperty, uint32_t userId); static void DoSandboxChmod(nlohmann::json jsonConfig, std::string &sandboxRoot); static int DoAllMntPointsMount(const AppSpawningCtx *appProperty, @@ -119,6 +122,8 @@ private: static std::string GetSandboxFsType(nlohmann::json &config); static std::string GetSandboxOptions(const AppSpawningCtx *appProperty, nlohmann::json &config); static std::vector GetSandboxDecPath(const AppSpawningCtx *appProperty, nlohmann::json &config); + static std::vector GetSandboxDenyPath(const AppSpawningCtx *appProperty, nlohmann::json &config); + static std::vector GetSandboxDenyPermDeps(const AppSpawningCtx *appProperty, nlohmann::json &config); static std::string GetSandboxPath(const AppSpawningCtx *appProperty, nlohmann::json &mntPoint, const std::string §ion, std::string sandboxRoot); static void GetSandboxMountConfig(const AppSpawningCtx *appProperty, const std::string §ion, 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 18a7ebdb3e39dded6ae3d062882679427b3ec630..57b86460a5928420c4c6906f3b77f98ad4a55467 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 @@ -1720,6 +1720,172 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_dec_05, TestSize.Level0) GTEST_LOG_(INFO) << "App_Spawn_Sandbox_dec_05 end"; } +/** + * @tc.name: App_Spawn_Sandbox_dec_06 + * @tc.desc: parse config file for dec deny paths, the numbers of deny-paths is zero + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_dec_06, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "App_Spawn_Sandbox_dec_06 start"; + std::string mJsconfig = "{ \ + \"mount-paths\": [{ \ + \"src-path\": \"\", \ + \"sandbox-path\": \"\", \ + \"sandbox-flags\": [ ] \ + \"deny-paths\": [ ] \ + \"deny-perm-deps\": [ ] \ + }] \ + }"; + nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); + const char *mountPath = "mount-paths"; + nlohmann::json j_secondConfig = j_config[mountPath][0]; + std::string section = "permission"; + OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); + OHOS::AppSpawn::SandboxUtils::SandboxMountConfig mountConfig; + AppSpawningCtx *appProperty = GetTestAppProperty(); + OHOS::AppSpawn::SandboxUtils::GetSandboxMountConfig(appProperty, section, j_secondConfig, mountConfig); + + int denyPathSize = mountConfig.denyPaths.size(); + ASSERT_EQ(denyPathSize, 0); + int permDepSize = mountConfig.denyPermDeps.size(); + ASSERT_EQ(permDepSize, 0); + int ret = OHOS::AppSpawn::SandboxUtils::DoAllMntPointsMount(appProperty, j_config, nullptr, "permission"); + EXPECT_EQ(ret, 0); + + DeleteAppSpawningCtx(appProperty); + GTEST_LOG_(INFO) << "App_Spawn_Sandbox_dec_06 end"; +} + +/** + * @tc.name: App_Spawn_Sandbox_dec_07 + * @tc.desc: parse config file for dec deny paths, the numbers of deny-perm-deps is zero + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_dec_07, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "App_Spawn_Sandbox_dec_07 start"; + std::string mJsconfig = "{ \ + \"mount-paths\": [{ \ + \"src-path\": \"\", \ + \"sandbox-path\": \"\", \ + \"sandbox-flags\": [ ] \ + \"deny-paths\": [ \"/storage/Users//Download\" ] \ + \"deny-perm-deps\": [ ] \ + }] \ + }"; + nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); + const char *mountPath = "mount-paths"; + nlohmann::json j_secondConfig = j_config[mountPath][0]; + std::string section = "permission"; + OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); + OHOS::AppSpawn::SandboxUtils::SandboxMountConfig mountConfig; + AppSpawningCtx *appProperty = GetTestAppProperty(); + OHOS::AppSpawn::SandboxUtils::GetSandboxMountConfig(appProperty, section, j_secondConfig, mountConfig); + + int denyPathSize = mountConfig.denyPaths.size(); + ASSERT_EQ(denyPathSize, 1); + int permDepSize = mountConfig.denyPermDeps.size(); + ASSERT_EQ(permDepSize, 0); + int ret = OHOS::AppSpawn::SandboxUtils::DoAllMntPointsMount(appProperty, j_config, nullptr, "permission"); + EXPECT_EQ(ret, 0); + + DeleteAppSpawningCtx(appProperty); + GTEST_LOG_(INFO) << "App_Spawn_Sandbox_dec_07 end"; +} + +/** + * @tc.name: App_Spawn_Sandbox_dec_08 + * @tc.desc: parse config file for dec deny paths, the numbers of deny-paths and deny-perm-deps is equal + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_dec_08, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "App_Spawn_Sandbox_dec_08 start"; + std::string mJsconfig = "{ \ + \"mount-paths\": [{ \ + \"src-path\": \"\", \ + \"sandbox-path\": \"\", \ + \"sandbox-flags\": [ ] \ + \"deny-paths\": [ \"/storage/Users//Download\" ] \ + \"deny-perm-deps\": [ \"ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY\" ] \ + }] \ + }"; + nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); + const char *mountPath = "mount-paths"; + nlohmann::json j_secondConfig = j_config[mountPath][0]; + std::string section = "permission"; + OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); + OHOS::AppSpawn::SandboxUtils::SandboxMountConfig mountConfig; + AppSpawningCtx *appProperty = GetTestAppProperty(); + OHOS::AppSpawn::SandboxUtils::GetSandboxMountConfig(appProperty, section, j_secondConfig, mountConfig); + + int denyPathSize = mountConfig.denyPaths.size(); + ASSERT_EQ(denyPathSize, 1); + int permDepSize = mountConfig.denyPermDeps.size(); + ASSERT_EQ(permDepSize, 1); + int ret = OHOS::AppSpawn::SandboxUtils::DoAllMntPointsMount(appProperty, j_config, nullptr, "permission"); + EXPECT_EQ(ret, 0); + + int32_t index = GetPermissionIndex(nullptr, "ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY"); + ASSERT_NE(index, 0); + ret = SetAppPermissionFlags(appProperty, index); + ASSERT_EQ(ret, 0); + int ret = OHOS::AppSpawn::SandboxUtils::DoAllMntPointsMount(appProperty, j_config, nullptr, "permission"); + EXPECT_EQ(ret, 0); + + DeleteAppSpawningCtx(appProperty); + GTEST_LOG_(INFO) << "App_Spawn_Sandbox_dec_08 end"; +} + +/** + * @tc.name: App_Spawn_Sandbox_dec_09 + * @tc.desc: parse config file for dec deny paths, the numbers of deny-paths and deny-perm-deps is not equal + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_dec_09, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "App_Spawn_Sandbox_dec_08 start"; + std::string mJsconfig = "{ \ + \"mount-paths\": [{ \ + \"src-path\": \"\", \ + \"sandbox-path\": \"\", \ + \"sandbox-flags\": [ ] \ + \"deny-paths\": [ \"/storage/Users//Download\",\"/storage/Users//Desktop\" ] \ + \"deny-perm-deps\": [ \"ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY\" ] \ + }] \ + }"; + nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); + const char *mountPath = "mount-paths"; + nlohmann::json j_secondConfig = j_config[mountPath][0]; + std::string section = "permission"; + OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); + OHOS::AppSpawn::SandboxUtils::SandboxMountConfig mountConfig; + AppSpawningCtx *appProperty = GetTestAppProperty(); + OHOS::AppSpawn::SandboxUtils::GetSandboxMountConfig(appProperty, section, j_secondConfig, mountConfig); + + int denyPathSize = mountConfig.denyPaths.size(); + ASSERT_EQ(denyPathSize, 2); + int permDepSize = mountConfig.denyPermDeps.size(); + ASSERT_EQ(permDepSize, 1); + int ret = OHOS::AppSpawn::SandboxUtils::DoAllMntPointsMount(appProperty, j_config, nullptr, "permission"); + EXPECT_EQ(ret, 0); + + int32_t index = GetPermissionIndex(nullptr, "ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY"); + ASSERT_NE(index, 0); + ret = SetAppPermissionFlags(appProperty, index); + ASSERT_EQ(ret, 0); + int ret = OHOS::AppSpawn::SandboxUtils::DoAllMntPointsMount(appProperty, j_config, nullptr, "permission"); + EXPECT_EQ(ret, 0); + + DeleteAppSpawningCtx(appProperty); + GTEST_LOG_(INFO) << "App_Spawn_Sandbox_dec_09 end"; +} + /** * @tc.name: App_Spawn_Sandbox_Shared_Mount_01 * @tc.desc: [IsValidDataGroupItem] input valid param