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 static const std::string SCENE_BOARD_PKG_NAME = "com.ohos.sceneboard";
33 std::recursive_mutex g_instanceMutex;
34 }
OnProcessDied(const ProcessData & processData)35 void PrivacyAppUsingSecCompStateObserver::OnProcessDied(const ProcessData &processData)
36 {
37 ACCESSTOKEN_LOG_INFO(LABEL, "OnProcessDied pid %{public}d", processData.pid);
38 PrivacySecCompEnhanceAgent::GetInstance().RemoveSecCompEnhance(processData.pid);
39 }
40
NotifyAppManagerDeath()41 void PrivacySecCompAppManagerDeathCallback::NotifyAppManagerDeath()
42 {
43 ACCESSTOKEN_LOG_INFO(LABEL, "AppManagerDeath called");
44
45 PrivacySecCompEnhanceAgent::GetInstance().OnAppMgrRemoteDiedHandle();
46 }
47
GetInstance()48 PrivacySecCompEnhanceAgent& PrivacySecCompEnhanceAgent::GetInstance()
49 {
50 static PrivacySecCompEnhanceAgent* instance = nullptr;
51 if (instance == nullptr) {
52 std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
53 if (instance == nullptr) {
54 instance = new PrivacySecCompEnhanceAgent();
55 }
56 }
57 return *instance;
58 }
59
InitAppObserver()60 void PrivacySecCompEnhanceAgent::InitAppObserver()
61 {
62 if (observer_ != nullptr) {
63 return;
64 }
65 observer_ = new (std::nothrow) PrivacyAppUsingSecCompStateObserver();
66 if (observer_ == nullptr) {
67 ACCESSTOKEN_LOG_ERROR(LABEL, "New observer failed.");
68 return;
69 }
70 if (AppManagerAccessClient::GetInstance().RegisterApplicationStateObserver(observer_) != 0) {
71 ACCESSTOKEN_LOG_ERROR(LABEL, "Register observer failed.");
72 observer_ = nullptr;
73 return;
74 }
75 if (appManagerDeathCallback_ == nullptr) {
76 appManagerDeathCallback_ = std::make_shared<PrivacySecCompAppManagerDeathCallback>();
77 AppManagerAccessClient::GetInstance().RegisterDeathCallback(appManagerDeathCallback_);
78 }
79 }
80
PrivacySecCompEnhanceAgent()81 PrivacySecCompEnhanceAgent::PrivacySecCompEnhanceAgent()
82 {
83 InitAppObserver();
84 }
85
~PrivacySecCompEnhanceAgent()86 PrivacySecCompEnhanceAgent::~PrivacySecCompEnhanceAgent()
87 {
88 if (observer_ != nullptr) {
89 AppManagerAccessClient::GetInstance().UnregisterApplicationStateObserver(observer_);
90 observer_ = nullptr;
91 }
92 }
93
OnAppMgrRemoteDiedHandle()94 void PrivacySecCompEnhanceAgent::OnAppMgrRemoteDiedHandle()
95 {
96 ACCESSTOKEN_LOG_INFO(LABEL, "OnAppMgrRemoteDiedHandle.");
97 std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
98 secCompEnhanceData_.clear();
99 observer_ = nullptr;
100 }
101
RemoveSecCompEnhance(int pid)102 void PrivacySecCompEnhanceAgent::RemoveSecCompEnhance(int pid)
103 {
104 std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
105 for (auto iter = secCompEnhanceData_.begin(); iter != secCompEnhanceData_.end(); ++iter) {
106 if (iter->pid == pid) {
107 secCompEnhanceData_.erase(iter);
108 ACCESSTOKEN_LOG_INFO(LABEL, "Remove pid %{public}d data.", pid);
109 return;
110 }
111 }
112 ACCESSTOKEN_LOG_ERROR(LABEL, "Not found pid %{public}d data.", pid);
113 return;
114 }
115
RegisterSecCompEnhance(const SecCompEnhanceData & enhanceData)116 int32_t PrivacySecCompEnhanceAgent::RegisterSecCompEnhance(const SecCompEnhanceData& enhanceData)
117 {
118 std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
119 InitAppObserver();
120 int pid = IPCSkeleton::GetCallingPid();
121 if (std::any_of(secCompEnhanceData_.begin(), secCompEnhanceData_.end(),
122 [pid](const auto& e) { return e.pid == pid; })) {
123 ACCESSTOKEN_LOG_ERROR(LABEL, "Register sec comp enhance exist, pid %{public}d.", pid);
124 return PrivacyError::ERR_CALLBACK_ALREADY_EXIST;
125 }
126 SecCompEnhanceData enhance;
127 enhance.callback = enhanceData.callback;
128 enhance.pid = pid;
129 enhance.token = IPCSkeleton::GetCallingTokenID();
130 enhance.challenge = enhanceData.challenge;
131 enhance.sessionId = enhanceData.sessionId;
132 enhance.seqNum = enhanceData.seqNum;
133 enhance.isSceneBoard = false;
134 if (memcpy_s(enhance.key, AES_KEY_STORAGE_LEN, enhanceData.key, AES_KEY_STORAGE_LEN) != EOK) {
135 return PrivacyError::ERR_CALLBACK_ALREADY_EXIST;
136 }
137 HapTokenInfo info;
138 if (AccessTokenKit::GetHapTokenInfo(enhance.token, info) == AccessTokenKitRet::RET_SUCCESS) {
139 if (info.bundleName == SCENE_BOARD_PKG_NAME) {
140 enhance.isSceneBoard = true;
141 }
142 }
143 secCompEnhanceData_.emplace_back(enhance);
144 ACCESSTOKEN_LOG_INFO(LABEL, "Register sec comp enhance success, pid %{public}d, total %{public}u.",
145 pid, static_cast<uint32_t>(secCompEnhanceData_.size()));
146 return RET_SUCCESS;
147 }
148
UpdateSecCompEnhance(int32_t pid,uint32_t seqNum)149 int32_t PrivacySecCompEnhanceAgent::UpdateSecCompEnhance(int32_t pid, uint32_t seqNum)
150 {
151 std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
152 InitAppObserver();
153 for (auto iter = secCompEnhanceData_.begin(); iter != secCompEnhanceData_.end(); ++iter) {
154 if (iter->pid == pid) {
155 iter->seqNum = seqNum;
156 ACCESSTOKEN_LOG_INFO(LABEL, "Update pid=%{public}d data successful.", pid);
157 return RET_SUCCESS;
158 }
159 }
160 return ERR_PARAM_INVALID;
161 }
162
GetSecCompEnhance(int32_t pid,SecCompEnhanceData & enhanceData)163 int32_t PrivacySecCompEnhanceAgent::GetSecCompEnhance(int32_t pid, SecCompEnhanceData& enhanceData)
164 {
165 std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
166 InitAppObserver();
167 for (auto iter = secCompEnhanceData_.begin(); iter != secCompEnhanceData_.end(); ++iter) {
168 if (iter->pid == pid) {
169 enhanceData = *iter;
170 ACCESSTOKEN_LOG_INFO(LABEL, "Get pid %{public}d data.", pid);
171 return RET_SUCCESS;
172 }
173 }
174 return ERR_PARAM_INVALID;
175 }
176
GetSpecialSecCompEnhance(const std::string & bundleName,std::vector<SecCompEnhanceData> & enhanceList)177 int32_t PrivacySecCompEnhanceAgent::GetSpecialSecCompEnhance(const std::string& bundleName,
178 std::vector<SecCompEnhanceData>& enhanceList)
179 {
180 std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
181 for (auto iter = secCompEnhanceData_.begin(); iter != secCompEnhanceData_.end(); iter++) {
182 if ((*iter).isSceneBoard) {
183 enhanceList.emplace_back(*iter);
184 }
185 }
186 return RET_SUCCESS;
187 }
188 } // namespace AccessToken
189 } // namespace Security
190 } // namespace OHOS
191