1 /*
2 * Copyright (c) 2024-2025 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
16 #include "permission_data_brief.h"
17
18 #include <algorithm>
19 #include <chrono>
20 #include <iostream>
21
22 #include "access_token.h"
23 #include "access_token_error.h"
24 #include "accesstoken_common_log.h"
25 #include "constant_common.h"
26 #include "permission_map.h"
27 #include "perm_setproc.h"
28 #include "permission_validator.h"
29 #include "accesstoken_id_manager.h"
30 #include "data_validator.h"
31 #include "token_field_const.h"
32 #include "data_translator.h"
33
34 namespace OHOS {
35 namespace Security {
36 namespace AccessToken {
37 std::recursive_mutex g_briefInstanceMutex;
38
39 const uint32_t IS_KERNEL_EFFECT = (0x1 << 0);
40 const uint32_t HAS_VALUE = (0x1 << 1);
41
GetInstance()42 PermissionDataBrief& PermissionDataBrief::GetInstance()
43 {
44 static PermissionDataBrief* instance = nullptr;
45 if (instance == nullptr) {
46 std::lock_guard<std::recursive_mutex> lock(g_briefInstanceMutex);
47 if (instance == nullptr) {
48 PermissionDataBrief* tmp = new PermissionDataBrief();
49 instance = std::move(tmp);
50 }
51 }
52 return *instance;
53 }
54
GetPermissionBriefData(AccessTokenID tokenID,const PermissionStatus & permState,const std::map<std::string,std::string> & aclExtendedMap,BriefPermData & briefPermData)55 bool PermissionDataBrief::GetPermissionBriefData(
56 AccessTokenID tokenID, const PermissionStatus &permState,
57 const std::map<std::string, std::string>& aclExtendedMap, BriefPermData& briefPermData)
58 {
59 uint32_t code;
60 if (PermissionValidator::IsGrantStatusValid(permState.grantStatus) &&
61 TransferPermissionToOpcode(permState.permissionName, code)) {
62 PermissionBriefDef briefDef;
63 GetPermissionBriefDef(code, briefDef);
64
65 briefPermData.status = static_cast<int8_t>(permState.grantStatus);
66 briefPermData.permCode = code;
67 briefPermData.flag = permState.grantFlag;
68 if (briefDef.isKernelEffect) {
69 briefPermData.type = IS_KERNEL_EFFECT;
70 } else {
71 briefPermData.type = 0;
72 }
73
74 uint64_t key = (static_cast<uint64_t>(tokenID) << 32) | briefPermData.permCode;
75 if (briefDef.hasValue) {
76 auto iter = aclExtendedMap.find(permState.permissionName);
77 if (iter != aclExtendedMap.end()) {
78 extendedValue_[key] = iter->second;
79 briefPermData.type |= HAS_VALUE;
80 } else {
81 LOGE(ATM_DOMAIN, ATM_TAG, "%{public}s is not in aclExtendedMap.", permState.permissionName.c_str());
82 return false;
83 }
84 }
85
86 if (briefPermData.type != 0) {
87 LOGI(ATM_DOMAIN, ATM_TAG, "%{public}s with type %{public}d",
88 permState.permissionName.c_str(), static_cast<int32_t>(briefPermData.type));
89 }
90 // if permission is about kernel permission without value, do not add it to extendedValue_
91 return true;
92 }
93
94 return false;
95 }
96
GetExetendedValueList(AccessTokenID tokenId,std::vector<PermissionWithValue> & extendedPermList)97 void PermissionDataBrief::GetExetendedValueList(
98 AccessTokenID tokenId, std::vector<PermissionWithValue>& extendedPermList)
99 {
100 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
101 return GetExetendedValueListInner(tokenId, extendedPermList);
102 }
103
GetExetendedValueListInner(AccessTokenID tokenId,std::vector<PermissionWithValue> & extendedPermList)104 void PermissionDataBrief::GetExetendedValueListInner(
105 AccessTokenID tokenId, std::vector<PermissionWithValue>& extendedPermList)
106 {
107 for (const auto& item : extendedValue_) {
108 uint64_t key = item.first;
109 uint32_t permCode = key & 0xFFFFFFFF;
110 std::string permissionName;
111 if (!TransferOpcodeToPermission(permCode, permissionName)) {
112 LOGE(ATM_DOMAIN, ATM_TAG, "TransferOpcodeToPermission failed, permCode: %{public}u", permCode);
113 continue;
114 }
115 uint32_t tmpTokenID = key >> 32;
116 if (tmpTokenID != tokenId) {
117 continue;
118 }
119 PermissionWithValue extendedPerm;
120 extendedPerm.permissionName = permissionName;
121 extendedPerm.value = item.second;
122 extendedPermList.emplace_back(extendedPerm);
123 }
124 }
125
GetKernelPermissions(AccessTokenID tokenId,std::vector<PermissionWithValue> & kernelPermList)126 int32_t PermissionDataBrief::GetKernelPermissions(
127 AccessTokenID tokenId, std::vector<PermissionWithValue>& kernelPermList)
128 {
129 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
130
131 std::vector<BriefPermData> list;
132 int32_t ret = GetBriefPermDataByTokenIdInner(tokenId, list);
133 if (ret != RET_SUCCESS) {
134 LOGE(ATM_DOMAIN, ATM_TAG,
135 "GetBriefPermDataByTokenIdInner failed, tokenId: %{public}d, ret is %{public}d", tokenId, ret);
136 return ret;
137 }
138 for (const auto& data : list) {
139 if ((data.type & IS_KERNEL_EFFECT) != IS_KERNEL_EFFECT) {
140 continue;
141 }
142 std::string permissionName;
143 if (!TransferOpcodeToPermission(data.permCode, permissionName)) {
144 LOGE(ATM_DOMAIN, ATM_TAG, "TransferOpcodeToPermission failed, permCode: %{public}u", data.permCode);
145 continue;
146 }
147 std::string value;
148 if ((data.type & HAS_VALUE) == HAS_VALUE) {
149 uint64_t key = (static_cast<uint64_t>(tokenId) << 32) | data.permCode;
150 auto it = extendedValue_.find(key);
151 if (it == extendedValue_.end()) {
152 LOGE(ATM_DOMAIN, ATM_TAG, "%{public}s not with value.", permissionName.c_str());
153 return ERR_PERMISSION_WITHOUT_VALUE;
154 }
155 value = it->second;
156 } else {
157 value = "true";
158 }
159 PermissionWithValue kernelPerm;
160 kernelPerm.permissionName = permissionName;
161 kernelPerm.value = value;
162 kernelPermList.emplace_back(kernelPerm);
163 }
164 return RET_SUCCESS;
165 }
166
GetReqPermissionByName(AccessTokenID tokenId,const std::string & permissionName,std::string & value,bool tokenIdCheck)167 int32_t PermissionDataBrief::GetReqPermissionByName(
168 AccessTokenID tokenId, const std::string& permissionName,
169 std::string& value, bool tokenIdCheck)
170 {
171 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
172 if (tokenIdCheck) {
173 auto iter = requestedPermData_.find(tokenId);
174 if (iter == requestedPermData_.end()) {
175 LOGE(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is not exist.", tokenId);
176 return ERR_TOKEN_INVALID;
177 }
178 }
179
180 uint32_t permCode;
181 if (!TransferPermissionToOpcode(permissionName, permCode)) {
182 LOGE(ATM_DOMAIN, ATM_TAG,
183 "TransferPermissionToOpcode failed, permissionName: %{public}s.", permissionName.c_str());
184 return ERR_PERMISSION_NOT_EXIST;
185 }
186 uint64_t key = (static_cast<uint64_t>(tokenId) << 32) | permCode;
187 auto it = extendedValue_.find(key);
188 if (it == extendedValue_.end()) {
189 LOGE(ATM_DOMAIN, ATM_TAG, "%{public}s not with value.", permissionName.c_str());
190 return ERR_PERMISSION_WITHOUT_VALUE;
191 }
192
193 value = it->second;
194 return RET_SUCCESS;
195 }
196
GetPermissionStatus(const BriefPermData & briefPermData,PermissionStatus & permState)197 bool PermissionDataBrief::GetPermissionStatus(const BriefPermData& briefPermData, PermissionStatus &permState)
198 {
199 std::string permissionName;
200 if (TransferOpcodeToPermission(briefPermData.permCode, permissionName)) {
201 permState.grantStatus = static_cast<int32_t>(briefPermData.status);
202 permState.permissionName = permissionName;
203 permState.grantFlag = briefPermData.flag;
204 return true;
205 }
206 return false;
207 }
208
GetPermissionBriefDataList(AccessTokenID tokenID,const std::vector<PermissionStatus> & permStateList,const std::map<std::string,std::string> & aclExtendedMap,std::vector<BriefPermData> & list)209 void PermissionDataBrief::GetPermissionBriefDataList(AccessTokenID tokenID,
210 const std::vector<PermissionStatus>& permStateList,
211 const std::map<std::string, std::string>& aclExtendedMap,
212 std::vector<BriefPermData>& list)
213 {
214 // delte permission with value
215 DeleteExtendedValue(tokenID);
216
217 for (const auto& state : permStateList) {
218 BriefPermData data = {0};
219 if (GetPermissionBriefData(tokenID, state, aclExtendedMap, data)) {
220 list.emplace_back(data);
221 }
222 }
223 }
224
AddBriefPermDataByTokenId(AccessTokenID tokenID,const std::vector<BriefPermData> & listInput)225 void PermissionDataBrief::AddBriefPermDataByTokenId(
226 AccessTokenID tokenID, const std::vector<BriefPermData>& listInput)
227 {
228 auto iter = requestedPermData_.find(tokenID);
229 if (iter != requestedPermData_.end()) {
230 requestedPermData_.erase(tokenID);
231 }
232 requestedPermData_[tokenID] = listInput;
233 }
234
AddPermToBriefPermission(AccessTokenID tokenId,const std::vector<PermissionStatus> & permStateList,bool defCheck)235 void PermissionDataBrief::AddPermToBriefPermission(
236 AccessTokenID tokenId, const std::vector<PermissionStatus>& permStateList, bool defCheck)
237 {
238 std::map<std::string, std::string> aclExtendedMap;
239 return AddPermToBriefPermission(tokenId, permStateList, aclExtendedMap, defCheck);
240 }
241
AddPermToBriefPermission(AccessTokenID tokenId,const std::vector<PermissionStatus> & permStateList,const std::map<std::string,std::string> & aclExtendedMap,bool defCheck)242 void PermissionDataBrief::AddPermToBriefPermission(
243 AccessTokenID tokenId, const std::vector<PermissionStatus>& permStateList,
244 const std::map<std::string, std::string>& aclExtendedMap, bool defCheck)
245 {
246 ATokenTypeEnum tokenType = AccessTokenIDManager::GetInstance().GetTokenIdTypeEnum(tokenId);
247 std::vector<PermissionStatus> permStateListRes;
248 if (defCheck) {
249 PermissionValidator::FilterInvalidPermissionState(tokenType, true, permStateList, permStateListRes);
250 } else {
251 permStateListRes.assign(permStateList.begin(), permStateList.end());
252 }
253
254 std::vector<BriefPermData> list;
255 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
256 GetPermissionBriefDataList(tokenId, permStateListRes, aclExtendedMap, list);
257 AddBriefPermDataByTokenId(tokenId, list);
258 }
259
UpdatePermStatus(const BriefPermData & permOld,BriefPermData & permNew)260 void PermissionDataBrief::UpdatePermStatus(const BriefPermData& permOld, BriefPermData& permNew)
261 {
262 // if user_grant permission is not operated by user, it keeps the new initalized state.
263 // the new state can be pre_authorization.
264 if ((permOld.flag == PERMISSION_DEFAULT_FLAG) && (permOld.status == PERMISSION_DENIED)) {
265 return;
266 }
267 // if old user_grant permission is granted by pre_authorization fixed, it keeps the new initalized state.
268 // the new state can be pre_authorization or not.
269 if ((permOld.flag == PERMISSION_SYSTEM_FIXED) ||
270 // if old user_grant permission is granted by pre_authorization unfixed
271 // and the user has not operated this permission, it keeps the new initalized state.
272 (permOld.flag == PERMISSION_GRANTED_BY_POLICY)) {
273 return;
274 }
275
276 permNew.status = permOld.status;
277 permNew.flag = permOld.flag;
278 }
279
Update(AccessTokenID tokenId,const std::vector<PermissionStatus> & permStateList,const std::map<std::string,std::string> & aclExtendedMap)280 void PermissionDataBrief::Update(
281 AccessTokenID tokenId, const std::vector<PermissionStatus>& permStateList,
282 const std::map<std::string, std::string>& aclExtendedMap)
283 {
284 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
285 std::vector<PermissionStatus> permStateFilterList;
286 PermissionValidator::FilterInvalidPermissionState(TOKEN_HAP, true, permStateList, permStateFilterList);
287 LOGI(ATM_DOMAIN, ATM_TAG, "PermStateFilterList size: %{public}zu.", permStateFilterList.size());
288
289 std::vector<BriefPermData> newList;
290 GetPermissionBriefDataList(tokenId, permStateFilterList, aclExtendedMap, newList);
291 std::vector<BriefPermData> briefPermDataList;
292 (void)GetBriefPermDataByTokenIdInner(tokenId, briefPermDataList);
293 for (BriefPermData& newPermData : newList) {
294 auto iter = std::find_if(briefPermDataList.begin(), briefPermDataList.end(),
295 [newPermData](const BriefPermData& oldPermData) {
296 return newPermData.permCode == oldPermData.permCode;
297 });
298 if (iter != briefPermDataList.end()) {
299 UpdatePermStatus(*iter, newPermData);
300 }
301 }
302 AddBriefPermDataByTokenId(tokenId, newList);
303 }
304
GetFlagWroteToDb(uint32_t grantFlag)305 uint32_t PermissionDataBrief::GetFlagWroteToDb(uint32_t grantFlag)
306 {
307 return ConstantCommon::GetFlagWithoutSpecifiedElement(grantFlag, PERMISSION_COMPONENT_SET);
308 }
309
TranslationIntoAclExtendedMap(AccessTokenID tokenId,const std::vector<GenericValues> & extendedPermRes,std::map<std::string,std::string> & aclExtendedMap)310 int32_t PermissionDataBrief::TranslationIntoAclExtendedMap(
311 AccessTokenID tokenId,
312 const std::vector<GenericValues>& extendedPermRes,
313 std::map<std::string, std::string>& aclExtendedMap)
314 {
315 for (const GenericValues& permValue : extendedPermRes) {
316 if ((AccessTokenID)permValue.GetInt(TokenFiledConst::FIELD_TOKEN_ID) != tokenId) {
317 continue;
318 }
319 PermissionWithValue perm;
320 int ret = DataTranslator::TranslationIntoExtendedPermission(permValue, perm);
321 if (ret != RET_SUCCESS) {
322 return ret;
323 }
324 aclExtendedMap[perm.permissionName] = perm.value;
325 }
326 return RET_SUCCESS;
327 }
328
RestorePermissionBriefData(AccessTokenID tokenId,const std::vector<GenericValues> & permStateRes,const std::vector<GenericValues> extendedPermRes)329 void PermissionDataBrief::RestorePermissionBriefData(AccessTokenID tokenId,
330 const std::vector<GenericValues>& permStateRes, const std::vector<GenericValues> extendedPermRes)
331 {
332 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
333 std::vector<BriefPermData> list;
334 std::map<std::string, std::string> aclExtendedMap;
335 int result = TranslationIntoAclExtendedMap(tokenId, extendedPermRes, aclExtendedMap);
336 if (result != RET_SUCCESS) {
337 return;
338 }
339 for (const GenericValues& stateValue : permStateRes) {
340 if ((AccessTokenID)stateValue.GetInt(TokenFiledConst::FIELD_TOKEN_ID) != tokenId) {
341 continue;
342 }
343 PermissionStatus state;
344 int ret = DataTranslator::TranslationIntoPermissionStatus(stateValue, state);
345 if (ret == RET_SUCCESS) {
346 BriefPermData data = {0};
347 if (!GetPermissionBriefData(tokenId, state, aclExtendedMap, data)) {
348 continue;
349 }
350 MergePermBriefData(list, data);
351 } else {
352 LOGE(ATM_DOMAIN, ATM_TAG, "TokenId 0x%{public}x permState is wrong.", tokenId);
353 }
354 }
355 AddBriefPermDataByTokenId(tokenId, list);
356 }
357
MergePermBriefData(std::vector<BriefPermData> & permBriefDataList,BriefPermData & data)358 void PermissionDataBrief::MergePermBriefData(std::vector<BriefPermData>& permBriefDataList,
359 BriefPermData& data)
360 {
361 uint32_t flag = GetFlagWroteToDb(data.flag);
362 data.flag = flag;
363 for (auto iter = permBriefDataList.begin(); iter != permBriefDataList.end(); iter++) {
364 if (data.permCode == iter->permCode) {
365 iter->status = data.status;
366 iter->flag = data.flag;
367 LOGD(ATM_DOMAIN, ATM_TAG, "Update permission: %{public}d.", static_cast<int32_t>(data.permCode));
368 return;
369 }
370 }
371 LOGD(ATM_DOMAIN, ATM_TAG, "Add permission: %{public}d.", static_cast<int32_t>(data.permCode));
372 permBriefDataList.emplace_back(data);
373 }
374
StorePermissionBriefData(AccessTokenID tokenId,std::vector<GenericValues> & permStateValueList)375 int32_t PermissionDataBrief::StorePermissionBriefData(AccessTokenID tokenId,
376 std::vector<GenericValues>& permStateValueList)
377 {
378 std::vector<BriefPermData> permBriefDatalist;
379 {
380 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
381 int32_t ret = GetBriefPermDataByTokenIdInner(tokenId, permBriefDatalist);
382 if (ret != RET_SUCCESS) {
383 return ret;
384 }
385 }
386
387 for (const auto& data : permBriefDatalist) {
388 LOGD(ATM_DOMAIN, ATM_TAG, "PermissionName: %{public}d", static_cast<int32_t>(data.permCode));
389 GenericValues genericValues;
390 PermissionStatus permState;
391 if (!GetPermissionStatus(data, permState)) {
392 return ERR_PERMISSION_NOT_EXIST;
393 }
394 genericValues.Put(TokenFiledConst::FIELD_TOKEN_ID, static_cast<int32_t>(tokenId));
395 DataTranslator::TranslationIntoGenericValues(permState, genericValues);
396 permStateValueList.emplace_back(genericValues);
397 }
398 return RET_SUCCESS;
399 }
400
UpdateWithNewFlag(uint32_t oldFlag,uint32_t currFlag)401 static uint32_t UpdateWithNewFlag(uint32_t oldFlag, uint32_t currFlag)
402 {
403 uint32_t newFlag = currFlag | (oldFlag & PERMISSION_GRANTED_BY_POLICY);
404 return newFlag;
405 }
406
UpdatePermStateList(AccessTokenID tokenId,uint32_t opCode,bool isGranted,uint32_t flag)407 int32_t PermissionDataBrief::UpdatePermStateList(
408 AccessTokenID tokenId, uint32_t opCode, bool isGranted, uint32_t flag)
409 {
410 auto iterPermData = requestedPermData_.find(tokenId);
411 if (iterPermData == requestedPermData_.end()) {
412 LOGE(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is not exist.", tokenId);
413 return ERR_TOKEN_INVALID;
414 }
415 std::vector<BriefPermData>& permBriefDatalist = requestedPermData_[tokenId];
416 auto iter = std::find_if(permBriefDatalist.begin(), permBriefDatalist.end(),
417 [opCode](const BriefPermData& permData) {
418 return opCode == permData.permCode;
419 });
420 if (iter == permBriefDatalist.end()) {
421 LOGE(ATM_DOMAIN, ATM_TAG, "Permission not request!");
422 return AccessTokenError::ERR_PARAM_INVALID;
423 }
424
425 if ((static_cast<uint32_t>(iter->flag) & PERMISSION_SYSTEM_FIXED) == PERMISSION_SYSTEM_FIXED) {
426 LOGE(ATM_DOMAIN, ATM_TAG, "Permission fixed by system!");
427 return AccessTokenError::ERR_PARAM_INVALID;
428 }
429 iter->status = isGranted ? PERMISSION_GRANTED : PERMISSION_DENIED;
430 iter->flag = UpdateWithNewFlag(iter->flag, flag);
431 return RET_SUCCESS;
432 }
433
UpdateSecCompGrantedPermList(AccessTokenID tokenId,const std::string & permissionName,bool isToGrant)434 int32_t PermissionDataBrief::UpdateSecCompGrantedPermList(AccessTokenID tokenId,
435 const std::string& permissionName, bool isToGrant)
436 {
437 uint32_t flag = 0;
438 int32_t ret = QueryPermissionFlag(tokenId, permissionName, flag);
439
440 LOGD(ATM_DOMAIN, ATM_TAG, "Ret is %{public}d. flag is %{public}d", ret, flag);
441 // if the permission has been operated by user or the permission has been granted by system.
442 if ((ConstantCommon::IsPermOperatedByUser(flag) || ConstantCommon::IsPermOperatedBySystem(flag))) {
443 LOGD(ATM_DOMAIN, ATM_TAG, "The permission has been operated.");
444 if (isToGrant) {
445 // The data included in requested perm list.
446 int32_t status = VerifyPermissionStatus(tokenId, permissionName);
447 // Permission has been granted, there is no need to add perm state in security component permList.
448 if (status == PERMISSION_GRANTED) {
449 return RET_SUCCESS;
450 } else {
451 LOGE(ATM_DOMAIN, ATM_TAG, "Permission has been revoked by user.");
452 return ERR_PERMISSION_DENIED;
453 }
454 } else {
455 /* revoke is called while the permission has been operated by user or system */
456 SecCompGrantedPermListUpdated(
457 tokenId, permissionName, false);
458 return RET_SUCCESS;
459 }
460 }
461 // the permission has not been operated by user or the app has not applied for this permission in config.json
462 SecCompGrantedPermListUpdated(tokenId, permissionName, isToGrant);
463 return RET_SUCCESS;
464 }
465
UpdatePermissionStatus(AccessTokenID tokenId,const std::string & permissionName,bool isGranted,uint32_t flag,bool & statusChanged)466 int32_t PermissionDataBrief::UpdatePermissionStatus(AccessTokenID tokenId,
467 const std::string& permissionName, bool isGranted, uint32_t flag, bool& statusChanged)
468 {
469 uint32_t opCode;
470 if (!TransferPermissionToOpcode(permissionName, opCode)) {
471 LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is invalid %{public}s.", permissionName.c_str());
472 return ERR_PARAM_INVALID;
473 }
474 int32_t ret;
475 int32_t oldStatus = VerifyPermissionStatus(tokenId, opCode);
476 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
477 if (!ConstantCommon::IsPermGrantedBySecComp(flag)) {
478 ret = UpdatePermStateList(tokenId, opCode, isGranted, flag);
479 } else {
480 LOGD(ATM_DOMAIN, ATM_TAG, "Permission is set by security component.");
481 ret = UpdateSecCompGrantedPermList(tokenId, permissionName, isGranted);
482 }
483 int32_t newStatus = VerifyPermissionStatus(tokenId, opCode);
484 statusChanged = (oldStatus == newStatus) ? false : true;
485 return ret;
486 }
487
ResetUserGrantPermissionStatus(AccessTokenID tokenID)488 int32_t PermissionDataBrief::ResetUserGrantPermissionStatus(AccessTokenID tokenID)
489 {
490 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
491 auto iter = requestedPermData_.find(tokenID);
492 if (iter == requestedPermData_.end()) {
493 LOGE(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is not exist.", tokenID);
494 return ERR_TOKEN_INVALID;
495 }
496 for (auto& perm : iter->second) {
497 uint32_t oldFlag = static_cast<uint32_t>(perm.flag);
498 if ((oldFlag & PERMISSION_SYSTEM_FIXED) != 0) {
499 continue;
500 }
501 /* A user_grant permission has been set by system for cancellable pre-authorization. */
502 /* it should keep granted when the app reset. */
503 if ((oldFlag & PERMISSION_GRANTED_BY_POLICY) != 0) {
504 perm.status = PERMISSION_GRANTED;
505 perm.flag = PERMISSION_GRANTED_BY_POLICY;
506 continue;
507 }
508 perm.status = PERMISSION_DENIED;
509 perm.flag = PERMISSION_DEFAULT_FLAG;
510 }
511 ClearAllSecCompGrantedPermById(tokenID);
512 return RET_SUCCESS;
513 }
514
DeleteExtendedValue(AccessTokenID tokenID)515 void PermissionDataBrief::DeleteExtendedValue(AccessTokenID tokenID)
516 {
517 auto it = extendedValue_.begin();
518 while (it != extendedValue_.end()) {
519 uint64_t key = it->first;
520 AccessTokenID tokenIDToDelete = key >> 32;
521 if (tokenIDToDelete == tokenID) {
522 it = extendedValue_.erase(it);
523 } else {
524 ++it;
525 }
526 }
527 }
528
DeleteBriefPermDataByTokenId(AccessTokenID tokenID)529 int32_t PermissionDataBrief::DeleteBriefPermDataByTokenId(AccessTokenID tokenID)
530 {
531 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
532 auto iter = requestedPermData_.find(tokenID);
533 if (iter == requestedPermData_.end()) {
534 LOGE(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is not exist.", tokenID);
535 return ERR_TOKEN_INVALID;
536 }
537 requestedPermData_.erase(tokenID);
538 std::list<BriefSecCompData>::iterator secCompData;
539 for (secCompData = secCompList_.begin(); secCompData != secCompList_.end();) {
540 if (secCompData->tokenId != tokenID) {
541 ++secCompData;
542 } else {
543 secCompData = secCompList_.erase(secCompData);
544 }
545 }
546 DeleteExtendedValue(tokenID);
547 LOGI(ATM_DOMAIN, ATM_TAG, "TokenID %{public}u is deleted.", tokenID);
548 return RET_SUCCESS;
549 }
GetBriefPermDataByTokenIdInner(AccessTokenID tokenID,std::vector<BriefPermData> & list)550 int32_t PermissionDataBrief::GetBriefPermDataByTokenIdInner(AccessTokenID tokenID, std::vector<BriefPermData>& list)
551 {
552 auto iter = requestedPermData_.find(tokenID);
553 if (iter == requestedPermData_.end()) {
554 LOGE(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is not exist.", tokenID);
555 return ERR_TOKEN_INVALID;
556 }
557 for (const auto& data : iter->second) {
558 list.emplace_back(data);
559 }
560 return RET_SUCCESS;
561 }
562
GetBriefPermDataByTokenId(AccessTokenID tokenID,std::vector<BriefPermData> & list)563 int32_t PermissionDataBrief::GetBriefPermDataByTokenId(AccessTokenID tokenID, std::vector<BriefPermData>& list)
564 {
565 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
566 return GetBriefPermDataByTokenIdInner(tokenID, list);
567 }
568
GetGrantedPermByTokenId(AccessTokenID tokenID,const std::vector<std::string> & constrainedList,std::vector<std::string> & permissionList)569 void PermissionDataBrief::GetGrantedPermByTokenId(AccessTokenID tokenID,
570 const std::vector<std::string>& constrainedList, std::vector<std::string>& permissionList)
571 {
572 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
573 auto iter = requestedPermData_.find(tokenID);
574 if (iter == requestedPermData_.end()) {
575 LOGE(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is not exist.", tokenID);
576 return;
577 }
578 for (const auto& data : iter->second) {
579 if (data.status == PERMISSION_GRANTED) {
580 std::string permission;
581 (void)TransferOpcodeToPermission(data.permCode, permission);
582 if (constrainedList.empty() ||
583 (std::find(constrainedList.begin(), constrainedList.end(), permission) == constrainedList.end())) {
584 permissionList.emplace_back(permission);
585 LOGD(ATM_DOMAIN, ATM_TAG, "Permission %{public}s is granted.", permission.c_str());
586 }
587 }
588 }
589 std::list<BriefSecCompData>::iterator secCompData;
590 for (secCompData = secCompList_.begin(); secCompData != secCompList_.end(); ++secCompData) {
591 if (secCompData->tokenId == tokenID) {
592 std::string permission;
593 (void)TransferOpcodeToPermission(secCompData->permCode, permission);
594 permissionList.emplace_back(permission);
595 LOGD(ATM_DOMAIN, ATM_TAG, "Permission %{public}s is granted by secComp.", permission.c_str());
596 }
597 }
598 return;
599 }
600
GetPermStatusListByTokenId(AccessTokenID tokenID,const std::vector<uint32_t> constrainedList,std::vector<uint32_t> & opCodeList,std::vector<bool> & statusList)601 void PermissionDataBrief::GetPermStatusListByTokenId(AccessTokenID tokenID,
602 const std::vector<uint32_t> constrainedList, std::vector<uint32_t>& opCodeList, std::vector<bool>& statusList)
603 {
604 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
605 auto iter = requestedPermData_.find(tokenID);
606 if (iter == requestedPermData_.end()) {
607 LOGE(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is not exist.", tokenID);
608 return;
609 }
610 for (const auto& data : iter->second) {
611 /* The permission is not constrained by user policy. */
612 if (constrainedList.empty() ||
613 (std::find(constrainedList.begin(), constrainedList.end(), data.permCode) == constrainedList.end())) {
614 opCodeList.emplace_back(data.permCode);
615 bool status = data.status == PERMISSION_GRANTED ? true : false;
616 statusList.emplace_back(status);
617 } else {
618 /* The permission is constrained by user policy which is in constrainedList. */
619 opCodeList.emplace_back(data.permCode);
620 statusList.emplace_back(false);
621 }
622 }
623
624 AccessTokenIDInner *idInner = reinterpret_cast<AccessTokenIDInner *>(&tokenID);
625 if (static_cast<ATokenTypeEnum>(idInner->type) != TOKEN_HAP) {
626 return;
627 }
628 /* Only an application can be granted by secComp. */
629 std::list<BriefSecCompData>::iterator secCompData;
630 for (secCompData = secCompList_.begin(); secCompData != secCompList_.end(); ++secCompData) {
631 if (secCompData->tokenId == tokenID) {
632 opCodeList.emplace_back(secCompData->permCode);
633 statusList.emplace_back(true);
634 }
635 }
636 return;
637 }
638
GetPermissionUsedType(AccessTokenID tokenID,int32_t opCode)639 PermUsedTypeEnum PermissionDataBrief::GetPermissionUsedType(AccessTokenID tokenID, int32_t opCode)
640 {
641 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
642 auto iter = requestedPermData_.find(tokenID);
643 if (iter == requestedPermData_.end()) {
644 LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is not exist %{public}d.", tokenID);
645 return PermUsedTypeEnum::INVALID_USED_TYPE;
646 }
647 auto it = std::find_if(iter->second.begin(), iter->second.end(), [opCode](BriefPermData data) {
648 return (data.permCode == opCode);
649 });
650 if (it != iter->second.end()) {
651 if (ConstantCommon::IsPermGrantedBySecComp(it->flag)) {
652 return PermUsedTypeEnum::SEC_COMPONENT_TYPE;
653 }
654 if (it->status == PERMISSION_DENIED) {
655 LOGE(ATM_DOMAIN, ATM_TAG, "Permission of %{public}d is requested, but not granted.", tokenID);
656 return PermUsedTypeEnum::INVALID_USED_TYPE;
657 }
658 return PermUsedTypeEnum::NORMAL_TYPE;
659 }
660 std::list<BriefSecCompData>::iterator secCompData;
661 for (secCompData = secCompList_.begin(); secCompData != secCompList_.end(); ++secCompData) {
662 if ((secCompData->tokenId == tokenID) && (secCompData->permCode == opCode)) {
663 return PermUsedTypeEnum::SEC_COMPONENT_TYPE;
664 }
665 }
666 return PermUsedTypeEnum::INVALID_USED_TYPE;
667 }
VerifyPermissionStatus(AccessTokenID tokenID,uint32_t permCode)668 int32_t PermissionDataBrief::VerifyPermissionStatus(AccessTokenID tokenID, uint32_t permCode)
669 {
670 auto iter = requestedPermData_.find(tokenID);
671 if (iter == requestedPermData_.end()) {
672 LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is not exist %{public}d.", tokenID);
673 return PERMISSION_DENIED;
674 }
675 auto it = std::find_if(iter->second.begin(), iter->second.end(), [permCode](BriefPermData data) {
676 return (data.permCode == permCode);
677 });
678 if (it != iter->second.end()) {
679 if (ConstantCommon::IsPermGrantedBySecComp(it->flag)) {
680 LOGD(ATM_DOMAIN, ATM_TAG, "TokenID: %{public}d, permission is granted by secComp", tokenID);
681 return PERMISSION_GRANTED;
682 }
683 return static_cast<int32_t>(it->status);
684 }
685
686 std::list<BriefSecCompData>::iterator secCompData;
687 for (secCompData = secCompList_.begin(); secCompData != secCompList_.end(); ++secCompData) {
688 if ((secCompData->tokenId == tokenID) && (secCompData->permCode == permCode)) {
689 LOGD(ATM_DOMAIN, ATM_TAG,
690 "TokenID: %{public}d, permission is not requested. While it is granted by secComp", tokenID);
691 return PERMISSION_GRANTED;
692 }
693 }
694 return PERMISSION_DENIED;
695 }
696
VerifyPermissionStatus(AccessTokenID tokenID,const std::string & permission)697 int32_t PermissionDataBrief::VerifyPermissionStatus(AccessTokenID tokenID, const std::string& permission)
698 {
699 LOGD(ATM_DOMAIN, ATM_TAG, "tokenID %{public}d, permissionName %{public}s.", tokenID, permission.c_str());
700 uint32_t opCode;
701 if (!TransferPermissionToOpcode(permission, opCode)) {
702 LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is invalid %{public}s.", permission.c_str());
703 return PERMISSION_DENIED;
704 }
705 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
706 return VerifyPermissionStatus(tokenID, opCode);
707 }
708
IsPermissionGrantedWithSecComp(AccessTokenID tokenID,const std::string & permissionName)709 bool PermissionDataBrief::IsPermissionGrantedWithSecComp(AccessTokenID tokenID, const std::string& permissionName)
710 {
711 uint32_t opCode;
712 if (!TransferPermissionToOpcode(permissionName, opCode)) {
713 LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is invalid %{public}s.", permissionName.c_str());
714 return false;
715 }
716
717 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
718 auto iter = requestedPermData_.find(tokenID);
719 if (iter == requestedPermData_.end()) {
720 LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is not exist %{public}d.", tokenID);
721 return false;
722 }
723 auto it = std::find_if(iter->second.begin(), iter->second.end(), [opCode](BriefPermData data) {
724 return (data.permCode == opCode);
725 });
726 if (it != iter->second.end()) {
727 if (ConstantCommon::IsPermGrantedBySecComp(it->flag)) {
728 LOGI(ATM_DOMAIN, ATM_TAG, "TokenID: %{public}d, permission is granted by secComp", tokenID);
729 return true;
730 }
731 }
732 std::list<BriefSecCompData>::iterator secCompData;
733 for (secCompData = secCompList_.begin(); secCompData != secCompList_.end(); ++secCompData) {
734 if (secCompData->tokenId == tokenID && secCompData->permCode == opCode) {
735 return true;
736 }
737 }
738 return false;
739 }
740
QueryPermissionFlag(AccessTokenID tokenID,const std::string & permissionName,uint32_t & flag)741 int32_t PermissionDataBrief::QueryPermissionFlag(AccessTokenID tokenID, const std::string& permissionName,
742 uint32_t& flag)
743 {
744 uint32_t opCode;
745 if (!TransferPermissionToOpcode(permissionName, opCode)) {
746 LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is invalid %{public}s.", permissionName.c_str());
747 return AccessTokenError::ERR_PERMISSION_NOT_EXIST;
748 }
749
750 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
751 auto iter = requestedPermData_.find(tokenID);
752 if (iter == requestedPermData_.end()) {
753 LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid %{public}u.", tokenID);
754 return AccessTokenError::ERR_TOKENID_NOT_EXIST;
755 }
756 auto it = std::find_if(iter->second.begin(), iter->second.end(), [opCode](BriefPermData data) {
757 return (data.permCode == opCode);
758 });
759 if (it != iter->second.end()) {
760 flag = it->flag;
761 return RET_SUCCESS;
762 }
763 LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is not in requestedPerm list %{public}s.", permissionName.c_str());
764 return AccessTokenError::ERR_PERMISSION_NOT_EXIST;
765 }
766
SecCompGrantedPermListUpdated(AccessTokenID tokenID,const std::string & permissionName,bool isAdded)767 void PermissionDataBrief::SecCompGrantedPermListUpdated(
768 AccessTokenID tokenID, const std::string& permissionName, bool isAdded)
769 {
770 uint32_t opCode;
771 if (!TransferPermissionToOpcode(permissionName, opCode)) {
772 LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is invalid %{public}s.", permissionName.c_str());
773 return;
774 }
775
776 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
777 auto iter = requestedPermData_.find(tokenID);
778 if (iter == requestedPermData_.end()) {
779 LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid %{public}u.", tokenID);
780 return;
781 }
782 std::list<BriefSecCompData>::iterator secCompDataIter;
783 for (secCompDataIter = secCompList_.begin(); secCompDataIter != secCompList_.end(); ++secCompDataIter) {
784 if (secCompDataIter->tokenId == tokenID && secCompDataIter->permCode == opCode) {
785 break;
786 }
787 }
788 if (isAdded) {
789 if (secCompDataIter == secCompList_.end()) {
790 BriefSecCompData secCompData = { 0 };
791 secCompData.permCode = opCode;
792 secCompData.tokenId = tokenID;
793 secCompList_.emplace_back(secCompData);
794 }
795 } else {
796 if (secCompDataIter != secCompList_.end()) {
797 secCompList_.erase(secCompDataIter);
798 }
799 }
800
801 auto it = std::find_if(iter->second.begin(), iter->second.end(), [opCode](BriefPermData data) {
802 return (data.permCode == opCode);
803 });
804 if (it != iter->second.end()) {
805 uint32_t oldFlag = it->flag;
806 uint32_t newFlag =
807 isAdded ? (oldFlag | PERMISSION_COMPONENT_SET) : (oldFlag & (~PERMISSION_COMPONENT_SET));
808 it->flag = newFlag;
809 LOGI(ATM_DOMAIN, ATM_TAG, "Update flag newFlag %{public}u, oldFlag %{public}u .", newFlag, oldFlag);
810 }
811 return;
812 }
813
ClearAllSecCompGrantedPerm()814 void PermissionDataBrief::ClearAllSecCompGrantedPerm()
815 {
816 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
817 std::list<BriefSecCompData>::iterator secCompData;
818 for (secCompData = secCompList_.begin(); secCompData != secCompList_.end();) {
819 secCompData = secCompList_.erase(secCompData);
820 }
821 }
822
ClearAllSecCompGrantedPermById(AccessTokenID tokenID)823 void PermissionDataBrief::ClearAllSecCompGrantedPermById(AccessTokenID tokenID)
824 {
825 std::list<BriefSecCompData>::iterator secCompData;
826 for (secCompData = secCompList_.begin(); secCompData != secCompList_.end();) {
827 if (secCompData->tokenId == tokenID) {
828 LOGI(ATM_DOMAIN, ATM_TAG, "TokenID is cleared %{public}u.", tokenID);
829 secCompData = secCompList_.erase(secCompData);
830 } else {
831 ++secCompData;
832 }
833 }
834 }
835
RefreshPermStateToKernel(const std::vector<std::string> & constrainedList,bool hapUserIsActive,AccessTokenID tokenId,std::map<std::string,bool> & refreshedPermList)836 int32_t PermissionDataBrief::RefreshPermStateToKernel(const std::vector<std::string>& constrainedList,
837 bool hapUserIsActive, AccessTokenID tokenId, std::map<std::string, bool>& refreshedPermList)
838 {
839 std::vector<uint32_t> constrainedCodeList;
840 for (const auto& perm : constrainedList) {
841 uint32_t code;
842 if (TransferPermissionToOpcode(perm, code)) {
843 constrainedCodeList.emplace_back(code);
844 } else {
845 LOGW(ATM_DOMAIN, ATM_TAG, "Perm %{public}s is not exist.", perm.c_str());
846 }
847 }
848 if (constrainedCodeList.empty()) {
849 LOGD(ATM_DOMAIN, ATM_TAG, "constrainedCodeList is null.");
850 return RET_SUCCESS;
851 }
852
853 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->permissionStateDataLock_);
854 auto iter = requestedPermData_.find(tokenId);
855 if (iter == requestedPermData_.end()) {
856 LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is not exist in requestedPermData_ %{public}u.", tokenId);
857 return AccessTokenError::ERR_PARAM_INVALID;
858 }
859
860 for (const auto& data : iter->second) {
861 if (std::find(constrainedCodeList.begin(), constrainedCodeList.end(), data.permCode) ==
862 constrainedCodeList.end()) {
863 continue;
864 }
865 bool isGrantedCurr;
866 int32_t ret = GetPermissionFromKernel(tokenId, data.permCode, isGrantedCurr);
867 if (ret != RET_SUCCESS) {
868 LOGE(ATM_DOMAIN, ATM_TAG, "GetPermissionToKernel err=%{public}d", ret);
869 continue;
870 }
871 bool isGrantedToBe = (data.status == PERMISSION_GRANTED) && hapUserIsActive;
872 LOGI(ATM_DOMAIN, ATM_TAG,
873 "id=%{public}u, opCode=%{public}u, isGranted=%{public}d, hapUserIsActive=%{public}d",
874 tokenId, data.permCode, isGrantedToBe, hapUserIsActive);
875 if (isGrantedCurr == isGrantedToBe) {
876 continue;
877 }
878 ret = SetPermissionToKernel(tokenId, data.permCode, isGrantedToBe);
879 if (ret != RET_SUCCESS) {
880 LOGE(ATM_DOMAIN, ATM_TAG, "SetPermissionToKernel err=%{public}d", ret);
881 continue;
882 }
883 std::string permission;
884 (void)TransferOpcodeToPermission(data.permCode, permission);
885 refreshedPermList[permission] = isGrantedToBe;
886 }
887 return RET_SUCCESS;
888 }
889 } // namespace AccessToken
890 } // namespace Security
891 } // namespace OHOS