1 /*
2 * Copyright (c) 2024 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 #define HUKS_DISABLE_LOG_AT_FILE_TO_REDUCE_ROM_SIZE
16
17 #ifdef HKS_CONFIG_FILE
18 #include HKS_CONFIG_FILE
19 #else
20 #include "hks_config.h"
21 #endif
22
23 #include "hks_permission_check.h"
24
25 #ifdef L2_STANDARD
26 #ifdef HKS_SUPPORT_ACCESS_TOKEN
27 #include <cinttypes>
28 #include <dlfcn.h>
29 #include <sys/time.h>
30 #include <sys/types.h>
31 #include <unistd.h>
32 #include "accesstoken_kit.h"
33 #include "tokenid_kit.h"
34 #include "ipc_skeleton.h"
35 #include "hks_base_check.h"
36 #include "hks_log.h"
37 #include "hks_response.h"
38 #include "hks_template.h"
39 #endif
40 #endif
41
42 #include "hks_param.h"
43 #include <stdint.h>
44
45 #ifdef L2_STANDARD
46 #ifdef HKS_SUPPORT_ACCESS_TOKEN
47 using namespace OHOS;
SensitivePermissionCheck(const char * permission)48 int32_t SensitivePermissionCheck(const char *permission)
49 {
50 OHOS::Security::AccessToken::AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID();
51 int result = OHOS::Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, permission);
52 if (result == OHOS::Security::AccessToken::PERMISSION_GRANTED) {
53 HKS_LOG_D("Check Permission success!");
54 return HKS_SUCCESS;
55 }
56
57 HKS_LOG_E("Check Permission failed!%" LOG_PUBLIC "s, ret = %" LOG_PUBLIC "d", permission, result);
58 return HKS_ERROR_NO_PERMISSION;
59 }
60
61 namespace {
CheckTokenType(void)62 static int32_t CheckTokenType(void)
63 {
64 auto accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
65 auto tokenType = OHOS::Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(
66 static_cast<OHOS::Security::AccessToken::AccessTokenID>(accessTokenIDEx));
67 switch (tokenType) {
68 case OHOS::Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE:
69 case OHOS::Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL:
70 return HKS_SUCCESS;
71 case OHOS::Security::AccessToken::ATokenTypeEnum::TOKEN_HAP:
72 HKS_IF_NOT_TRUE_LOGE_RETURN(
73 OHOS::Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx),
74 HKS_ERROR_NOT_SYSTEM_APP,
75 "not system hap, check permission failed, accessTokenIDEx %" LOG_PUBLIC PRIu64, accessTokenIDEx);
76 return HKS_SUCCESS;
77 default:
78 HKS_LOG_E("unknown tokenid, accessTokenIDEx %" LOG_PUBLIC PRIu64, accessTokenIDEx);
79 return HKS_ERROR_INVALID_ACCESS_TYPE;
80 }
81 }
82 }
83
SystemApiPermissionCheck(int callerUserId)84 int32_t SystemApiPermissionCheck(int callerUserId)
85 {
86 int32_t ret = CheckTokenType();
87 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "CheckTokenType fail %" LOG_PUBLIC "d", ret)
88 HKS_IF_TRUE_LOGE_RETURN(callerUserId < 0 || callerUserId >= HKS_ROOT_USER_UPPERBOUND, HKS_ERROR_NO_PERMISSION,
89 "invalid callerUserId %" LOG_PUBLIC "d", callerUserId)
90 return HKS_SUCCESS;
91 }
92
93 static const int g_trustedUid[] = {
94 1024, 3333, 3515, 3553, 6226, 7008, 7023, 7998
95 };
96
HksCheckAcrossAccountsPermission(const struct HksParamSet * paramSet,int32_t callerUserId)97 int32_t HksCheckAcrossAccountsPermission(const struct HksParamSet *paramSet, int32_t callerUserId)
98 {
99 struct HksParam *specificUserId = NULL;
100 int32_t ret = HksGetParam(paramSet, HKS_TAG_SPECIFIC_USER_ID, &specificUserId);
101 if (ret == HKS_ERROR_PARAM_NOT_EXIST) {
102 return HKS_SUCCESS;
103 } else if (ret != HKS_SUCCESS) {
104 return ret;
105 }
106
107 ret = SystemApiPermissionCheck(callerUserId);
108 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check systemapi permission failed");
109
110 ret = SensitivePermissionCheck("ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS");
111 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check interact across local accounts permission failed")
112
113 auto callingUid = IPCSkeleton::GetCallingUid();
114 for (uint32_t i = 0; i < HKS_ARRAY_SIZE(g_trustedUid); i++) {
115 if (callingUid == g_trustedUid[i]) {
116 return HKS_SUCCESS;
117 }
118 }
119
120 int32_t frontUserId;
121 ret = HksGetFrontUserId(&frontUserId);
122 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get front user id failed");
123
124 if (specificUserId->int32Param != frontUserId) {
125 HKS_LOG_E("specific user id %" LOG_PUBLIC "d not equal front user id %" LOG_PUBLIC "d",
126 specificUserId->int32Param, frontUserId);
127 return HKS_ERROR_ACCESS_OTHER_USER_KEY;
128 }
129 return HKS_SUCCESS;
130 }
131 #endif
132 #else
HksCheckAcrossAccountsPermission(const struct HksParamSet * paramSet,int32_t callerUserId)133 int32_t HksCheckAcrossAccountsPermission(const struct HksParamSet *paramSet, int32_t callerUserId)
134 {
135 (void)paramSet;
136 (void)callerUserId;
137 return HKS_SUCCESS;
138 }
139 #endif // L2_STANDARD
140