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