From a8c6793f3df562f6b454143046dba2e2701e8cb3 Mon Sep 17 00:00:00 2001 From: ShortMessage Date: Mon, 28 Apr 2025 17:44:52 +0800 Subject: [PATCH] =?UTF-8?q?UDMF=E6=96=B0=E5=A2=9E=E9=80=9A=E9=81=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ShortMessage --- .../service/test/BUILD.gn | 2 + .../udmf/lifecycle/lifecycle_manager.cpp | 3 + .../udmf/lifecycle/lifecycle_policy.cpp | 12 ++ .../service/udmf/lifecycle/lifecycle_policy.h | 2 + .../service/udmf/store/store_cache.cpp | 8 +- .../service/udmf/store/store_cache.h | 1 + .../service/udmf/udmf_service_impl.cpp | 125 ++++++++++++++++-- .../service/udmf/udmf_service_impl.h | 8 +- 8 files changed, 146 insertions(+), 15 deletions(-) diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn index 1a0d4a4d9..b2f90d849 100755 --- a/services/distributeddataservice/service/test/BUILD.gn +++ b/services/distributeddataservice/service/test/BUILD.gn @@ -1190,6 +1190,7 @@ ohos_unittest("UdmfServiceImplTest") { "${data_service_path}/service/udmf/store", "${data_service_path}/service/udmf", "${data_service_path}/framework/include", + "${data_service_path}/service/udmf/permission", ] cflags = [ @@ -1229,6 +1230,7 @@ ohos_unittest("UdmfServiceStubTest") { "${data_service_path}/service/udmf/store", "${data_service_path}/service/udmf", "${data_service_path}/framework/include", + "${data_service_path}/service/udmf/permission", ] cflags = [ diff --git a/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.cpp b/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.cpp index cbfdca07a..e427c2e73 100644 --- a/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.cpp +++ b/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.cpp @@ -23,6 +23,9 @@ namespace UDMF { using CleanAfterGet = LifeCyclePolicy; std::unordered_map> LifeCycleManager::intentionPolicy_ = { { UD_INTENTION_MAP.at(UD_INTENTION_DRAG), std::make_shared() }, + { UD_INTENTION_MAP.at(UD_INTENTION_PICKER), std::make_shared() }, + { UD_INTENTION_MAP.at(UD_INTENTION_MENU), std::make_shared() }, + { UD_INTENTION_MAP.at(UD_INTENTION_SYSTEM_SHARE), std::make_shared() }, { UD_INTENTION_MAP.at(UD_INTENTION_DATA_HUB), std::make_shared() } }; diff --git a/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.cpp b/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.cpp index cc3d88659..e620abd75 100644 --- a/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.cpp +++ b/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.cpp @@ -59,6 +59,8 @@ Status LifeCyclePolicy::OnTimeout(const std::string &intention) return E_DB_ERROR; } std::vector timeoutKeys; + Duration interval = INTERVAL; + CheckFileMangerIntention(intention, interval); auto status = GetTimeoutKeys(store, INTERVAL, timeoutKeys); if (status != E_OK) { ZLOGE("Timeout keys get failed"); @@ -97,5 +99,15 @@ Status LifeCyclePolicy::GetTimeoutKeys( } return E_OK; } + +Status LifeCyclePolicy::CheckFileMangerIntention(const std::string &intention, Duration &interval) +{ + if (intention == UD_INTENTION_MAP.at(UD_INTENTION_SYSTEM_SHARE) || + intention == UD_INTENTION_MAP.at(UD_INTENTION_PICKER) || + intention == UD_INTENTION_MAP.at(UD_INTENTION_MENU)) { + interval = SYSTEM_SHARE_INTERVAL; + } + return E_OK; +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.h b/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.h index f7703e562..8f64b236f 100644 --- a/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.h +++ b/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.h @@ -23,6 +23,7 @@ class LifeCyclePolicy { public: using Duration = std::chrono::steady_clock::duration; static constexpr Duration INTERVAL = std::chrono::milliseconds(60 * 60 * 1000); + static constexpr Duration SYSTEM_SHARE_INTERVAL = std::chrono::milliseconds(24 * 60 * 60 * 1000); virtual ~LifeCyclePolicy() = default; virtual Status OnGot(const UnifiedKey &key); virtual Status OnStart(const std::string &intention); @@ -31,6 +32,7 @@ public: const std::shared_ptr &store, Duration interval, std::vector &timeoutKeys); private: + virtual Status CheckFileMangerIntention(const std::string &intention, Duration &interval); static constexpr const char *DATA_PREFIX = "udmf://"; }; } // namespace UDMF diff --git a/services/distributeddataservice/service/udmf/store/store_cache.cpp b/services/distributeddataservice/service/udmf/store/store_cache.cpp index 9bd6ae679..545b549a1 100644 --- a/services/distributeddataservice/service/udmf/store/store_cache.cpp +++ b/services/distributeddataservice/service/udmf/store/store_cache.cpp @@ -45,8 +45,7 @@ std::shared_ptr StoreCache::GetStore(std::string intention) return true; } - if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG) - || intention == UD_INTENTION_MAP.at(UD_INTENTION_DATA_HUB)) { + if (IsValidIntention(intention)) { storePtr = std::make_shared(intention); if (!storePtr->Init()) { ZLOGE("Init runtime store failed."); @@ -94,5 +93,10 @@ void StoreCache::CloseStores() ZLOGI("CloseStores, stores size:%{public}zu", stores_.Size()); stores_.Clear(); } + +bool StoreCache::IsValidIntention(const std::string &intention) +{ + return UnifiedDataUtils::GetIntentionByString(intention) != UD_INTENTION_BUTT; +} } // namespace UDMF } // namespace OHOS diff --git a/services/distributeddataservice/service/udmf/store/store_cache.h b/services/distributeddataservice/service/udmf/store/store_cache.h index dfc7933eb..5d3918d2d 100644 --- a/services/distributeddataservice/service/udmf/store/store_cache.h +++ b/services/distributeddataservice/service/udmf/store/store_cache.h @@ -38,6 +38,7 @@ private: StoreCache &operator=(const StoreCache &obj) = delete; void GarbageCollect(); + static bool IsValidIntention(const std::string &intention); ConcurrentMap> stores_; std::mutex taskMutex_; diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index 28bdac177..17e35b2d5 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -37,6 +37,7 @@ #include "system_ability_definition.h" #include "uri_permission_manager.h" #include "udmf_radar_reporter.h" +#include "udmf_utils.h" #include "unified_data_helper.h" #include "utils/anonymous.h" @@ -59,6 +60,7 @@ constexpr const char *DEVICE_2IN1_TAG = "2in1"; constexpr const char *DEVICE_PHONE_TAG = "phone"; constexpr const char *DEVICE_DEFAULT_TAG = "default"; constexpr const char *HAP_LIST[] = {"com.ohos.pasteboarddialog"}; +constexpr uint32_t FOUNDATION_UID = 5523; __attribute__((used)) UdmfServiceImpl::Factory UdmfServiceImpl::factory_; UdmfServiceImpl::Factory::Factory() { @@ -349,6 +351,7 @@ int32_t UdmfServiceImpl::ProcessCrossDeviceData(uint32_t tokenId, UnifiedData &u int32_t UdmfServiceImpl::GetBatchData(const QueryOption &query, std::vector &unifiedDataSet) { ZLOGD("start"); + UnifiedKey key(query.key); std::vector dataSet; std::shared_ptr store; auto status = QueryDataCommon(query, dataSet, store); @@ -360,6 +363,10 @@ int32_t UdmfServiceImpl::GetBatchData(const QueryOption &query, std::vector &unifiedDataSet) { ZLOGD("start"); + UnifiedKey key(query.key); + if (!key.IsValid() && !key.key.empty()) { + ZLOGE("invalid key, query.key: %{public}s", query.key.c_str()); + return E_INVALID_PARAMETERS; + } + std::string intention = UnifiedDataUtils::FindIntentionMap(query.intention); + if (!UnifiedDataUtils::ValidateIntention(key, intention)) { + ZLOGE("invalid option, query.key: %{public}s, intention: %{public}d", query.key.c_str(), query.intention); + return E_INVALID_PARAMETERS; + } std::vector dataSet; std::shared_ptr store; auto status = QueryDataCommon(query, dataSet, store); @@ -484,17 +507,16 @@ int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privi std::string processName; if (!PreProcessUtils::GetNativeProcessNameByToken(query.tokenId, processName)) { + ZLOGE("GetNativeProcessNameByToken is faild"); return E_ERROR; } - if (key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) { - if (find(DRAG_AUTHORIZED_PROCESSES, std::end(DRAG_AUTHORIZED_PROCESSES), processName) == - std::end(DRAG_AUTHORIZED_PROCESSES)) { - ZLOGE("Process:%{public}s lacks permission for intention:drag", processName.c_str()); - return E_NO_PERMISSION; - } - } else { - ZLOGE("Intention: %{public}s has no authorized processes", key.intention.c_str()); + if (CheckAddPrivilegePermission(key, processName, query) != E_OK) { + ZLOGE("Intention:%{public}s no permission", key.intention.c_str()); + return E_NO_PERMISSION; + } + if (!UTILS::IsNativeCallingToken()) { + ZLOGE("Calling Token is not native"); return E_NO_PERMISSION; } @@ -698,14 +720,17 @@ int32_t UdmfServiceImpl::OnInitialize() int32_t UdmfServiceImpl::QueryDataCommon( const QueryOption &query, std::vector &dataSet, std::shared_ptr &store) { - auto find = UD_INTENTION_MAP.find(query.intention); - std::string intention = find == UD_INTENTION_MAP.end() ? intention : find->second; - if (!UnifiedDataUtils::IsValidOptions(query.key, intention)) { + std::string intention = UnifiedDataUtils::FindIntentionMap(query.intention); + UnifiedKey key(query.key); + if (!key.key.empty() && !key.IsValid()) { + ZLOGE("invalid key, query.key: %{public}s", query.key.c_str()); + return E_INVALID_PARAMETERS; + } + if (!UnifiedDataUtils::ValidateIntention(key, intention)) { ZLOGE("Unified key: %{public}s and intention: %{public}s is invalid.", query.key.c_str(), intention.c_str()); return E_INVALID_PARAMETERS; } std::string dataPrefix = DATA_PREFIX + intention; - UnifiedKey key(query.key); key.IsValid(); if (intention.empty()) { dataPrefix = UnifiedKey(key.key).GetPropertyKey(); @@ -883,5 +908,81 @@ bool UdmfServiceImpl::IsNeedTransferDeviceType(const QueryOption &query) } return false; } + +int32_t UdmfServiceImpl::CheckAddPrivilegePermission(UnifiedKey &key, + std::string &processName, const QueryOption &query) +{ + if (UnifiedDataUtils::IsFileMangerIntention(key.intention)) { + if (IsFileMangerSa()) { + return E_OK; + } + std::string intention = UnifiedDataUtils::FindIntentionMap(query.intention); + if (!intention.empty() && key.intention != intention) { + ZLOGE("Query.intention no not equal to key.intention"); + return E_INVALID_PARAMETERS; + } + return E_OK; + } + if (key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) { + if (find(DRAG_AUTHORIZED_PROCESSES, std::end(DRAG_AUTHORIZED_PROCESSES), processName) == + std::end(DRAG_AUTHORIZED_PROCESSES)) { + ZLOGE("Process:%{public}s lacks permission for intention:drag", processName.c_str()); + return E_NO_PERMISSION; + } + return E_OK; + } + ZLOGE("Check addPrivilege permission is faild."); + return E_NO_PERMISSION; +} + +bool UdmfServiceImpl::IsFileMangerSa() +{ + if (IPCSkeleton::GetCallingUid() == FOUNDATION_UID) { + return true; + } + ZLOGE("Caller no permission"); + return false; +} + +int32_t UdmfServiceImpl::ProcessData(UnifiedKey &key, + const QueryOption &query, std::vector &dataSet) +{ + std::string intention = UnifiedDataUtils::FindIntentionMap(query.intention); + if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DATA_HUB) || + key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DATA_HUB)) { + return E_OK; + } + CheckerManager::CheckInfo info; + info.tokenId = query.tokenId; + for (auto &data : dataSet) { + auto ret = VerifyIntentionPermission(query, data, key, info); + if (ret != E_OK) { + ZLOGE("Verify intention permission is faild:%{public}d", ret); + return ret; + } + } + return E_OK; +} + +int32_t UdmfServiceImpl::VerifyIntentionPermission(const QueryOption &query, + UnifiedData &data, UnifiedKey &key, CheckerManager::CheckInfo &info) +{ + std::shared_ptr runtime = data.GetRuntime(); + if (runtime == nullptr) { + ZLOGE("runtime is nullptr."); + return E_DB_ERROR; + } + if (!CheckerManager::GetInstance().IsValid(runtime->privileges, info)) { + ZLOGE("Query no permission."); + return E_NO_PERMISSION; + } + if (!IsReadAndKeep(runtime->privileges, query)) { + if (LifeCycleManager::GetInstance().OnGot(key) != E_OK) { + ZLOGE("Remove data failed:%{public}s", key.intention.c_str()); + return E_DB_ERROR; + } + } + return E_OK; +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.h b/services/distributeddataservice/service/udmf/udmf_service_impl.h index 48a80b442..82e45cc78 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.h +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.h @@ -19,6 +19,7 @@ #include "store_cache.h" #include "udmf_service_stub.h" #include "kv_store_delegate_manager.h" +#include "checker_manager.h" namespace OHOS { namespace UDMF { /* @@ -60,7 +61,12 @@ private: void RegisterAsyncProcessInfo(const std::string &businessUdKey); void TransferToEntriesIfNeed(const QueryOption &query, UnifiedData &unifiedData); bool IsNeedTransferDeviceType(const QueryOption &query); - + bool CheckDragParams(UnifiedKey &key, const QueryOption &query); + int32_t CheckAddPrivilegePermission(UnifiedKey &key, std::string &processName, const QueryOption &query); + int32_t ProcessData(UnifiedKey &key, const QueryOption &query, std::vector &dataSet); + int32_t VerifyIntentionPermission(const QueryOption &query, UnifiedData &dataSet, + UnifiedKey &key, CheckerManager::CheckInfo &info); + bool IsFileMangerSa(); class Factory { public: Factory(); -- Gitee