1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "privacy_sec_comp_enhance_agent.h"
16
17 #include "access_token.h"
18 #include "accesstoken_kit.h"
19 #include "accesstoken_log.h"
20 #include "app_manager_access_client.h"
21 #include "ipc_skeleton.h"
22 #include "privacy_error.h"
23 #include "securec.h"
24
25 namespace OHOS {
26 namespace Security {
27 namespace AccessToken {
28 namespace {
29 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
30 LOG_CORE, SECURITY_DOMAIN_PRIVACY, "PrivacySecCompEnhanceAgent"
31 };
32 std::recursive_mutex g_instanceMutex;
33 }
OnProcessDied(const ProcessData & processData)34 void PrivacyAppUsingSecCompStateObserver::OnProcessDied(const ProcessData &processData)
35 {
36 ACCESSTOKEN_LOG_INFO(LABEL, "OnProcessDied pid %{public}d", processData.pid);
37 PrivacySecCompEnhanceAgent::GetInstance().RemoveSecCompEnhance(processData.pid);
38 }
39
NotifyAppManagerDeath()40 void PrivacySecCompAppManagerDeathCallback::NotifyAppManagerDeath()
41 {
42 ACCESSTOKEN_LOG_INFO(LABEL, "AppManagerDeath called");
43
44 PrivacySecCompEnhanceAgent::GetInstance().OnAppMgrRemoteDiedHandle();
45 }
46
GetInstance()47 PrivacySecCompEnhanceAgent& PrivacySecCompEnhanceAgent::GetInstance()
48 {
49 static PrivacySecCompEnhanceAgent* instance = nullptr;
50 if (instance == nullptr) {
51 std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
52 if (instance == nullptr) {
53 instance = new PrivacySecCompEnhanceAgent();
54 }
55 }
56 return *instance;
57 }
58
InitAppObserver()59 void PrivacySecCompEnhanceAgent::InitAppObserver()
60 {
61 if (observer_ != nullptr) {
62 return;
63 }
64 observer_ = new (std::nothrow) PrivacyAppUsingSecCompStateObserver();
65 if (observer_ == nullptr) {
66 ACCESSTOKEN_LOG_ERROR(LABEL, "New observer failed.");
67 return;
68 }
69 if (AppManagerAccessClient::GetInstance().RegisterApplicationStateObserver(observer_) != 0) {
70 ACCESSTOKEN_LOG_ERROR(LABEL, "Register observer failed.");
71 observer_ = nullptr;
72 return;
73 }
74 if (appManagerDeathCallback_ == nullptr) {
75 appManagerDeathCallback_ = std::make_shared<PrivacySecCompAppManagerDeathCallback>();
76 AppManagerAccessClient::GetInstance().RegisterDeathCallback(appManagerDeathCallback_);
77 }
78 }
79
PrivacySecCompEnhanceAgent()80 PrivacySecCompEnhanceAgent::PrivacySecCompEnhanceAgent()
81 {
82 InitAppObserver();
83 }
84
~PrivacySecCompEnhanceAgent()85 PrivacySecCompEnhanceAgent::~PrivacySecCompEnhanceAgent()
86 {
87 if (observer_ != nullptr) {
88 AppManagerAccessClient::GetInstance().UnregisterApplicationStateObserver(observer_);
89 observer_ = nullptr;
90 }
91 }
92
OnAppMgrRemoteDiedHandle()93 void PrivacySecCompEnhanceAgent::OnAppMgrRemoteDiedHandle()
94 {
95 ACCESSTOKEN_LOG_INFO(LABEL, "OnAppMgrRemoteDiedHandle.");
96 std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
97 secCompEnhanceData_.clear();
98 observer_ = nullptr;
99 }
100
RemoveSecCompEnhance(int pid)101 void PrivacySecCompEnhanceAgent::RemoveSecCompEnhance(int pid)
102 {
103 std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
104 for (auto iter = secCompEnhanceData_.begin(); iter != secCompEnhanceData_.end(); ++iter) {
105 if (iter->pid == pid) {
106 secCompEnhanceData_.erase(iter);
107 ACCESSTOKEN_LOG_INFO(LABEL, "Remove pid %{public}d data.", pid);
108 return;
109 }
110 }
111 ACCESSTOKEN_LOG_ERROR(LABEL, "Not found pid %{public}d data.", pid);
112 return;
113 }
114
RegisterSecCompEnhance(const SecCompEnhanceData & enhanceData)115 int32_t PrivacySecCompEnhanceAgent::RegisterSecCompEnhance(const SecCompEnhanceData& enhanceData)
116 {
117 std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
118 InitAppObserver();
119 int pid = IPCSkeleton::GetCallingPid();
120 if (std::any_of(secCompEnhanceData_.begin(), secCompEnhanceData_.end(),
121 [pid](const auto& e) { return e.pid == pid; })) {
122 ACCESSTOKEN_LOG_ERROR(LABEL, "Register sec comp enhance exist, pid %{public}d.", pid);
123 return PrivacyError::ERR_CALLBACK_ALREADY_EXIST;
124 }
125 SecCompEnhanceData enhance;
126 enhance.callback = enhanceData.callback;
127 enhance.pid = pid;
128 enhance.token = IPCSkeleton::GetCallingTokenID();
129 enhance.challenge = enhanceData.challenge;
130 enhance.sessionId = enhanceData.sessionId;
131 enhance.seqNum = enhanceData.seqNum;
132 if (memcpy_s(enhance.key, AES_KEY_STORAGE_LEN, enhanceData.key, AES_KEY_STORAGE_LEN) != EOK) {
133 return PrivacyError::ERR_CALLBACK_ALREADY_EXIST;
134 }
135 secCompEnhanceData_.emplace_back(enhance);
136 ACCESSTOKEN_LOG_INFO(LABEL, "Register sec comp enhance success, pid %{public}d, total %{public}u.",
137 pid, static_cast<uint32_t>(secCompEnhanceData_.size()));
138 return RET_SUCCESS;
139 }
140
UpdateSecCompEnhance(int32_t pid,uint32_t seqNum)141 int32_t PrivacySecCompEnhanceAgent::UpdateSecCompEnhance(int32_t pid, uint32_t seqNum)
142 {
143 std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
144 InitAppObserver();
145 for (auto iter = secCompEnhanceData_.begin(); iter != secCompEnhanceData_.end(); ++iter) {
146 if (iter->pid == pid) {
147 iter->seqNum = seqNum;
148 ACCESSTOKEN_LOG_INFO(LABEL, "Update pid=%{public}d data successful.", pid);
149 return RET_SUCCESS;
150 }
151 }
152 return ERR_PARAM_INVALID;
153 }
154
GetSecCompEnhance(int32_t pid,SecCompEnhanceData & enhanceData)155 int32_t PrivacySecCompEnhanceAgent::GetSecCompEnhance(int32_t pid, SecCompEnhanceData& enhanceData)
156 {
157 std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
158 InitAppObserver();
159 for (auto iter = secCompEnhanceData_.begin(); iter != secCompEnhanceData_.end(); ++iter) {
160 if (iter->pid == pid) {
161 enhanceData = *iter;
162 ACCESSTOKEN_LOG_INFO(LABEL, "Get pid %{public}d data.", pid);
163 return RET_SUCCESS;
164 }
165 }
166 return ERR_PARAM_INVALID;
167 }
168
GetSpecialSecCompEnhance(const std::string & bundleName,std::vector<SecCompEnhanceData> & enhanceList)169 int32_t PrivacySecCompEnhanceAgent::GetSpecialSecCompEnhance(const std::string& bundleName,
170 std::vector<SecCompEnhanceData>& enhanceList)
171 {
172 std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
173 for (auto iter = secCompEnhanceData_.begin(); iter != secCompEnhanceData_.end(); iter++) {
174 HapTokenInfo info;
175 if (AccessTokenKit::GetHapTokenInfo(iter->token, info) == AccessTokenKitRet::RET_SUCCESS) {
176 if (bundleName == info.bundleName) {
177 enhanceList.emplace_back(*iter);
178 }
179 }
180 }
181 return RET_SUCCESS;
182 }
183 } // namespace AccessToken
184 } // namespace Security
185 } // namespace OHOS
186