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 "sec_comp_perm_manager.h"
16
17 #include "sec_comp_err.h"
18 #include "sec_comp_log.h"
19
20 namespace OHOS {
21 namespace Security {
22 namespace SecurityComponent {
23 namespace {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_SECURITY_COMPONENT, "SecCompPermManager"};
25 static const int32_t DELAY_REVOKE_MILLISECONDS = 10 * 1000;
26 static const std::string REVOKE_TASK_PREFIX = "RevokeAll";
27 static const std::string REVOKE_SAVE_PERM_TASK_PREFIX = "RevokeSavePerm";
28 }
29
GetInstance()30 SecCompPermManager& SecCompPermManager::GetInstance()
31 {
32 static SecCompPermManager instance;
33 return instance;
34 }
35
DelaySaveRevokePermission(AccessToken::AccessTokenID tokenId,const std::string & taskName)36 bool SecCompPermManager::DelaySaveRevokePermission(AccessToken::AccessTokenID tokenId, const std::string& taskName)
37 {
38 if (secHandler_ == nullptr) {
39 SC_LOG_ERROR(LABEL, "fail to get EventHandler");
40 return false;
41 }
42
43 std::function<void()> delayed = ([tokenId]() {
44 SC_LOG_DEBUG(LABEL, "delay revoke save permission");
45 SecCompPermManager::GetInstance().RevokeTempSavePermissionCount(tokenId);
46 });
47
48 SC_LOG_DEBUG(LABEL, "revoke save permission after %{public}d ms", DELAY_REVOKE_MILLISECONDS);
49 secHandler_->ProxyPostTask(delayed, taskName, DELAY_REVOKE_MILLISECONDS);
50 return true;
51 }
52
RevokeSavePermissionTask(const std::string & taskName)53 bool SecCompPermManager::RevokeSavePermissionTask(const std::string& taskName)
54 {
55 if (secHandler_ == nullptr) {
56 SC_LOG_ERROR(LABEL, "fail to get EventHandler");
57 return false;
58 }
59
60 SC_LOG_DEBUG(LABEL, "revoke save permission task name:%{public}s", taskName.c_str());
61 secHandler_->ProxyRemoveTask(taskName);
62 return true;
63 }
64
GrantTempSavePermission(AccessToken::AccessTokenID tokenId)65 int32_t SecCompPermManager::GrantTempSavePermission(AccessToken::AccessTokenID tokenId)
66 {
67 auto current = static_cast<uint64_t>(std::chrono::high_resolution_clock::now().time_since_epoch().count());
68 std::string taskName = std::to_string(tokenId) + std::to_string(current);
69 if (!DelaySaveRevokePermission(tokenId, taskName)) {
70 return SC_SERVICE_ERROR_PERMISSION_OPER_FAIL;
71 }
72 std::lock_guard<std::mutex> lock(mutex_);
73 saveTaskDequeMap_[tokenId].push_back(taskName);
74 applySaveCountMap_[tokenId]++;
75 SC_LOG_DEBUG(LABEL, "tokenId: %{public}d current permission apply counts is: %{public}d.",
76 tokenId, applySaveCountMap_[tokenId]);
77 return SC_OK;
78 }
79
RevokeTempSavePermissionCount(AccessToken::AccessTokenID tokenId)80 void SecCompPermManager::RevokeTempSavePermissionCount(AccessToken::AccessTokenID tokenId)
81 {
82 std::lock_guard<std::mutex> lock(mutex_);
83 auto iter = applySaveCountMap_.find(tokenId);
84 if (iter == applySaveCountMap_.end()) {
85 SC_LOG_ERROR(LABEL, "This hap has no permissions to save files.");
86 return;
87 }
88 if (saveTaskDequeMap_[tokenId].size() == 0) {
89 SC_LOG_ERROR(LABEL, "Current no task need to be revoke.");
90 return;
91 }
92 std::string taskName = saveTaskDequeMap_[tokenId].front();
93 if (!RevokeSavePermissionTask(taskName)) {
94 return;
95 }
96 saveTaskDequeMap_[tokenId].pop_front();
97 SC_LOG_DEBUG(LABEL, "tokenId: %{public}d current permission apply counts is: %{public}d.",
98 tokenId, applySaveCountMap_[tokenId]);
99 if ((--applySaveCountMap_[tokenId]) == 0) {
100 applySaveCountMap_.erase(tokenId);
101 SC_LOG_INFO(LABEL, "tokenId: %{public}d save permission count is 0, revoke it.", tokenId);
102 }
103 return;
104 }
105
RevokeTempSavePermission(AccessToken::AccessTokenID tokenId)106 void SecCompPermManager::RevokeTempSavePermission(AccessToken::AccessTokenID tokenId)
107 {
108 std::lock_guard<std::mutex> lock(mutex_);
109 applySaveCountMap_.erase(tokenId);
110 auto& taskDeque = saveTaskDequeMap_[tokenId];
111 for (auto iter = taskDeque.begin(); iter != taskDeque.end(); ++iter) {
112 if (!RevokeSavePermissionTask(*iter)) {
113 continue;
114 }
115 }
116 taskDeque.clear();
117 SC_LOG_INFO(LABEL, "tokenId: %{public}d revoke save permission.", tokenId);
118 return;
119 }
120
VerifySavePermission(AccessToken::AccessTokenID tokenId)121 bool SecCompPermManager::VerifySavePermission(AccessToken::AccessTokenID tokenId)
122 {
123 std::lock_guard<std::mutex> lock(mutex_);
124 auto iter = applySaveCountMap_.find(tokenId);
125 if (iter == applySaveCountMap_.end() || applySaveCountMap_[tokenId] == 0) {
126 SC_LOG_ERROR(LABEL, "This hap has no permissions to save files.");
127 return false;
128 }
129 return true;
130 }
131
VerifyPermission(AccessToken::AccessTokenID tokenId,SecCompType type)132 bool SecCompPermManager::VerifyPermission(AccessToken::AccessTokenID tokenId, SecCompType type)
133 {
134 int32_t res;
135 switch (type) {
136 case LOCATION_COMPONENT:
137 res = AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, "ohos.permission.LOCATION");
138 if (res != AccessToken::TypePermissionState::PERMISSION_GRANTED) {
139 return false;
140 }
141 res = AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, "ohos.permission.APPROXIMATELY_LOCATION");
142 return (res == AccessToken::TypePermissionState::PERMISSION_GRANTED);
143 case PASTE_COMPONENT:
144 res = AccessToken::AccessTokenKit::VerifyAccessToken(tokenId,
145 "ohos.permission.SECURE_PASTE");
146 return (res == AccessToken::TypePermissionState::PERMISSION_GRANTED);
147 case SAVE_COMPONENT:
148 return VerifySavePermission(tokenId);
149 default:
150 SC_LOG_ERROR(LABEL, "Unknown component type.");
151 }
152 return false;
153 }
154
AddAppGrantPermissionRecord(AccessToken::AccessTokenID tokenId,const std::string & permissionName)155 void SecCompPermManager::AddAppGrantPermissionRecord(AccessToken::AccessTokenID tokenId,
156 const std::string& permissionName)
157 {
158 auto iter = grantMap_.find(tokenId);
159 if (iter != grantMap_.end()) {
160 iter->second.insert(permissionName);
161 return;
162 }
163 std::set<std::string> permSet;
164 permSet.insert(permissionName);
165 grantMap_[tokenId] = permSet;
166 }
167
RemoveAppGrantPermissionRecord(AccessToken::AccessTokenID tokenId,const std::string & permissionName)168 void SecCompPermManager::RemoveAppGrantPermissionRecord(AccessToken::AccessTokenID tokenId,
169 const std::string& permissionName)
170 {
171 auto iter = grantMap_.find(tokenId);
172 if (iter == grantMap_.end()) {
173 return;
174 }
175
176 grantMap_[tokenId].erase(permissionName);
177 }
178
GrantAppPermission(AccessToken::AccessTokenID tokenId,const std::string & permissionName)179 int32_t SecCompPermManager::GrantAppPermission(AccessToken::AccessTokenID tokenId,
180 const std::string& permissionName)
181 {
182 std::lock_guard<std::mutex> lock(grantMtx_);
183 int32_t res = AccessToken::AccessTokenKit::GrantPermission(tokenId, permissionName,
184 AccessToken::PermissionFlag::PERMISSION_COMPONENT_SET);
185 SC_LOG_INFO(LABEL, "grant permission res: %{public}d, permission: %{public}s, tokenId:%{public}d",
186 res, permissionName.c_str(), tokenId);
187
188 AddAppGrantPermissionRecord(tokenId, permissionName);
189 return res;
190 }
191
RevokeAppPermission(AccessToken::AccessTokenID tokenId,const std::string & permissionName)192 int32_t SecCompPermManager::RevokeAppPermission(AccessToken::AccessTokenID tokenId,
193 const std::string& permissionName)
194 {
195 std::lock_guard<std::mutex> lock(grantMtx_);
196 int32_t res = AccessToken::AccessTokenKit::RevokePermission(tokenId, permissionName,
197 AccessToken::PermissionFlag::PERMISSION_COMPONENT_SET);
198 SC_LOG_INFO(LABEL, "revoke permission res: %{public}d, permission: %{public}s, tokenId:%{public}d",
199 res, permissionName.c_str(), tokenId);
200
201 RemoveAppGrantPermissionRecord(tokenId, permissionName);
202 return res;
203 }
204
RevokeAppPermissions(AccessToken::AccessTokenID tokenId)205 void SecCompPermManager::RevokeAppPermissions(AccessToken::AccessTokenID tokenId)
206 {
207 RevokeAppPermisionsImmediately(tokenId);
208 CancelAppRevokingPermisions(tokenId);
209 }
210
RevokeAppPermisionsDelayed(AccessToken::AccessTokenID tokenId)211 void SecCompPermManager::RevokeAppPermisionsDelayed(AccessToken::AccessTokenID tokenId)
212 {
213 if (secHandler_ == nullptr) {
214 SC_LOG_ERROR(LABEL, "fail to get EventHandler");
215 return;
216 }
217
218 std::function<void()> delayed = ([tokenId]() {
219 SC_LOG_DEBUG(LABEL, "delay revoke token id %{public}d permissions", tokenId);
220 SecCompPermManager::GetInstance().RevokeAppPermisionsImmediately(tokenId);
221 });
222
223 SC_LOG_DEBUG(LABEL, "revoke token id %{public}d permissions after %{public}d ms",
224 tokenId, DELAY_REVOKE_MILLISECONDS);
225 std::string taskName = REVOKE_TASK_PREFIX + std::to_string(tokenId);
226 secHandler_->ProxyPostTask(delayed, taskName, DELAY_REVOKE_MILLISECONDS);
227 }
228
RevokeAppPermisionsImmediately(AccessToken::AccessTokenID tokenId)229 void SecCompPermManager::RevokeAppPermisionsImmediately(AccessToken::AccessTokenID tokenId)
230 {
231 std::lock_guard<std::mutex> lock(grantMtx_);
232 auto it = grantMap_.find(tokenId);
233 if (it == grantMap_.end()) {
234 return;
235 }
236
237 auto& grantSet = grantMap_[tokenId];
238 for (auto iter = grantSet.begin(); iter != grantSet.end(); ++iter) {
239 int32_t res = AccessToken::AccessTokenKit::RevokePermission(tokenId, *iter,
240 AccessToken::PermissionFlag::PERMISSION_COMPONENT_SET);
241 SC_LOG_INFO(LABEL, "revoke token id %{public}d permission %{public}s res %{public}d",
242 tokenId, iter->c_str(), res);
243 }
244 grantSet.clear();
245 }
246
CancelAppRevokingPermisions(AccessToken::AccessTokenID tokenId)247 void SecCompPermManager::CancelAppRevokingPermisions(AccessToken::AccessTokenID tokenId)
248 {
249 if (secHandler_ == nullptr) {
250 SC_LOG_ERROR(LABEL, "fail to get EventHandler");
251 return;
252 }
253
254 SC_LOG_DEBUG(LABEL, "cancel revoke token id %{public}d permission", tokenId);
255 std::string taskName = REVOKE_TASK_PREFIX + std::to_string(tokenId);
256 secHandler_->ProxyRemoveTask(taskName);
257 }
258
InitEventHandler(const std::shared_ptr<SecEventHandler> & secHandler)259 void SecCompPermManager::InitEventHandler(const std::shared_ptr<SecEventHandler>& secHandler)
260 {
261 secHandler_ = secHandler;
262 }
263 } // namespace SecurityComponent
264 } // namespace Security
265 } // namespace OHOS
266