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
AddAppGrantPermissionRecord(AccessToken::AccessTokenID tokenId,const std::string & permissionName)132 void SecCompPermManager::AddAppGrantPermissionRecord(AccessToken::AccessTokenID tokenId,
133 const std::string& permissionName)
134 {
135 auto iter = grantMap_.find(tokenId);
136 if (iter != grantMap_.end()) {
137 iter->second.insert(permissionName);
138 return;
139 }
140 std::set<std::string> permSet;
141 permSet.insert(permissionName);
142 grantMap_[tokenId] = permSet;
143 }
144
RemoveAppGrantPermissionRecord(AccessToken::AccessTokenID tokenId,const std::string & permissionName)145 void SecCompPermManager::RemoveAppGrantPermissionRecord(AccessToken::AccessTokenID tokenId,
146 const std::string& permissionName)
147 {
148 auto iter = grantMap_.find(tokenId);
149 if (iter == grantMap_.end()) {
150 return;
151 }
152
153 grantMap_[tokenId].erase(permissionName);
154 }
155
GrantAppPermission(AccessToken::AccessTokenID tokenId,const std::string & permissionName)156 int32_t SecCompPermManager::GrantAppPermission(AccessToken::AccessTokenID tokenId,
157 const std::string& permissionName)
158 {
159 std::lock_guard<std::mutex> lock(grantMtx_);
160 int32_t res = AccessToken::AccessTokenKit::GrantPermission(tokenId, permissionName,
161 AccessToken::PermissionFlag::PERMISSION_COMPONENT_SET);
162 SC_LOG_INFO(LABEL, "grant permission res: %{public}d, permission: %{public}s, tokenId:%{public}d",
163 res, permissionName.c_str(), tokenId);
164
165 AddAppGrantPermissionRecord(tokenId, permissionName);
166 return res;
167 }
168
RevokeAppPermission(AccessToken::AccessTokenID tokenId,const std::string & permissionName)169 int32_t SecCompPermManager::RevokeAppPermission(AccessToken::AccessTokenID tokenId,
170 const std::string& permissionName)
171 {
172 std::lock_guard<std::mutex> lock(grantMtx_);
173 int32_t res = AccessToken::AccessTokenKit::RevokePermission(tokenId, permissionName,
174 AccessToken::PermissionFlag::PERMISSION_COMPONENT_SET);
175 SC_LOG_INFO(LABEL, "revoke permission res: %{public}d, permission: %{public}s, tokenId:%{public}d",
176 res, permissionName.c_str(), tokenId);
177
178 RemoveAppGrantPermissionRecord(tokenId, permissionName);
179 return res;
180 }
181
RevokeAppPermissions(AccessToken::AccessTokenID tokenId)182 void SecCompPermManager::RevokeAppPermissions(AccessToken::AccessTokenID tokenId)
183 {
184 RevokeAppPermisionsImmediately(tokenId);
185 CancelAppRevokingPermisions(tokenId);
186 }
187
RevokeAppPermisionsDelayed(AccessToken::AccessTokenID tokenId)188 void SecCompPermManager::RevokeAppPermisionsDelayed(AccessToken::AccessTokenID tokenId)
189 {
190 if (secHandler_ == nullptr) {
191 SC_LOG_ERROR(LABEL, "fail to get EventHandler");
192 return;
193 }
194
195 std::function<void()> delayed = ([tokenId]() {
196 SC_LOG_DEBUG(LABEL, "delay revoke token id %{public}d permissions", tokenId);
197 SecCompPermManager::GetInstance().RevokeAppPermisionsImmediately(tokenId);
198 });
199
200 SC_LOG_DEBUG(LABEL, "revoke token id %{public}d permissions after %{public}d ms",
201 tokenId, DELAY_REVOKE_MILLISECONDS);
202 std::string taskName = REVOKE_TASK_PREFIX + std::to_string(tokenId);
203 secHandler_->ProxyPostTask(delayed, taskName, DELAY_REVOKE_MILLISECONDS);
204 }
205
RevokeAppPermisionsImmediately(AccessToken::AccessTokenID tokenId)206 void SecCompPermManager::RevokeAppPermisionsImmediately(AccessToken::AccessTokenID tokenId)
207 {
208 std::lock_guard<std::mutex> lock(grantMtx_);
209 auto it = grantMap_.find(tokenId);
210 if (it == grantMap_.end()) {
211 return;
212 }
213
214 auto& grantSet = grantMap_[tokenId];
215 for (auto iter = grantSet.begin(); iter != grantSet.end(); ++iter) {
216 int32_t res = AccessToken::AccessTokenKit::RevokePermission(tokenId, *iter,
217 AccessToken::PermissionFlag::PERMISSION_COMPONENT_SET);
218 SC_LOG_INFO(LABEL, "revoke token id %{public}d permission %{public}s res %{public}d",
219 tokenId, iter->c_str(), res);
220 }
221 grantSet.clear();
222 }
223
CancelAppRevokingPermisions(AccessToken::AccessTokenID tokenId)224 void SecCompPermManager::CancelAppRevokingPermisions(AccessToken::AccessTokenID tokenId)
225 {
226 if (secHandler_ == nullptr) {
227 SC_LOG_ERROR(LABEL, "fail to get EventHandler");
228 return;
229 }
230
231 SC_LOG_DEBUG(LABEL, "cancel revoke token id %{public}d permission", tokenId);
232 std::string taskName = REVOKE_TASK_PREFIX + std::to_string(tokenId);
233 secHandler_->ProxyRemoveTask(taskName);
234 }
235
InitEventHandler(const std::shared_ptr<SecEventHandler> & secHandler)236 bool SecCompPermManager::InitEventHandler(const std::shared_ptr<SecEventHandler>& secHandler)
237 {
238 secHandler_ = secHandler;
239 return true;
240 }
241 } // namespace SecurityComponent
242 } // namespace Security
243 } // namespace OHOS
244