diff --git a/services/distributeddataservice/service/test/udmf_service_impl_test.cpp b/services/distributeddataservice/service/test/udmf_service_impl_test.cpp index bcb18a86406b7702f270ea8105c8d3d591010cec..ca167d70536edef292c9d272ad8a983bed97feeb 100644 --- a/services/distributeddataservice/service/test/udmf_service_impl_test.cpp +++ b/services/distributeddataservice/service/test/udmf_service_impl_test.cpp @@ -179,6 +179,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 @@ -431,5 +446,41 @@ HWTEST_F(UdmfServiceImplTest, IsValidInput004, TestSize.Level1) bool result = impl.IsValidInput(query, unifiedData, key); EXPECT_FALSE(result); } + +/** + * @tc.name: CheckRuntimeAndProcessRequest001 + * @tc.desc: no permission + * @tc.type: FUNC + */ +HWTEST_F(UdmfServiceImplTest, CheckRuntimeAndProcessRequest001, TestSize.Level1) +{ + std::shared_ptr runtime = std::make_shared(); + UnifiedKey key("udmf://DataHub/aaa/N]2fIEMbrJj@wp:jMuPa7"); + CheckerManager::CheckInfo info; + const QueryOption query; + UnifiedData unifiedData; + + UdmfServiceImpl impl; + auto result = impl.CheckRuntimeAndProcessRequest(runtime, key, info, query, unifiedData); + EXPECT_EQ(result, E_NO_PERMISSION); +} + +/** + * @tc.name: CheckRuntimeAndProcessRequest002 + * @tc.desc: runtime is nullptr + * @tc.type: FUNC + */ +HWTEST_F(UdmfServiceImplTest, CheckRuntimeAndProcessRequest002, TestSize.Level1) +{ + std::shared_ptr runtime; + UnifiedKey key("udmf://DataHub/aaa/N]2fIEMbrJj@wp:jMuPa7"); + CheckerManager::CheckInfo info; + const QueryOption query; + UnifiedData unifiedData; + + UdmfServiceImpl impl; + auto result = impl.CheckRuntimeAndProcessRequest(runtime, key, info, query, unifiedData); + EXPECT_EQ(result, OHOS::UDMF::E_DB_ERROR); +} }; // namespace DistributedDataTest }; // namespace OHOS::Test diff --git a/services/distributeddataservice/service/udmf/BUILD.gn b/services/distributeddataservice/service/udmf/BUILD.gn index 6180f01b6998dca381c6afa7f69b5783460ccb7f..df5233a884778981c447505fe8f615565de66662 100644 --- a/services/distributeddataservice/service/udmf/BUILD.gn +++ b/services/distributeddataservice/service/udmf/BUILD.gn @@ -19,6 +19,7 @@ config("module_public_config") { include_dirs = [ "${data_service_path}/adapter/include/communicator", "${data_service_path}/service/matrix/include", + "${data_service_path}/service/permission/include", "${data_service_path}/service/udmf/lifecycle", "${data_service_path}/service/udmf/permission", "${data_service_path}/service/udmf/preprocess", @@ -64,7 +65,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/udmf_service_impl.cpp b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index 1ceb45cc8c31ec8eb3c3b032727484ca8aa1cecb..b54bcca9bddbfe6c72c5cded43bcfd11e464364c 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" namespace OHOS { namespace UDMF { @@ -234,12 +235,38 @@ int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &uni CheckerManager::CheckInfo info; info.tokenId = query.tokenId; std::shared_ptr runtime = unifiedData.GetRuntime(); + auto status = CheckRuntimeAndProcessRequest(runtime, key, info, query, unifiedData); + if (status != E_OK) { + return status; + } + + 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; + } + } + + { + std::lock_guard lock(mutex_); + privilegeCache_.erase(query.key); + } + + PreProcessUtils::SetRemoteData(unifiedData); + return E_OK; +} + +int32_t UdmfServiceImpl::CheckRuntimeAndProcessRequest(std::shared_ptr runtime, UnifiedKey &key, + CheckerManager::CheckInfo &info, const QueryOption &query, UnifiedData &unifiedData) +{ if (runtime == nullptr) { + ZLOGE("Runtime is null."); 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); + ZLOGE("No permission."); return E_NO_PERMISSION; } @@ -252,21 +279,12 @@ int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &uni 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; - } - } - - privilegeCache_.erase(query.key); - - PreProcessUtils::SetRemoteData(unifiedData); return E_OK; } bool UdmfServiceImpl::IsPermissionInCache(const QueryOption &query) { + std::lock_guard lock(mutex_); auto iter = privilegeCache_.find(query.key); if (iter != privilegeCache_.end() && iter->second.tokenId == query.tokenId) { return true; @@ -282,6 +300,7 @@ bool UdmfServiceImpl::IsReadAndKeep(const std::vector &privileges, co } } + std::lock_guard lock(mutex_); auto iter = privilegeCache_.find(query.key); if (iter != privilegeCache_.end() && iter->second.tokenId == query.tokenId && iter->second.readPermission == PRIVILEGE_READ_AND_KEEP) { @@ -547,6 +566,7 @@ int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privi Runtime runtime; auto res = store->GetRuntime(query.key, runtime); if (res == E_NOT_FOUND) { + std::lock_guard lock(mutex_); privilegeCache_[query.key] = privilege; ZLOGW("Add privilege in cache, key: %{public}s.", query.key.c_str()); return E_OK; @@ -565,6 +585,12 @@ int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privi int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vector &devices) { + ZLOGD("start"); + 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); @@ -812,6 +838,7 @@ int32_t UdmfServiceImpl::QueryDataCommon( int32_t UdmfServiceImpl::OnBind(const BindInfo &bindInfo) { + std::lock_guard lock(mutex_); executors_ = bindInfo.executors; StoreCache::GetInstance().SetThreadPool(bindInfo.executors); LifeCycleManager::GetInstance().SetThreadPool(bindInfo.executors); @@ -891,7 +918,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("Permission is empty."); + return false; } int status = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerTokenId, permission); if (status != Security::AccessToken::PermissionState::PERMISSION_GRANTED) { @@ -1079,7 +1107,10 @@ int32_t UdmfServiceImpl::SetDelayInfo(const DataLoadInfo &dataLoadInfo, sptr(iUdmfNotifier)); + { + std::lock_guard lock(mutex_); + dataLoadCallback_.Insert(key, iface_cast(iUdmfNotifier)); + } auto store = StoreCache::GetInstance().GetStore(UD_INTENTION_MAP.at(UD_INTENTION_DRAG)); if (store == nullptr) { @@ -1110,14 +1141,17 @@ int32_t UdmfServiceImpl::PushDelayData(const std::string &key, UnifiedData &unif if (ret != E_OK) { ZLOGW("SetRemoteUri failed, ret:%{public}d, key:%{public}s.", ret, key.c_str()); } - - auto it = delayDataCallback_.Find(key); - if (!it.first) { - ZLOGE("DelayData callback no exist, key:%{public}s", key.c_str()); - return E_ERROR; + DelayGetDataInfo delayGetDataInfo; + { + auto it = delayDataCallback_.Find(key); + if (!it.first) { + ZLOGE("DelayData callback no exist, key:%{public}s", key.c_str()); + return E_ERROR; + } + delayGetDataInfo = it.second; } QueryOption query { - .tokenId = it.second.tokenId, + .tokenId = delayGetDataInfo.tokenId, .key = key }; if (option.tokenId != query.tokenId && !IsPermissionInCache(query)) { @@ -1129,17 +1163,29 @@ 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(mutex_); + privilegeCache_.erase(key); + } PreProcessUtils::SetRemoteData(unifiedData); TransferToEntriesIfNeed(query, unifiedData); - auto callback = iface_cast(it.second.dataCallback); + return HandleDelayDataCallback(delayGetDataInfo, 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; } callback->DelayDataCallback(key, unifiedData); - delayDataCallback_.Erase(key); + { + std::lock_guard lock(mutex_); + delayDataCallback_.Erase(key); + } return E_OK; } @@ -1167,6 +1213,7 @@ int32_t UdmfServiceImpl::GetDataIfAvailable(const std::string &key, const DataLo .dataCallback = iUdmfNotifier, .tokenId = static_cast(IPCSkeleton::GetCallingTokenID()), }; + std::lock_guard lock(mutex_); delayDataCallback_.InsertOrAssign(key, std::move(delayGetDataInfo)); auto it = dataLoadCallback_.Find(key); diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.h b/services/distributeddataservice/service/udmf/udmf_service_impl.h index 8f366463f115a91d92db2235973f50bd04c25a0c..967e8c61e85ce98ecfe9a3436f3b6b62a6553a03 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.h +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.h @@ -80,6 +80,10 @@ private: std::string FindIntentionMap(const Intention &queryintention); bool IsValidOptionsNonDrag(UnifiedKey &key, const std::string &intention); bool IsValidInput(const QueryOption &query, UnifiedData &unifiedData, UnifiedKey &key); + int32_t HandleDelayDataCallback(DelayGetDataInfo &delayGetDataInfo, UnifiedData &unifiedData, + const std::string &key); + int32_t CheckRuntimeAndProcessRequest(std::shared_ptr runtime, UnifiedKey &key, + CheckerManager::CheckInfo &info, const QueryOption &query, UnifiedData &unifiedData); class Factory { public: Factory();