diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn index 9955ea5e3c3171874b3d1d5cbb783362c34fb481..f78279dd6100f1ecc4efeec839a024e45b0ad383 100644 --- a/services/distributeddataservice/service/test/BUILD.gn +++ b/services/distributeddataservice/service/test/BUILD.gn @@ -1274,6 +1274,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 = [ @@ -1313,6 +1314,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 cbfdca07a431b4edd55fba26efc3e70081f1d8dc..e427c2e7381b6acb73a8973b4565cd4ef2fc2407 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 095a95f65ddb346549999b6579cc3b8f6a73c412..5651c916ac301678abb7efa758126ee48d03bdf8 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 f7703e562be97760cb5218ca560c3afa4d2c8df4..2979965dc28df15da6b77a14d1929a02cdad4bf7 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: + 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 9bd6ae679bae31ba76641bfffa2aaaf18f483726..545b549a17b0145ca1a1957ba92ce5c7986594c9 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 dfc7933eb6611e72a929fe7bb344fca675597571..5d3918d2d0bd44121b6e8f7618eade4103ff3358 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 42ef97a5d3a3385b69f5e8793a8b8eb184fc1e71..e80a23d7c9c9d9312d65435abb54c59ac0fac775 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" @@ -60,6 +61,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() { @@ -373,6 +375,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 = FindIntentionMap(query.intention); + if (!IsValidOptionsNonDrag(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); @@ -497,17 +519,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; } @@ -715,10 +736,13 @@ 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; UnifiedKey key(query.key); - if (!UnifiedDataUtils::IsValidOptions(key, intention, UD_INTENTION_MAP.at(UD_INTENTION_DATA_HUB))) { + if (!key.IsValid() && !key.key.empty()) { + ZLOGE("invalid key, query.key: %{public}s", query.key.c_str()); + return E_INVALID_PARAMETERS; + } + std::string intention = FindIntentionMap(query.intention); + if (!IsValidOptionsNonDrag(key, intention)) { ZLOGE("Unified key: %{public}s and intention: %{public}s is invalid.", query.key.c_str(), intention.c_str()); return E_INVALID_PARAMETERS; } @@ -906,5 +930,110 @@ bool UdmfServiceImpl::IsNeedTransferDeviceType(const QueryOption &query) } return false; } + +int32_t UdmfServiceImpl::CheckAddPrivilegePermission(UnifiedKey &key, + std::string &processName, const QueryOption &query) +{ + if (IsFileMangerIntention(key.intention)) { + if (IsFileMangerSa()) { + return E_OK; + } + std::string intention = 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(const QueryOption &query, std::vector &dataSet) +{ + 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; + } + std::string intention = 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; +} + +bool UdmfServiceImpl::IsFileMangerIntention(const std::string &intention) +{ + Intention optionIntention = UnifiedDataUtils::GetIntentionByString(intention); + if (optionIntention == UD_INTENTION_SYSTEM_SHARE || + optionIntention == UD_INTENTION_MENU || + optionIntention == UD_INTENTION_PICKER) { + return true; + } + return false; +} + +std::string UdmfServiceImpl::FindIntentionMap(const Intention &queryIntention) +{ + auto find = UD_INTENTION_MAP.find(queryIntention); + return find == UD_INTENTION_MAP.end() ? "" : find->second; +} + +bool UdmfServiceImpl::IsValidOptionsNonDrag(UnifiedKey &key, const std::string &intention) +{ + if (UnifiedDataUtils::IsValidOptions(key, intention)) { + return !key.key.empty() || intention == UD_INTENTION_MAP.at(Intention::UD_INTENTION_DATA_HUB); + } + return false; +} } // 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 da95d6eb4dc8abacaed2fefe39abd2c7395f8d70..16b46026b9922825cda2b6344a3b8270c74cae8d 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 { /* @@ -61,7 +62,14 @@ private: 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(const QueryOption &query, std::vector &dataSet); + int32_t VerifyIntentionPermission(const QueryOption &query, UnifiedData &dataSet, + UnifiedKey &key, CheckerManager::CheckInfo &info); + bool IsFileMangerSa(); + bool IsFileMangerIntention(const std::string &intention); + std::string FindIntentionMap(const Intention &queryintention); + bool IsValidOptionsNonDrag(UnifiedKey &key, const std::string &intention); class Factory { public: Factory();