• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static std::mutex g_instanceMutex;
29 }
30 
GetInstance()31 SecCompPermManager& SecCompPermManager::GetInstance()
32 {
33     static SecCompPermManager* instance = nullptr;
34     if (instance == nullptr) {
35         std::lock_guard<std::mutex> lock(g_instanceMutex);
36         if (instance == nullptr) {
37             instance = new SecCompPermManager();
38         }
39     }
40     return *instance;
41 }
42 
DelaySaveRevokePermission(AccessToken::AccessTokenID tokenId,const std::string & taskName)43 bool SecCompPermManager::DelaySaveRevokePermission(AccessToken::AccessTokenID tokenId, const std::string& taskName)
44 {
45     if (secHandler_ == nullptr) {
46         SC_LOG_ERROR(LABEL, "fail to get EventHandler");
47         return false;
48     }
49 
50     std::function<void()> delayed = ([tokenId]() {
51         SC_LOG_DEBUG(LABEL, "delay revoke save permission");
52         SecCompPermManager::GetInstance().RevokeTempSavePermissionCount(tokenId);
53     });
54 
55     SC_LOG_DEBUG(LABEL, "revoke save permission after %{public}d ms", DELAY_REVOKE_MILLISECONDS);
56     secHandler_->ProxyPostTask(delayed, taskName, DELAY_REVOKE_MILLISECONDS);
57     return true;
58 }
59 
RevokeSavePermissionTask(const std::string & taskName)60 bool SecCompPermManager::RevokeSavePermissionTask(const std::string& taskName)
61 {
62     if (secHandler_ == nullptr) {
63         SC_LOG_ERROR(LABEL, "fail to get EventHandler");
64         return false;
65     }
66 
67     SC_LOG_DEBUG(LABEL, "revoke save permission task name:%{public}s", taskName.c_str());
68     secHandler_->ProxyRemoveTask(taskName);
69     return true;
70 }
71 
GrantTempSavePermission(AccessToken::AccessTokenID tokenId)72 int32_t SecCompPermManager::GrantTempSavePermission(AccessToken::AccessTokenID tokenId)
73 {
74     auto current = static_cast<uint64_t>(std::chrono::high_resolution_clock::now().time_since_epoch().count());
75     std::string taskName = std::to_string(tokenId) + std::to_string(current);
76     if (!DelaySaveRevokePermission(tokenId, taskName)) {
77         return SC_SERVICE_ERROR_PERMISSION_OPER_FAIL;
78     }
79     std::lock_guard<std::mutex> lock(mutex_);
80     saveTaskDequeMap_[tokenId].push_back(taskName);
81     applySaveCountMap_[tokenId]++;
82     SC_LOG_DEBUG(LABEL, "tokenId: %{public}d current permission apply counts is: %{public}d.",
83         tokenId, applySaveCountMap_[tokenId]);
84     return SC_OK;
85 }
86 
RevokeTempSavePermissionCount(AccessToken::AccessTokenID tokenId)87 void SecCompPermManager::RevokeTempSavePermissionCount(AccessToken::AccessTokenID tokenId)
88 {
89     std::lock_guard<std::mutex> lock(mutex_);
90     auto iter = applySaveCountMap_.find(tokenId);
91     if (iter == applySaveCountMap_.end()) {
92         SC_LOG_ERROR(LABEL, "This hap has no permissions to save files.");
93         return;
94     }
95     if (saveTaskDequeMap_[tokenId].size() == 0) {
96         SC_LOG_ERROR(LABEL, "Current no task need to be revoke.");
97         return;
98     }
99     std::string taskName = saveTaskDequeMap_[tokenId].front();
100     if (!RevokeSavePermissionTask(taskName)) {
101         return;
102     }
103     saveTaskDequeMap_[tokenId].pop_front();
104     SC_LOG_DEBUG(LABEL, "tokenId: %{public}d current permission apply counts is: %{public}d.",
105         tokenId, applySaveCountMap_[tokenId]);
106     if ((--applySaveCountMap_[tokenId]) == 0) {
107         applySaveCountMap_.erase(tokenId);
108         SC_LOG_INFO(LABEL, "tokenId: %{public}d save permission count is 0, revoke it.", tokenId);
109     }
110     return;
111 }
112 
RevokeTempSavePermission(AccessToken::AccessTokenID tokenId)113 void SecCompPermManager::RevokeTempSavePermission(AccessToken::AccessTokenID tokenId)
114 {
115     std::lock_guard<std::mutex> lock(mutex_);
116     applySaveCountMap_.erase(tokenId);
117     auto& taskDeque = saveTaskDequeMap_[tokenId];
118     for (auto iter = taskDeque.begin(); iter != taskDeque.end(); ++iter) {
119         if (!RevokeSavePermissionTask(*iter)) {
120             continue;
121         }
122     }
123     taskDeque.clear();
124     SC_LOG_INFO(LABEL, "tokenId: %{public}d revoke save permission.", tokenId);
125     return;
126 }
127 
VerifySavePermission(AccessToken::AccessTokenID tokenId)128 bool SecCompPermManager::VerifySavePermission(AccessToken::AccessTokenID tokenId)
129 {
130     std::lock_guard<std::mutex> lock(mutex_);
131     auto iter = applySaveCountMap_.find(tokenId);
132     if (iter == applySaveCountMap_.end() || applySaveCountMap_[tokenId] == 0) {
133         SC_LOG_ERROR(LABEL, "This hap has no permissions to save files.");
134         return false;
135     }
136     return true;
137 }
138 
VerifyPermission(AccessToken::AccessTokenID tokenId,SecCompType type)139 bool SecCompPermManager::VerifyPermission(AccessToken::AccessTokenID tokenId, SecCompType type)
140 {
141     int32_t res;
142     switch (type) {
143         case LOCATION_COMPONENT:
144             res = AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, "ohos.permission.LOCATION");
145             if (res != AccessToken::TypePermissionState::PERMISSION_GRANTED) {
146                 return false;
147             }
148             res = AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, "ohos.permission.APPROXIMATELY_LOCATION");
149             return (res == AccessToken::TypePermissionState::PERMISSION_GRANTED);
150         case PASTE_COMPONENT:
151             res = AccessToken::AccessTokenKit::VerifyAccessToken(tokenId,
152                 "ohos.permission.SECURE_PASTE");
153             return (res == AccessToken::TypePermissionState::PERMISSION_GRANTED);
154         case SAVE_COMPONENT:
155             return VerifySavePermission(tokenId);
156         default:
157             SC_LOG_ERROR(LABEL, "Unknown component type.");
158     }
159     return false;
160 }
161 
AddAppGrantPermissionRecord(AccessToken::AccessTokenID tokenId,const std::string & permissionName)162 void SecCompPermManager::AddAppGrantPermissionRecord(AccessToken::AccessTokenID tokenId,
163     const std::string& permissionName)
164 {
165     auto iter = grantMap_.find(tokenId);
166     if (iter != grantMap_.end()) {
167         iter->second.insert(permissionName);
168         return;
169     }
170     std::set<std::string> permSet;
171     permSet.insert(permissionName);
172     grantMap_[tokenId] = permSet;
173 }
174 
RemoveAppGrantPermissionRecord(AccessToken::AccessTokenID tokenId,const std::string & permissionName)175 void SecCompPermManager::RemoveAppGrantPermissionRecord(AccessToken::AccessTokenID tokenId,
176     const std::string& permissionName)
177 {
178     auto iter = grantMap_.find(tokenId);
179     if (iter == grantMap_.end()) {
180         return;
181     }
182 
183     grantMap_[tokenId].erase(permissionName);
184 }
185 
GrantAppPermission(AccessToken::AccessTokenID tokenId,const std::string & permissionName)186 int32_t SecCompPermManager::GrantAppPermission(AccessToken::AccessTokenID tokenId,
187     const std::string& permissionName)
188 {
189     std::lock_guard<std::mutex> lock(grantMtx_);
190     int32_t res = AccessToken::AccessTokenKit::GrantPermission(tokenId, permissionName,
191         AccessToken::PermissionFlag::PERMISSION_COMPONENT_SET);
192     SC_LOG_INFO(LABEL, "grant permission res: %{public}d, permission: %{public}s, tokenId:%{public}d",
193         res, permissionName.c_str(), tokenId);
194 
195     AddAppGrantPermissionRecord(tokenId, permissionName);
196     return res;
197 }
198 
RevokeAppPermission(AccessToken::AccessTokenID tokenId,const std::string & permissionName)199 int32_t SecCompPermManager::RevokeAppPermission(AccessToken::AccessTokenID tokenId,
200     const std::string& permissionName)
201 {
202     std::lock_guard<std::mutex> lock(grantMtx_);
203     int32_t res = AccessToken::AccessTokenKit::RevokePermission(tokenId, permissionName,
204         AccessToken::PermissionFlag::PERMISSION_COMPONENT_SET);
205     SC_LOG_INFO(LABEL, "revoke permission res: %{public}d, permission: %{public}s, tokenId:%{public}d",
206         res, permissionName.c_str(), tokenId);
207 
208     RemoveAppGrantPermissionRecord(tokenId, permissionName);
209     return res;
210 }
211 
RevokeAppPermissions(AccessToken::AccessTokenID tokenId)212 void SecCompPermManager::RevokeAppPermissions(AccessToken::AccessTokenID tokenId)
213 {
214     RevokeAppPermisionsImmediately(tokenId);
215     CancelAppRevokingPermisions(tokenId);
216 }
217 
RevokeAppPermisionsDelayed(AccessToken::AccessTokenID tokenId)218 void SecCompPermManager::RevokeAppPermisionsDelayed(AccessToken::AccessTokenID tokenId)
219 {
220     if (secHandler_ == nullptr) {
221         SC_LOG_ERROR(LABEL, "fail to get EventHandler");
222         return;
223     }
224 
225     std::function<void()> delayed = ([tokenId]() {
226         SC_LOG_DEBUG(LABEL, "delay revoke token id %{public}d permissions", tokenId);
227         SecCompPermManager::GetInstance().RevokeAppPermisionsImmediately(tokenId);
228     });
229 
230     SC_LOG_DEBUG(LABEL, "revoke token id %{public}d permissions after %{public}d ms",
231         tokenId, DELAY_REVOKE_MILLISECONDS);
232     std::string taskName = REVOKE_TASK_PREFIX + std::to_string(tokenId);
233     secHandler_->ProxyPostTask(delayed, taskName, DELAY_REVOKE_MILLISECONDS);
234 }
235 
RevokeAppPermisionsImmediately(AccessToken::AccessTokenID tokenId)236 void SecCompPermManager::RevokeAppPermisionsImmediately(AccessToken::AccessTokenID tokenId)
237 {
238     std::lock_guard<std::mutex> lock(grantMtx_);
239     auto it = grantMap_.find(tokenId);
240     if (it == grantMap_.end()) {
241         return;
242     }
243 
244     auto& grantSet = grantMap_[tokenId];
245     for (auto iter = grantSet.begin(); iter != grantSet.end(); ++iter) {
246         int32_t res = AccessToken::AccessTokenKit::RevokePermission(tokenId, *iter,
247             AccessToken::PermissionFlag::PERMISSION_COMPONENT_SET);
248         SC_LOG_INFO(LABEL, "revoke token id %{public}d permission %{public}s res %{public}d",
249             tokenId, iter->c_str(), res);
250     }
251     grantSet.clear();
252 }
253 
CancelAppRevokingPermisions(AccessToken::AccessTokenID tokenId)254 void SecCompPermManager::CancelAppRevokingPermisions(AccessToken::AccessTokenID tokenId)
255 {
256     if (secHandler_ == nullptr) {
257         SC_LOG_ERROR(LABEL, "fail to get EventHandler");
258         return;
259     }
260 
261     SC_LOG_DEBUG(LABEL, "cancel revoke token id %{public}d permission", tokenId);
262     std::string taskName = REVOKE_TASK_PREFIX + std::to_string(tokenId);
263     secHandler_->ProxyRemoveTask(taskName);
264 }
265 
InitEventHandler(const std::shared_ptr<SecEventHandler> & secHandler)266 void SecCompPermManager::InitEventHandler(const std::shared_ptr<SecEventHandler>& secHandler)
267 {
268     secHandler_ = secHandler;
269 }
270 
271 namespace {
IsDlpSandboxCalling(AccessToken::AccessTokenID tokenId)272 inline bool IsDlpSandboxCalling(AccessToken::AccessTokenID tokenId)
273 {
274     return AccessToken::AccessTokenKit::GetHapDlpFlag(tokenId) != 0;
275 }
276 }
277 
GrantTempPermission(AccessToken::AccessTokenID tokenId,const std::shared_ptr<SecCompBase> & componentInfo)278 int32_t SecCompPermManager::GrantTempPermission(AccessToken::AccessTokenID tokenId,
279     const std::shared_ptr<SecCompBase>& componentInfo)
280 {
281     if ((tokenId <= 0) || (componentInfo == nullptr)) {
282         SC_LOG_ERROR(LABEL, "Grant component is null");
283         return SC_SERVICE_ERROR_PERMISSION_OPER_FAIL;
284     }
285 
286     SecCompType type = componentInfo->type_;
287     int32_t res;
288     switch (type) {
289         case LOCATION_COMPONENT:
290             {
291                 res = GrantAppPermission(tokenId, "ohos.permission.APPROXIMATELY_LOCATION");
292                 if (res != SC_OK) {
293                     return SC_SERVICE_ERROR_PERMISSION_OPER_FAIL;
294                 }
295                 res = GrantAppPermission(tokenId, "ohos.permission.LOCATION");
296                 if (res != SC_OK) {
297                     RevokeAppPermission(tokenId, "ohos.permission.APPROXIMATELY_LOCATION");
298                     return SC_SERVICE_ERROR_PERMISSION_OPER_FAIL;
299                 }
300                 SC_LOG_INFO(LABEL, "Grant location permission, scid = %{public}d.", componentInfo->nodeId_);
301                 return SC_OK;
302             }
303         case PASTE_COMPONENT:
304             res = GrantAppPermission(tokenId, "ohos.permission.SECURE_PASTE");
305             if (res != SC_OK) {
306                 return SC_SERVICE_ERROR_PERMISSION_OPER_FAIL;
307             }
308             SC_LOG_INFO(LABEL, "Grant paste permission, scid = %{public}d.", componentInfo->nodeId_);
309             return SC_OK;
310         case SAVE_COMPONENT:
311             if (IsDlpSandboxCalling(tokenId)) {
312                 SC_LOG_INFO(LABEL, "Dlp sandbox app are not allowed to use save component.");
313                 return SC_SERVICE_ERROR_PERMISSION_OPER_FAIL;
314             }
315             SC_LOG_INFO(LABEL, "Grant save permission, scid = %{public}d.", componentInfo->nodeId_);
316             return GrantTempSavePermission(tokenId);
317         default:
318             SC_LOG_ERROR(LABEL, "Parse component type unknown");
319             break;
320     }
321     return SC_SERVICE_ERROR_PERMISSION_OPER_FAIL;
322 }
323 }  // namespace SecurityComponent
324 }  // namespace Security
325 }  // namespace OHOS
326