From 324e34ec2e16a327278b306a40b30b8bc98e0720 Mon Sep 17 00:00:00 2001 From: wangchen Date: Thu, 19 Jun 2025 17:28:53 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B7=AF=E5=BE=84=E8=A7=84=E5=88=99=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=20close=20#ICEREV=20Signed-off-by:=20wangchen=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cpp/include/service/policy_info_manager.h | 4 +- .../main/cpp/src/mac/mac_adapter.cpp | 2 +- .../cpp/src/service/policy_info_manager.cpp | 79 +++++++++++++---- .../unittest/policy_info_manager_test.cpp | 87 +++++++++++++++---- 4 files changed, 136 insertions(+), 36 deletions(-) diff --git a/services/sandbox_manager/main/cpp/include/service/policy_info_manager.h b/services/sandbox_manager/main/cpp/include/service/policy_info_manager.h index c87253e..971634c 100644 --- a/services/sandbox_manager/main/cpp/include/service/policy_info_manager.h +++ b/services/sandbox_manager/main/cpp/include/service/policy_info_manager.h @@ -269,8 +269,10 @@ private: const uint32_t tokenId, const std::vector &policy, std::vector &results); int32_t GetMediaPolicyCommonWork(const uint32_t tokenId, const std::vector &policy, std::vector &results, std::vector &validIndex, std::vector &normalPolicy); - int32_t CheckBeforeSetPolicy(const std::vector &policy, std::vector &result, + uint32_t CheckBeforeSetPolicy(const std::vector &policy, std::vector &result, std::vector &validIndex, std::vector &validPolicies); + std::vector splitPath(const std::string &path); + bool CheckPathWithinRule(const std::string &path); }; } // namespace SandboxManager } // namespace AccessControl diff --git a/services/sandbox_manager/main/cpp/src/mac/mac_adapter.cpp b/services/sandbox_manager/main/cpp/src/mac/mac_adapter.cpp index 3c03577..3e0a39b 100644 --- a/services/sandbox_manager/main/cpp/src/mac/mac_adapter.cpp +++ b/services/sandbox_manager/main/cpp/src/mac/mac_adapter.cpp @@ -209,7 +209,7 @@ int32_t MacAdapter::SetDenyCfg(std::string &rawData) int32_t ret; for (int32_t i = 0; i < arraySize; i += MAX_POLICY_NUM) { struct SandboxPolicyInfo info; - int32_t curBatchSize = std::min(static_cast(MAX_POLICY_NUM), arraySize - i); + size_t curBatchSize = std::min(static_cast(MAX_POLICY_NUM), arraySize - i); ret = FillInfo(root, info, i, curBatchSize); if (ret != SANDBOX_MANAGER_OK) { break; diff --git a/services/sandbox_manager/main/cpp/src/service/policy_info_manager.cpp b/services/sandbox_manager/main/cpp/src/service/policy_info_manager.cpp index 7533750..bb2c6ea 100644 --- a/services/sandbox_manager/main/cpp/src/service/policy_info_manager.cpp +++ b/services/sandbox_manager/main/cpp/src/service/policy_info_manager.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -473,7 +474,7 @@ MacParams PolicyInfoManager::GetMacParams(uint32_t tokenId, uint64_t policyFlag, return macParams; } -int32_t PolicyInfoManager::CheckBeforeSetPolicy(const std::vector &policy, std::vector &result, +uint32_t PolicyInfoManager::CheckBeforeSetPolicy(const std::vector &policy, std::vector &result, std::vector &validIndex, std::vector &validPolicies) { uint32_t invalidNum = 0; @@ -927,24 +928,69 @@ int32_t PolicyInfoManager::CheckPolicyValidity(const PolicyInfo &policy) return SANDBOX_MANAGER_OK; } -const std::unordered_set g_blockPathList = { - "/storage/Users/currentUser/appdata", - "/storage/Users/currentUser/appdata/el1", - "/storage/Users/currentUser/appdata/el2", - "/storage/Users/currentUser/appdata/el3", - "/storage/Users/currentUser/appdata/el4", - "/storage/Users/currentUser/appdata/el5", - "/storage/Users/currentUser/appdata/el1/base", - "/storage/Users/currentUser/appdata/el2/base", - "/storage/Users/currentUser/appdata/el3/base", - "/storage/Users/currentUser/appdata/el4/base", - "/storage/Users/currentUser/appdata/el5/base", -}; +// components num of "/storage/Users/currentUser/appdata/*/*" +#define MAX_CHECK_COM_NUM 6 +#define SECOND_PATH_SEGMENT 2 +const std::string ROOT_PATH = "/storage"; +const std::string APPDATA_PATH = "/storage/Users/currentUser/appdata"; + +std::vector PolicyInfoManager::splitPath(const std::string &path) +{ + std::vector components; + std::stringstream ss(path); + std::string component; + int comNum = 0; + while (std::getline(ss, component, '/')) { + if (!component.empty()) { + components.push_back(component); + } + if (comNum > MAX_CHECK_COM_NUM) { + break; + } + comNum++; + } + return components; +} + +bool PolicyInfoManager::CheckPathWithinRule(const std::string &path) +{ + size_t ROOT_PATH_SIZE = ROOT_PATH.length(); + // Check if the path starts with "/storage" + if (path.substr(0, ROOT_PATH_SIZE) != ROOT_PATH) { + return true; + } + + std::vector components = splitPath(path); + // check whether path is "/storage" or "/storage/*" + if (components.size() <= SECOND_PATH_SEGMENT) { + return false; + } + + // Check if the path is "/storage/Users/" and ensure it is followed by "currentUser" + if (components[0] == "storage" && components[1] == "Users") { + if (components[SECOND_PATH_SEGMENT] != "currentUser") { + return false; // such as "/storage/Users/a" + } + } + + // check whether path is longer than "/storage/Users/currentUser/appdata/*/*" + if (components.size() > MAX_CHECK_COM_NUM) { + return true; + } + + // Check if the path is /storage/Users/currentUser/appdata and ensure it has more than 2 levels + size_t APPDATA_PATH_SIZE = APPDATA_PATH.length(); + if ((path.size() >= APPDATA_PATH_SIZE) && (path.substr(0, APPDATA_PATH_SIZE) == APPDATA_PATH)) { + return false; + } + + return true; +} int32_t PolicyInfoManager::CheckPathIsBlocked(const std::string &path) { uint32_t length = path.length(); - const char* cStr = path.c_str(); + const char *cStr = path.c_str(); uint32_t cStrLength = strlen(cStr); if (length != cStrLength) { SANDBOXMANAGER_LOG_ERROR(LABEL, "path have a terminator: %{public}s, pathLen:%{public}u, cstrLen:%{public}u", @@ -953,7 +999,8 @@ int32_t PolicyInfoManager::CheckPathIsBlocked(const std::string &path) } std::string pathTmp = AdjustPath(path); - if (g_blockPathList.count(pathTmp) != 0) { + int ret = CheckPathWithinRule(pathTmp); + if (ret != true) { SANDBOXMANAGER_LOG_ERROR(LABEL, "path not allowed to set policy: %{public}s", path.c_str()); return SandboxRetType::INVALID_PATH; } diff --git a/services/sandbox_manager/test/unittest/policy_info_manager_test.cpp b/services/sandbox_manager/test/unittest/policy_info_manager_test.cpp index 35c27a4..4cf15b8 100644 --- a/services/sandbox_manager/test/unittest/policy_info_manager_test.cpp +++ b/services/sandbox_manager/test/unittest/policy_info_manager_test.cpp @@ -167,7 +167,7 @@ HWTEST_F(PolicyInfoManagerTest, PolicyInfoManagerTest003, TestSize.Level0) std::vector policy; policy.emplace_back(info); - info.path = "/storage/Users/currentUser/appdata/el2"; + info.path = "/storage/Users/currentUser/appdata"; info.mode = OperateMode::READ_MODE + OperateMode::WRITE_MODE; policy[0] = info; std::vector setResult; @@ -175,40 +175,91 @@ HWTEST_F(PolicyInfoManagerTest, PolicyInfoManagerTest003, TestSize.Level0) ASSERT_EQ(1, setResult.size()); EXPECT_EQ(SandboxRetType::INVALID_PATH, setResult[0]); - info.path = "/storage/Users/currentUser/appdata/el3/base"; + info.path = "/storage/Users/currentUser/appdata/el1"; info.mode = OperateMode::READ_MODE + OperateMode::WRITE_MODE; policy[0] = info; EXPECT_EQ(SANDBOX_MANAGER_OK, PolicyInfoManager::GetInstance().SetPolicy(selfTokenId_, policy, 1, setResult)); ASSERT_EQ(1, setResult.size()); EXPECT_EQ(SandboxRetType::INVALID_PATH, setResult[0]); - info.path = "/storage/Users/currentUser/appdata/el6"; + info.path = "/storage/Users/currentUser/appdata/el1/a"; info.mode = OperateMode::READ_MODE + OperateMode::WRITE_MODE; policy[0] = info; EXPECT_EQ(SANDBOX_MANAGER_OK, PolicyInfoManager::GetInstance().SetPolicy(selfTokenId_, policy, 1, setResult)); ASSERT_EQ(1, setResult.size()); - EXPECT_EQ(SandboxRetType::OPERATE_SUCCESSFULLY, setResult[0]); + EXPECT_EQ(SandboxRetType::INVALID_PATH, setResult[0]); - info.path = "/storage/Users/currentUser/appdata/el3"; - size_t insert_pos = info.path.length(); - info.path.insert(insert_pos, 1, '\0'); - info.path += "/test"; + info.path = "/storage/Users/currentUser/appdata/el1/a/b"; info.mode = OperateMode::READ_MODE + OperateMode::WRITE_MODE; policy[0] = info; EXPECT_EQ(SANDBOX_MANAGER_OK, PolicyInfoManager::GetInstance().SetPolicy(selfTokenId_, policy, 1, setResult)); ASSERT_EQ(1, setResult.size()); - EXPECT_EQ(SandboxRetType::INVALID_PATH, setResult[0]); + EXPECT_EQ(SandboxRetType::OPERATE_SUCCESSFULLY, setResult[0]); } #endif #ifdef DEC_ENABLED /** * @tc.name: PolicyInfoManagerTest004 - * @tc.desc: Test MatchPolicy - normal + * @tc.desc: Test AddPolicy - block list path traversal * @tc.type: FUNC * @tc.require: */ HWTEST_F(PolicyInfoManagerTest, PolicyInfoManagerTest004, TestSize.Level0) +{ + PolicyInfo info; + std::vector policy; + policy.emplace_back(info); + + info.mode = OperateMode::READ_MODE + OperateMode::WRITE_MODE; + policy[0] = info; + std::vector setResult; + + info.path = "/storage"; + policy[0] = info; + EXPECT_EQ(SANDBOX_MANAGER_OK, PolicyInfoManager::GetInstance().SetPolicy(selfTokenId_, policy, 1, setResult)); + EXPECT_EQ(SandboxRetType::INVALID_PATH, setResult[0]); + + info.path = "/storage/a"; + policy[0] = info; + EXPECT_EQ(SANDBOX_MANAGER_OK, PolicyInfoManager::GetInstance().SetPolicy(selfTokenId_, policy, 1, setResult)); + EXPECT_EQ(SandboxRetType::INVALID_PATH, setResult[0]); + + info.path = "/storage/a/b"; + policy[0] = info; + EXPECT_EQ(SANDBOX_MANAGER_OK, PolicyInfoManager::GetInstance().SetPolicy(selfTokenId_, policy, 1, setResult)); + EXPECT_EQ(SandboxRetType::OPERATE_SUCCESSFULLY, setResult[0]); + + info.path = "/storage/Users/a"; + policy[0] = info; + EXPECT_EQ(SANDBOX_MANAGER_OK, PolicyInfoManager::GetInstance().SetPolicy(selfTokenId_, policy, 1, setResult)); + EXPECT_EQ(SandboxRetType::INVALID_PATH, setResult[0]); + + info.path = "/storage/Users/currentUser"; + policy[0] = info; + EXPECT_EQ(SANDBOX_MANAGER_OK, PolicyInfoManager::GetInstance().SetPolicy(selfTokenId_, policy, 1, setResult)); + EXPECT_EQ(SandboxRetType::OPERATE_SUCCESSFULLY, setResult[0]); + + info.path = "/storage/Users/currentUser/a"; + policy[0] = info; + EXPECT_EQ(SANDBOX_MANAGER_OK, PolicyInfoManager::GetInstance().SetPolicy(selfTokenId_, policy, 1, setResult)); + EXPECT_EQ(SandboxRetType::OPERATE_SUCCESSFULLY, setResult[0]); + + info.path = "/storage/Users/currentUser/appdata"; + policy[0] = info; + EXPECT_EQ(SANDBOX_MANAGER_OK, PolicyInfoManager::GetInstance().SetPolicy(selfTokenId_, policy, 1, setResult)); + EXPECT_EQ(SandboxRetType::INVALID_PATH, setResult[0]); +} +#endif + +#ifdef DEC_ENABLED +/** + * @tc.name: PolicyInfoManagerTest005 + * @tc.desc: Test MatchPolicy - normal + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(PolicyInfoManagerTest, PolicyInfoManagerTest005, TestSize.Level0) { PolicyInfo info; uint64_t sizeLimit = 1; @@ -307,19 +358,19 @@ HWTEST_F(PolicyInfoManagerTest, PolicyInfoManagerTest008, TestSize.Level0) { std::string path1 = "/storage/Users/currentUser/appdata"; std::string path2 = "/storage/Users/currentUser/appdata/el1"; - std::string path3 = "/storage/Users/currentUser/appdata/el2/base"; + std::string path3 = "/storage/Users/currentUser/appdata/el6"; std::string path4 = "/storage/Users/currentUser/appdata/test"; - std::string path5 = "/storage/Users/currentUser/appdata/el1/test"; - std::string path6 = "/storage/Users/currentUser/appdata/el2/base/test"; - std::string path7 = "/storage/Users/currentUser/appdata/el6"; - std::string path8 = "/storage/Users/currentUser/appdata/el5/"; + std::string path5 = "/storage/Users/currentUser/appdata/el1/base"; + std::string path6 = "/storage/Users/currentUser/appdata/el6/test"; + std::string path7 = "/storage/Users/currentUser/appdata/el1/base/test"; + std::string path8 = "/storage/Users/currentUser/appdata/"; EXPECT_EQ(SandboxRetType::INVALID_PATH, PolicyInfoManager::GetInstance().CheckPathIsBlocked(path1)); EXPECT_EQ(SandboxRetType::INVALID_PATH, PolicyInfoManager::GetInstance().CheckPathIsBlocked(path2)); EXPECT_EQ(SandboxRetType::INVALID_PATH, PolicyInfoManager::GetInstance().CheckPathIsBlocked(path3)); - EXPECT_EQ(SANDBOX_MANAGER_OK, PolicyInfoManager::GetInstance().CheckPathIsBlocked(path4)); - EXPECT_EQ(SANDBOX_MANAGER_OK, PolicyInfoManager::GetInstance().CheckPathIsBlocked(path5)); - EXPECT_EQ(SANDBOX_MANAGER_OK, PolicyInfoManager::GetInstance().CheckPathIsBlocked(path6)); + EXPECT_EQ(SandboxRetType::INVALID_PATH, PolicyInfoManager::GetInstance().CheckPathIsBlocked(path4)); + EXPECT_EQ(SandboxRetType::INVALID_PATH, PolicyInfoManager::GetInstance().CheckPathIsBlocked(path5)); + EXPECT_EQ(SandboxRetType::INVALID_PATH, PolicyInfoManager::GetInstance().CheckPathIsBlocked(path6)); EXPECT_EQ(SANDBOX_MANAGER_OK, PolicyInfoManager::GetInstance().CheckPathIsBlocked(path7)); EXPECT_EQ(SandboxRetType::INVALID_PATH, PolicyInfoManager::GetInstance().CheckPathIsBlocked(path8)); } -- Gitee