diff --git a/services/distributeddataservice/service/test/udmf_service_impl_test.cpp b/services/distributeddataservice/service/test/udmf_service_impl_test.cpp index c43180b4a78ad4769626aea38dbc5a58283908aa..bc39e7fc2d59b8fcf13a8f389b721ef6068eda76 100644 --- a/services/distributeddataservice/service/test/udmf_service_impl_test.cpp +++ b/services/distributeddataservice/service/test/udmf_service_impl_test.cpp @@ -182,6 +182,21 @@ HWTEST_F(UdmfServiceImplTest, Sync001, TestSize.Level1) EXPECT_EQ(ret, E_INVALID_PARAMETERS); } +/** +* @tc.name: VerifyPermission001 +* @tc.desc: Abnormal test of VerifyPermission, permission is empty +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfServiceImplTest, VerifyPermission001, TestSize.Level1) +{ + std::string permission; + uint32_t callerTokenId = 0; + UdmfServiceImpl udmfServiceImpl; + bool ret = udmfServiceImpl.VerifyPermission(permission, callerTokenId); + EXPECT_FALSE(ret); +} + /** * @tc.name: IsRemoteData001 * @tc.desc: Abnormal test of IsRemoteData, query.key is invalid @@ -530,5 +545,45 @@ HWTEST_F(UdmfServiceImplTest, CheckDeleteDataPermission004, TestSize.Level1) bool ret = impl.CheckDeleteDataPermission(appId, runtime, query); EXPECT_FALSE(ret); } + +/** + * @tc.name: VerifyDataAccessPermission001 + * @tc.desc: no permission + * @tc.type: FUNC + */ +HWTEST_F(UdmfServiceImplTest, VerifyDataAccessPermission001, TestSize.Level1) +{ + std::shared_ptr runtime = std::make_shared(); + const QueryOption query; + UnifiedData unifiedData; + + UdmfServiceImpl impl; + auto result = impl.VerifyDataAccessPermission(runtime, query, unifiedData); + EXPECT_EQ(result, E_NO_PERMISSION); +} + +/** + * @tc.name: VerifyDataAccessPermission002 + * @tc.desc: runtime is nullptr + * @tc.type: FUNC + */ +HWTEST_F(UdmfServiceImplTest, VerifyDataAccessPermission002, TestSize.Level1) +{ + std::shared_ptr runtime = std::make_shared(); + Privilege privilege { + .tokenId = TOKEN_ID, + .readPermission = STORE_ID, + .writePermission = STORE_ID, + }; + runtime->privileges = { privilege }; + QueryOption query; + query.tokenId = TOKEN_ID; + UnifiedData unifiedData; + + UdmfServiceImpl impl; + auto result = impl.VerifyDataAccessPermission(runtime, query, unifiedData); + EXPECT_EQ(runtime->privileges[0].tokenId, query.tokenId); + EXPECT_EQ(result, OHOS::UDMF::E_OK); +} }; // namespace DistributedDataTest }; // namespace OHOS::Test diff --git a/services/distributeddataservice/service/udmf/BUILD.gn b/services/distributeddataservice/service/udmf/BUILD.gn index 313702368a3e1e27eb143a05bb5c1a131dd21072..6ab6b40031a197f2ef98e7f6617813c40e8b62f8 100644 --- a/services/distributeddataservice/service/udmf/BUILD.gn +++ b/services/distributeddataservice/service/udmf/BUILD.gn @@ -66,7 +66,10 @@ ohos_source_set("udmf_server") { "-Oz", ] - deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] + deps = [ + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service/permission:distributeddata_permit" + ] external_deps = [ "ability_base:zuri", diff --git a/services/distributeddataservice/service/udmf/store/store_cache.cpp b/services/distributeddataservice/service/udmf/store/store_cache.cpp index acc6bf716d5f6b6744b533253ded413742762a73..442af3a98b6f0033ca2931bae96ead944338b44c 100644 --- a/services/distributeddataservice/service/udmf/store/store_cache.cpp +++ b/services/distributeddataservice/service/udmf/store/store_cache.cpp @@ -57,7 +57,7 @@ std::shared_ptr StoreCache::GetStore(std::string intention) }); std::unique_lock lock(taskMutex_); if (taskId_ == ExecutorPool::INVALID_TASK_ID && executorPool_ != nullptr) { - taskId_ = executorPool_->Schedule(std::chrono::minutes(INTERVAL), std::bind(&StoreCache::GarbageCollect, this)); + taskId_ = executorPool_->Schedule(std::chrono::minutes(INTERVAL), [this]() { this->GarbageCollect(); }); } return store; } @@ -75,7 +75,7 @@ void StoreCache::GarbageCollect() std::unique_lock lock(taskMutex_); if (!stores_.Empty() && executorPool_ != nullptr) { ZLOGD("GarbageCollect, stores size:%{public}zu", stores_.Size()); - taskId_ = executorPool_->Schedule(std::chrono::minutes(INTERVAL), std::bind(&StoreCache::GarbageCollect, this)); + taskId_ = executorPool_->Schedule(std::chrono::minutes(INTERVAL), [this]() { this->GarbageCollect(); }); } else { taskId_ = ExecutorPool::INVALID_TASK_ID; } diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index 1dd95e497ea3d61b8f9700905b1e9affc8954582..dc285565af4718efc4cb14f0a349a60e891e336b 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -42,6 +42,7 @@ #include "udmf_utils.h" #include "unified_data_helper.h" #include "utils/anonymous.h" +#include "permission_validator.h" #include "bundle_mgr/bundlemgr_adapter.h" namespace OHOS { @@ -229,17 +230,14 @@ int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &uni ZLOGE("Get data incomplete,key:%{public}s", query.key.c_str()); return E_NOT_FOUND; } - - CheckerManager::CheckInfo info; - info.tokenId = query.tokenId; std::shared_ptr runtime = unifiedData.GetRuntime(); if (runtime == nullptr) { return E_DB_ERROR; } - if (!CheckerManager::GetInstance().IsValid(runtime->privileges, info) && !IsPermissionInCache(query)) { - RadarReporterAdapter::ReportFail(std::string(__FUNCTION__), - BizScene::GET_DATA, GetDataStage::VERIFY_PRIVILEGE, StageRes::FAILED, E_NO_PERMISSION); - return E_NO_PERMISSION; + + res = VerifyDataAccessPermission(runtime, query, unifiedData); + if (res != E_OK) { + return res; } if (key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) { @@ -258,14 +256,33 @@ int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &uni } } - privilegeCache_.erase(query.key); - + { + std::lock_guard lock(cacheMutex_); + privilegeCache_.erase(query.key); + } PreProcessUtils::SetRemoteData(unifiedData); return E_OK; } +int32_t UdmfServiceImpl::VerifyDataAccessPermission(std::shared_ptr runtime, const QueryOption &query, + const UnifiedData &unifiedData) +{ + CheckerManager::CheckInfo info; + info.tokenId = query.tokenId; + + if (!CheckerManager::GetInstance().IsValid(runtime->privileges, info) && !IsPermissionInCache(query)) { + RadarReporterAdapter::ReportFail(std::string(__FUNCTION__), + BizScene::GET_DATA, GetDataStage::VERIFY_PRIVILEGE, StageRes::FAILED, E_NO_PERMISSION); + ZLOGE("Get data failed,key:%{public}s", query.key.c_str()); + return E_NO_PERMISSION; + } + + return E_OK; +} + bool UdmfServiceImpl::IsPermissionInCache(const QueryOption &query) { + std::lock_guard lock(cacheMutex_); auto iter = privilegeCache_.find(query.key); if (iter != privilegeCache_.end() && iter->second.tokenId == query.tokenId) { return true; @@ -281,6 +298,7 @@ bool UdmfServiceImpl::IsReadAndKeep(const std::vector &privileges, co } } + std::lock_guard lock(cacheMutex_); auto iter = privilegeCache_.find(query.key); if (iter != privilegeCache_.end() && iter->second.tokenId == query.tokenId && iter->second.readPermission == PRIVILEGE_READ_AND_KEEP) { @@ -589,6 +607,7 @@ int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privi Runtime runtime; int32_t res = store->GetRuntime(query.key, runtime); if (res == E_NOT_FOUND) { + std::lock_guard lock(cacheMutex_); privilegeCache_[query.key] = privilege; ZLOGW("Add privilege in cache, key: %{public}s.", query.key.c_str()); return E_OK; @@ -609,6 +628,11 @@ int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privi int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vector &devices) { + if (!UTILS::IsTokenNative() && + !DistributedKv::PermissionValidator::GetInstance().CheckSyncPermission(query.tokenId)) { + ZLOGE("Tokenid permission verification failed!"); + return E_NO_PERMISSION; + } RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__), BizScene::SYNC_DATA, SyncDataStage::SYNC_BEGIN, StageRes::IDLE, BizState::DFX_BEGIN); UnifiedKey key(query.key); @@ -943,7 +967,8 @@ int32_t UdmfServiceImpl::ResolveAutoLaunch(const std::string &identifier, DBLaun bool UdmfServiceImpl::VerifyPermission(const std::string &permission, uint32_t callerTokenId) { if (permission.empty()) { - return true; + ZLOGE("VerifyPermission failed, Permission is empty."); + return false; } int status = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerTokenId, permission); if (status != Security::AccessToken::PermissionState::PERMISSION_GRANTED) { @@ -1181,11 +1206,20 @@ int32_t UdmfServiceImpl::PushDelayData(const std::string &key, UnifiedData &unif ZLOGE("ProcessUri failed:%{public}d", ret); return E_NO_PERMISSION; } - privilegeCache_.erase(key); + { + std::lock_guard lock(cacheMutex_); + privilegeCache_.erase(key); + } PreProcessUtils::SetRemoteData(unifiedData); TransferToEntriesIfNeed(query, unifiedData); - auto callback = iface_cast(it.second.dataCallback); + return HandleDelayDataCallback(it.second, unifiedData, key); +} + +int32_t UdmfServiceImpl::HandleDelayDataCallback(DelayGetDataInfo &delayGetDataInfo, UnifiedData &unifiedData, + const std::string &key) +{ + auto callback = iface_cast(delayGetDataInfo.dataCallback); if (callback == nullptr) { ZLOGE("Delay data callback is null, key:%{public}s", key.c_str()); return E_ERROR; diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.h b/services/distributeddataservice/service/udmf/udmf_service_impl.h index 584eee68ffc7716abefdf283513ebd94153ddd67..b64267e29d1425849b57c4ff9638b3aecb2ffbb3 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.h +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.h @@ -85,6 +85,10 @@ private: int32_t CheckAppId(std::shared_ptr runtime, const std::string &bundleName); void CloseStoreWhenCorrupted(const std::string &intention, int32_t status); void HandleDbError(const std::string &intention, int32_t &status); + int32_t HandleDelayDataCallback(DelayGetDataInfo &delayGetDataInfo, UnifiedData &unifiedData, + const std::string &key); + int32_t VerifyDataAccessPermission(std::shared_ptr runtime, const QueryOption &query, + const UnifiedData &unifiedData); class Factory { public: Factory(); @@ -94,6 +98,7 @@ private: std::shared_ptr product_; }; static Factory factory_; + mutable std::recursive_mutex cacheMutex_; std::map privilegeCache_; std::shared_ptr executors_;