From 42ec20913b172137495a750a4fcefbfe16d39810 Mon Sep 17 00:00:00 2001 From: baoyang Date: Tue, 24 Jun 2025 22:51:12 +0800 Subject: [PATCH] add retry when sa exit Signed-off-by: baoyang Change-Id: If534adfae3c97df80836d285b2955f2476f58c3d --- .../include/sec_comp_client.h | 6 ++ .../src/sec_comp_client.cpp | 75 +++++++++++++++---- .../test/unittest/src/sec_comp_kit_test.cpp | 2 +- 3 files changed, 66 insertions(+), 17 deletions(-) diff --git a/frameworks/inner_api/security_component/include/sec_comp_client.h b/frameworks/inner_api/security_component/include/sec_comp_client.h index 46328a4..8602c0d 100644 --- a/frameworks/inner_api/security_component/include/sec_comp_client.h +++ b/frameworks/inner_api/security_component/include/sec_comp_client.h @@ -17,6 +17,7 @@ #define SECURITY_COMPONENT_CLIENT_H #include +#include #include #include #include "access_token.h" @@ -68,11 +69,16 @@ private: void LoadSecCompSa(); sptr GetProxy(bool doLoadSa); void GetProxyFromRemoteObject(const sptr& remoteObject); + int32_t TryRegisterSecurityComponent(SecCompType type, const std::string& componentInfo, + int32_t& scId, sptr proxy); std::mutex cvLock_; bool readyFlag_ = false; std::condition_variable secComCon_; std::mutex proxyMutex_; + bool secCompSAFlag_ = false; + std::condition_variable secCompSACon_; + std::mutex secCompSaMutex_; sptr proxy_ = nullptr; sptr serviceDeathObserver_ = nullptr; }; diff --git a/frameworks/inner_api/security_component/src/sec_comp_client.cpp b/frameworks/inner_api/security_component/src/sec_comp_client.cpp index 0708f20..897370e 100644 --- a/frameworks/inner_api/security_component/src/sec_comp_client.cpp +++ b/frameworks/inner_api/security_component/src/sec_comp_client.cpp @@ -21,7 +21,10 @@ #include "sec_comp_load_callback.h" #include "sec_comp_log.h" #include "sec_comp_service_proxy.h" +#include "sys_binder.h" #include "tokenid_kit.h" +#include +#include namespace OHOS { namespace Security { @@ -30,6 +33,10 @@ namespace { static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_SECURITY_COMPONENT, "SecCompClient"}; constexpr int32_t SA_ID_SECURITY_COMPONENT_SERVICE = 3506; static std::mutex g_instanceMutex; +static constexpr int32_t SENDREQ_FAIL_ERR = 32; +static const std::vector RETRY_CODE_LIST = { + SC_SERVICE_ERROR_SERVICE_NOT_EXIST, BR_DEAD_REPLY, BR_FAILED_REPLY, SENDREQ_FAIL_ERR }; +static constexpr int32_t SA_DIED_TIME_OUT = 500; } // namespace SecCompClient& SecCompClient::GetInstance() @@ -80,15 +87,9 @@ int32_t SecCompClient::RegisterWriteToRawdata(SecCompType type, const std::strin return SC_OK; } -int32_t SecCompClient::RegisterSecurityComponent(SecCompType type, - const std::string& componentInfo, int32_t& scId) +int32_t SecCompClient::TryRegisterSecurityComponent(SecCompType type, const std::string& componentInfo, + int32_t& scId, sptr proxy) { - auto proxy = GetProxy(true); - if (proxy == nullptr) { - SC_LOG_ERROR(LABEL, "Proxy is null"); - return SC_SERVICE_ERROR_VALUE_INVALID; - } - std::lock_guard lock(useIPCMutex_); SecCompRawdata rawData; if (RegisterWriteToRawdata(type, componentInfo, rawData) != SC_OK) { @@ -98,13 +99,14 @@ int32_t SecCompClient::RegisterSecurityComponent(SecCompType type, SecCompRawdata rawReply; int32_t res = proxy->RegisterSecurityComponent(rawData, rawReply); MessageParcel deserializedReply; - if (!SecCompEnhanceAdapter::EnhanceClientDeserialize(rawReply, deserializedReply)) { - SC_LOG_ERROR(LABEL, "Register deserialize session info failed."); - return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL; - } if (res != SC_OK) { SC_LOG_ERROR(LABEL, "Register request failed, result: %{public}d.", res); + return res; + } + + if (!SecCompEnhanceAdapter::EnhanceClientDeserialize(rawReply, deserializedReply)) { + SC_LOG_ERROR(LABEL, "Register deserialize session info failed."); return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL; } @@ -126,6 +128,30 @@ int32_t SecCompClient::RegisterSecurityComponent(SecCompType type, return res; } +int32_t SecCompClient::RegisterSecurityComponent(SecCompType type, + const std::string& componentInfo, int32_t& scId) +{ + auto proxy = GetProxy(true); + if (proxy == nullptr) { + SC_LOG_ERROR(LABEL, "Proxy is null."); + return SC_SERVICE_ERROR_VALUE_INVALID; + } + + auto res = TryRegisterSecurityComponent(type, componentInfo, scId, proxy); + if (std::find(RETRY_CODE_LIST.begin(), RETRY_CODE_LIST.end(), res) == RETRY_CODE_LIST.end()) { + return res; + } + + std::unique_lock lock(secCompSaMutex_); + auto waitStatus = secCompSACon_.wait_for(lock, std::chrono::milliseconds(SA_DIED_TIME_OUT), + [this]() { return secCompSAFlag_; }); + if (waitStatus) { + proxy = GetProxy(true); + return TryRegisterSecurityComponent(type, componentInfo, scId, proxy); + } + return res; +} + int32_t SecCompClient::UpdateWriteToRawdata(int32_t scId, const std::string& componentInfo, SecCompRawdata& rawData) { MessageParcel dataParcel; @@ -477,9 +503,15 @@ void SecCompClient::FinishStartSASuccess(const sptr& remoteObject { GetProxyFromRemoteObject(remoteObject); // get lock which wait_for release and send a notice so that wait_for can out of block - std::unique_lock lock(cvLock_); - readyFlag_ = true; - secComCon_.notify_one(); + { + std::unique_lock lock(cvLock_); + readyFlag_ = true; + secComCon_.notify_one(); + } + { + std::unique_lock lock(secCompSaMutex_); + secCompSAFlag_ = false; + } } void SecCompClient::FinishStartSAFail() @@ -487,7 +519,7 @@ void SecCompClient::FinishStartSAFail() SC_LOG_ERROR(LABEL, "get security component sa failed."); // get lock which wait_for release and send a notice std::unique_lock lock(cvLock_); - readyFlag_ = true; + readyFlag_ = false; secComCon_.notify_one(); } @@ -503,12 +535,23 @@ void SecCompClient::OnRemoteDiedHandle() { SC_LOG_ERROR(LABEL, "Remote service died"); std::unique_lock lock(proxyMutex_); + if (proxy_ != nullptr) { + auto remoteObj = proxy_->AsObject(); + if ((remoteObj != nullptr) && (serviceDeathObserver_ != nullptr)) { + remoteObj->RemoveDeathRecipient(serviceDeathObserver_); + } + } proxy_ = nullptr; serviceDeathObserver_ = nullptr; { std::unique_lock lock1(cvLock_); readyFlag_ = false; } + { + std::unique_lock lock1(secCompSaMutex_); + secCompSAFlag_ = true; + secCompSACon_.notify_one(); + } } void SecCompClient::GetProxyFromRemoteObject(const sptr& remoteObject) diff --git a/frameworks/inner_api/security_component/test/unittest/src/sec_comp_kit_test.cpp b/frameworks/inner_api/security_component/test/unittest/src/sec_comp_kit_test.cpp index 81c516a..ab248ab 100644 --- a/frameworks/inner_api/security_component/test/unittest/src/sec_comp_kit_test.cpp +++ b/frameworks/inner_api/security_component/test/unittest/src/sec_comp_kit_test.cpp @@ -218,7 +218,7 @@ HWTEST_F(SecCompKitTest, RegisterWithoutCallback001, TestSize.Level0) HWTEST_F(SecCompKitTest, FinishStartSAFail001, TestSize.Level0) { SecCompClient::GetInstance().FinishStartSAFail(); - EXPECT_TRUE(SecCompClient::GetInstance().readyFlag_); + EXPECT_EQ(SecCompClient::GetInstance().readyFlag_, false); SecCompClient::GetInstance().OnRemoteDiedHandle(); EXPECT_EQ(nullptr, SecCompClient::GetInstance().proxy_); SecCompClient::GetInstance().GetProxyFromRemoteObject(nullptr); -- Gitee