• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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