From 1c55e62e76338234c7e21741c71760fe15b2d8ed Mon Sep 17 00:00:00 2001 From: wangchen Date: Wed, 19 Mar 2025 14:54:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Edeny=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=20close=20#IBTL5T=20Signed-off-by:=20wangche?= =?UTF-8?q?n=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bundle.json | 16 +- .../inner_api/sandbox_manager/test/BUILD.gn | 2 + .../include/sandbox_manager_err_code.h | 1 + services/sandbox_manager/BUILD.gn | 2 + .../main/cpp/include/mac/mac_adapter.h | 7 +- .../main/cpp/src/mac/mac_adapter.cpp | 169 ++++++++++++++++++ services/sandbox_manager/test/BUILD.gn | 2 + .../unittest/policy_info_manager_test.cpp | 140 +++++++++++++++ .../sandbox_manager_service_fuzz.gni | 2 + 9 files changed, 333 insertions(+), 8 deletions(-) diff --git a/bundle.json b/bundle.json index ce69ce5..0817d09 100644 --- a/bundle.json +++ b/bundle.json @@ -26,18 +26,20 @@ ], "deps": { "components": [ + "ability_base", + "access_token", + "cJSON", "c_utils", + "common_event_service", + "config_policy", + "eventhandler", "hilog", "hisysevent", "ipc", - "safwk", - "samgr", - "access_token", - "eventhandler", - "common_event_service", - "ability_base", + "os_account", "relational_store", - "os_account" + "safwk", + "samgr" ], "third_party": [] }, diff --git a/frameworks/inner_api/sandbox_manager/test/BUILD.gn b/frameworks/inner_api/sandbox_manager/test/BUILD.gn index 29ca097..4525653 100644 --- a/frameworks/inner_api/sandbox_manager/test/BUILD.gn +++ b/frameworks/inner_api/sandbox_manager/test/BUILD.gn @@ -57,8 +57,10 @@ ohos_unittest("libsandbox_manager_sdk_test") { "access_token:libaccesstoken_sdk", "access_token:libnativetoken", "access_token:libtoken_setproc", + "cJSON:cjson", "c_utils:utils", "common_event_service:cesfwk_innerkits", + "config_policy:configpolicy_util", "hilog:libhilog", "ipc:ipc_single", "samgr:samgr_proxy", diff --git a/interfaces/inner_api/sandbox_manager/include/sandbox_manager_err_code.h b/interfaces/inner_api/sandbox_manager/include/sandbox_manager_err_code.h index 22d16e2..9e58949 100644 --- a/interfaces/inner_api/sandbox_manager/include/sandbox_manager_err_code.h +++ b/interfaces/inner_api/sandbox_manager/include/sandbox_manager_err_code.h @@ -33,6 +33,7 @@ enum SandboxManagerErrCode : int32_t { SANDBOX_MANAGER_MAC_NOT_INIT, SANDBOX_MANAGER_MAC_IOCTL_ERR, + SANDBOX_MANAGER_DENY_ERR, }; } // SandboxManager } // AccessControl diff --git a/services/sandbox_manager/BUILD.gn b/services/sandbox_manager/BUILD.gn index b462e2c..f7e2205 100644 --- a/services/sandbox_manager/BUILD.gn +++ b/services/sandbox_manager/BUILD.gn @@ -80,9 +80,11 @@ if (is_standard_system) { external_deps = [ "ability_base:want", "access_token:libaccesstoken_sdk", + "cJSON:cjson", "c_utils:utils", "common_event_service:cesfwk_core", "common_event_service:cesfwk_innerkits", + "config_policy:configpolicy_util", "eventhandler:libeventhandler", "hilog:libhilog", "ipc:ipc_core", diff --git a/services/sandbox_manager/main/cpp/include/mac/mac_adapter.h b/services/sandbox_manager/main/cpp/include/mac/mac_adapter.h index 7244785..1aae73c 100644 --- a/services/sandbox_manager/main/cpp/include/mac/mac_adapter.h +++ b/services/sandbox_manager/main/cpp/include/mac/mac_adapter.h @@ -22,6 +22,9 @@ namespace OHOS { namespace AccessControl { namespace SandboxManager { +static const std::string DENY_CONFIG_FILE = "etc/sandbox_manager_service/file_deny_policy.json"; +constexpr int MAX_DENY_CONFIG_FILE_SIZE = 5 * 1024 * 1024; // 5M +constexpr size_t BUFFER_SIZE = 1024; struct MacParams { uint32_t tokenId; @@ -44,7 +47,9 @@ public: int32_t CheckSandboxPolicy(uint32_t tokenId, const std::vector &policy, std::vector &result); int32_t DestroySandboxPolicy(uint32_t tokenId, uint64_t timestamp); int32_t UnSetSandboxPolicyByUser(int32_t userId, const std::vector &policy, std::vector &result); - + int32_t ReadDenyFile(const char *jsonPath, std::string& rawData); + int32_t SetDenyCfg(std::string& json); + void DenyInit(); private: int32_t fd_ = -1; bool isMacSupport_ = false; 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 92ca1ec..a7f20b5 100644 --- a/services/sandbox_manager/main/cpp/src/mac/mac_adapter.cpp +++ b/services/sandbox_manager/main/cpp/src/mac/mac_adapter.cpp @@ -19,8 +19,11 @@ #include #include #include +#include #include #include +#include "cJSON.h" +#include "config_policy_utils.h" #include "sandbox_manager_err_code.h" #include "sandbox_manager_log.h" @@ -59,6 +62,7 @@ struct SandboxPolicyInfo { #define CHECK_POLICY 4 #define DESTROY_POLICY 5 #define DEL_POLICY_BY_USER 7 +#define DENY_POLICY_ID 9 #define SET_POLICY_CMD _IOWR(SANDBOX_IOCTL_BASE, SET_POLICY, struct SandboxPolicyInfo) #define UN_SET_POLICY_CMD _IOWR(SANDBOX_IOCTL_BASE, UN_SET_POLICY, struct SandboxPolicyInfo) @@ -66,6 +70,16 @@ struct SandboxPolicyInfo { #define CHECK_POLICY_CMD _IOWR(SANDBOX_IOCTL_BASE, CHECK_POLICY, struct SandboxPolicyInfo) #define DESTROY_POLICY_CMD _IOWR(SANDBOX_IOCTL_BASE, DESTROY_POLICY, struct SandboxPolicyInfo) #define DEL_DEC_POLICY_BY_USER_CMD _IOWR(SANDBOX_IOCTL_BASE, DEL_POLICY_BY_USER, struct SandboxPolicyInfo) +#define DENY_DEC_RULE_CMD _IOWR(SANDBOX_IOCTL_BASE, DENY_POLICY_ID, struct SandboxPolicyInfo) + +#define DEC_DENY_RENAME (1 << 2) +#define DEC_DENY_REMOVE (1 << 3) +#define DEC_DENY_INHERIT (1 << 4) + +constexpr const char* JSON_ITEM_PATH = "path"; +constexpr const char* JSON_ITEM_RENAME = "rename"; +constexpr const char* JSON_ITEM_DELETE = "delete"; +constexpr const char* JSON_ITEM_INHERIT = "inherit"; MacAdapter::MacAdapter() {} @@ -78,6 +92,160 @@ MacAdapter::~MacAdapter() isMacSupport_ = false; } +int32_t MacAdapter::ReadDenyFile(const char *jsonPath, std::string& rawData) +{ + char buf[BUFFER_SIZE] = { 0 }; + char *path = GetOneCfgFile(jsonPath, buf, BUFFER_SIZE); + if (path == nullptr) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "GetOneCfgFile failed, cannot find file with %{public}s", jsonPath); + return SANDBOX_MANAGER_DENY_ERR; + } + int32_t fd = open(path, O_RDONLY); + if (fd < 0) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "Open failed errno %{public}d.", errno); + return SANDBOX_MANAGER_DENY_ERR; + } + + struct stat statBuffer; + if (fstat(fd, &statBuffer) != 0) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "fstat failed"); + close(fd); + return SANDBOX_MANAGER_DENY_ERR; + } + + if (statBuffer.st_size == 0) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "Config file size is zero."); + close(fd); + return SANDBOX_MANAGER_DENY_ERR; + } + + if (statBuffer.st_size > MAX_DENY_CONFIG_FILE_SIZE) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "Config file size is too large"); + close(fd); + return SANDBOX_MANAGER_DENY_ERR; + } + rawData.reserve(statBuffer.st_size); + ssize_t readLen = 0; + while ((readLen = read(fd, buf, BUFFER_SIZE)) > 0) { + rawData.append(buf, readLen); + } + close(fd); + if (readLen == 0) { + return SANDBOX_MANAGER_OK; + } + return SANDBOX_MANAGER_DENY_ERR; +} + +static uint32_t FillInfo(cJSON *root, struct SandboxPolicyInfo &info, int32_t start, int32_t curBatchSize) +{ + uint32_t mode = 0; + + for (int32_t i = 0; i < curBatchSize; i++) { + cJSON *cjsonItem = cJSON_GetArrayItem(root, i + start); + if (cjsonItem == nullptr) { + return SANDBOX_MANAGER_DENY_ERR; + } + + mode = 0; + cJSON *pathNameJson = cJSON_GetObjectItemCaseSensitive(cjsonItem, JSON_ITEM_PATH); + if ((pathNameJson == nullptr) || !cJSON_IsString(pathNameJson) || (pathNameJson->valuestring == nullptr)) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "pathname get error"); + return SANDBOX_MANAGER_DENY_ERR; + } + + cJSON *reameJson = cJSON_GetObjectItemCaseSensitive(cjsonItem, JSON_ITEM_RENAME); + if ((reameJson == nullptr) || !cJSON_IsNumber(reameJson)) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "rename info get error, path = %{public}s", pathNameJson->valuestring); + return SANDBOX_MANAGER_DENY_ERR; + } + if (reameJson->valueint == 1) { + mode |= DEC_DENY_RENAME; + } + + cJSON *deleteJson = cJSON_GetObjectItemCaseSensitive(cjsonItem, JSON_ITEM_DELETE); + if ((deleteJson == nullptr) || !cJSON_IsNumber(deleteJson)) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "delete info get error, path = %{public}s", pathNameJson->valuestring); + return SANDBOX_MANAGER_DENY_ERR; + } + if (deleteJson->valueint == 1) { + mode |= DEC_DENY_REMOVE; + } + + cJSON *inheritJson = cJSON_GetObjectItemCaseSensitive(cjsonItem, JSON_ITEM_INHERIT); + if ((inheritJson == nullptr) || !cJSON_IsNumber(inheritJson)) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "inherit info get error, path = %{public}s", pathNameJson->valuestring); + return SANDBOX_MANAGER_DENY_ERR; + } + if (inheritJson->valueint == 1) { + mode |= DEC_DENY_INHERIT; + } + + info.pathInfos[i].path = pathNameJson->valuestring; + info.pathInfos[i].pathLen = std::strlen(pathNameJson->valuestring); + info.pathInfos[i].mode = mode; + SANDBOXMANAGER_LOG_INFO(LABEL, "path = %{public}s, mode = %{public}x", pathNameJson->valuestring, mode); + } + return SANDBOX_MANAGER_OK; +} + +int32_t MacAdapter::SetDenyCfg(std::string &rawData) +{ + cJSON *root = cJSON_Parse(rawData.c_str()); + if (root == nullptr) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "json parse error"); + return SANDBOX_MANAGER_DENY_ERR; + } + int32_t arraySize = cJSON_GetArraySize(root); + if (arraySize < 0) { + cJSON_Delete(root); + return SANDBOX_MANAGER_DENY_ERR; + } + int32_t succSet = 0; + 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); + ret = FillInfo(root, info, i, curBatchSize); + if (ret != SANDBOX_MANAGER_OK) { + break; + } + info.pathNum = curBatchSize; + if (ioctl(fd_, DENY_DEC_RULE_CMD, &info) < 0) { + SANDBOXMANAGER_LOG_ERROR(LABEL, + "Set deny failed errno=%{public}d, path = %{public}s, mode = %{public}x, num = %{public}d", + errno, info.pathInfos[i].path, info.pathInfos[i].mode, info.pathNum); + break; + } + succSet += curBatchSize; + } + cJSON_Delete(root); + + if (arraySize != succSet) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "denyfile has %{public}d. failed from %{public}d", arraySize, succSet); + return SANDBOX_MANAGER_DENY_ERR; + } + return SANDBOX_MANAGER_OK; +} + +void MacAdapter::DenyInit() +{ +#ifndef NOT_RESIDENT + int32_t ret; + std::string inputString; + ret = ReadDenyFile(DENY_CONFIG_FILE.c_str(), inputString); + if (ret != SANDBOX_MANAGER_OK) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "Json read error"); + return; + } + + ret = SetDenyCfg(inputString); + if (ret != SANDBOX_MANAGER_OK) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "Json set error"); + } + return; +#endif +} + void MacAdapter::Init() { if (access(DEV_NODE, F_OK) == 0) { @@ -93,6 +261,7 @@ void MacAdapter::Init() return; } SANDBOXMANAGER_LOG_INFO(LABEL, "Open node success."); + DenyInit(); return; } diff --git a/services/sandbox_manager/test/BUILD.gn b/services/sandbox_manager/test/BUILD.gn index d68945b..01988c4 100644 --- a/services/sandbox_manager/test/BUILD.gn +++ b/services/sandbox_manager/test/BUILD.gn @@ -74,9 +74,11 @@ ohos_unittest("libsandbox_manager_service_standard_test") { "access_token:libaccesstoken_sdk", "access_token:libnativetoken", "access_token:libtoken_setproc", + "cJSON:cjson", "c_utils:utils", "common_event_service:cesfwk_core", "common_event_service:cesfwk_innerkits", + "config_policy:configpolicy_util", "eventhandler:libeventhandler", "hilog:libhilog", "ipc:ipc_core", 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 177e0f2..04785b1 100644 --- a/services/sandbox_manager/test/unittest/policy_info_manager_test.cpp +++ b/services/sandbox_manager/test/unittest/policy_info_manager_test.cpp @@ -369,6 +369,146 @@ HWTEST_F(PolicyInfoManagerTest, MacAdapterTest001, TestSize.Level1) EXPECT_EQ(SANDBOX_MANAGER_MAC_NOT_INIT, macAdapter.DestroySandboxPolicy(selfTokenId_, 0)); } +#ifdef DEC_ENABLED +/** + * @tc.name: DenyTest001 + * @tc.desc: Test DenyTest normal + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(PolicyInfoManagerTest, DenyTest001, TestSize.Level1) +{ + std::string stringJson1 = R"([{"path":"/data/test", "rename":1, "delete":1, "inherit":1}])"; + EXPECT_EQ(SANDBOX_MANAGER_OK, PolicyInfoManager::GetInstance().macAdapter_.SetDenyCfg(stringJson1)); +} + +/** + * @tc.name: DenyTest002 + * @tc.desc: Test DenyTest delete error + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(PolicyInfoManagerTest, DenyTest002, TestSize.Level1) +{ + std::string stringJson1 = R"([ + {"path":"/etc/test", "rename":1, "delete":"test", "inherit":1}])"; + EXPECT_EQ(SANDBOX_MANAGER_DENY_ERR, PolicyInfoManager::GetInstance().macAdapter_.SetDenyCfg(stringJson1)); +} + +/** + * @tc.name: DenyTest003 + * @tc.desc: Test DenyTest rename error + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(PolicyInfoManagerTest, DenyTest003, TestSize.Level1) +{ + std::string stringJson1 = R"([ + {"path":"/etc/test", "rename":"test", "delete":1, "inherit":1}])"; + EXPECT_EQ(SANDBOX_MANAGER_DENY_ERR, PolicyInfoManager::GetInstance().macAdapter_.SetDenyCfg(stringJson1)); +} + +/** + * @tc.name: DenyTest004 + * @tc.desc: Test DenyTest inherit error + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(PolicyInfoManagerTest, DenyTest004, TestSize.Level1) +{ + std::string stringJson1 = R"([ + {"path":"/etc/test", "rename":1, "delete":1, "inherit":"test"}])"; + EXPECT_EQ(SANDBOX_MANAGER_DENY_ERR, PolicyInfoManager::GetInstance().macAdapter_.SetDenyCfg(stringJson1)); +} + +/** + * @tc.name: DenyTest005 + * @tc.desc: Test DenyTest pass error + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(PolicyInfoManagerTest, DenyTest005, TestSize.Level1) +{ + std::string stringJson1 = R"([ + {"path":1, "rename":1, "delete":1, "inherit":1}])"; + EXPECT_EQ(SANDBOX_MANAGER_DENY_ERR, PolicyInfoManager::GetInstance().macAdapter_.SetDenyCfg(stringJson1)); +} + +/** + * @tc.name: DenyTest006 + * @tc.desc: Test DenyTest empty json + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(PolicyInfoManagerTest, DenyTest006, TestSize.Level1) +{ + std::string stringJson1 = R"([])"; + EXPECT_EQ(SANDBOX_MANAGER_OK, PolicyInfoManager::GetInstance().macAdapter_.SetDenyCfg(stringJson1)); +} + +/** + * @tc.name: DenyTest007 + * @tc.desc: Test DenyTest long json + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(PolicyInfoManagerTest, DenyTest007, TestSize.Level1) +{ + std::string stringJson1 = R"([ + {"path":"/etc/test", "rename":1, "delete":1, "inherit":1}, + {"path":"/etc/test2", "rename":1, "delete":1, "inherit":1}, + {"path":"/etc/test3", "rename":1, "delete":1, "inherit":1}, + {"path":"/etc/test4", "rename":1, "delete":1, "inherit":1}, + {"path":"/etc/test5", "rename":1, "delete":1, "inherit":1}, + {"path":"/etc/test6", "rename":1, "delete":1, "inherit":1}, + {"path":"/etc/test7", "rename":1, "delete":1, "inherit":1}, + {"path":"/etc/test8", "rename":1, "delete":1, "inherit":1}, + {"path":"/etc/test9", "rename":1, "delete":1, "inherit":1} + ])"; + EXPECT_EQ(SANDBOX_MANAGER_OK, PolicyInfoManager::GetInstance().macAdapter_.SetDenyCfg(stringJson1)); +} + +/** + * @tc.name: DenyTest008 + * @tc.desc: Test DenyTest json item lost + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(PolicyInfoManagerTest, DenyTest008, TestSize.Level1) +{ + std::string stringJson1 = R"([ + {"path":"/etc/test", "delete":1, "inherit":1}])"; + EXPECT_EQ(SANDBOX_MANAGER_DENY_ERR, PolicyInfoManager::GetInstance().macAdapter_.SetDenyCfg(stringJson1)); +} + +/** + * @tc.name: DenyTest009 + * @tc.desc: Test DenyTest path error + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(PolicyInfoManagerTest, DenyTest009, TestSize.Level1) +{ + const char *jsonPath = "etc/sandbox_manager_service/test"; + std::string inputString; + EXPECT_EQ(SANDBOX_MANAGER_DENY_ERR, + PolicyInfoManager::GetInstance().macAdapter_.ReadDenyFile(jsonPath, inputString)); +} + +/** + * @tc.name: DenyTest010 + * @tc.desc: Test DenyTest path right + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(PolicyInfoManagerTest, DenyTest010, TestSize.Level1) +{ + const char *jsonPath = "etc/sandbox/appdata-sandbox.json"; + std::string inputString; + EXPECT_EQ(SANDBOX_MANAGER_OK, PolicyInfoManager::GetInstance().macAdapter_.ReadDenyFile(jsonPath, inputString)); +} +#endif + /** * @tc.name: PolicyInfoManagerTest012 * @tc.desc: Test PolicyInfoManager - MAC not supported diff --git a/test/fuzztest/services/sandbox_manager/sandbox_manager_service_fuzz.gni b/test/fuzztest/services/sandbox_manager/sandbox_manager_service_fuzz.gni index b0e2239..b3475e8 100644 --- a/test/fuzztest/services/sandbox_manager/sandbox_manager_service_fuzz.gni +++ b/test/fuzztest/services/sandbox_manager/sandbox_manager_service_fuzz.gni @@ -55,9 +55,11 @@ sandbox_manager_external_deps = [ "access_token:libaccesstoken_sdk", "access_token:libnativetoken", "access_token:libtoken_setproc", + "cJSON:cjson", "c_utils:utils", "common_event_service:cesfwk_core", "common_event_service:cesfwk_innerkits", + "config_policy:configpolicy_util", "hilog:libhilog", "ipc:ipc_core", "os_account:os_account_innerkits", -- Gitee