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
16 #include "ipc_security/rs_ipc_interface_code_access_verifier_base.h"
17
18 namespace OHOS {
19 namespace Rosen {
20
21 const std::unordered_map<PermissionType, std::string> PERMISSION_MAP {
22 { PermissionType::CAPTURE_SCREEN, "ohos.permission.CAPTURE_SCREEN" },
23 { PermissionType::UPDATE_CONFIGURATION, "ohos.permission.UPDATE_CONFIGURATION" },
24 { PermissionType::GET_RUNNING_INFO, "ohos.permission.GET_RUNNING_INFO" },
25 };
26
IsInterfaceCodeAccessible(CodeUnderlyingType code)27 bool RSInterfaceCodeAccessVerifierBase::IsInterfaceCodeAccessible(CodeUnderlyingType code)
28 {
29 #ifdef ENABLE_IPC_SECURITY
30 if (!IsCommonVerificationPassed(code)) {
31 RS_LOGE("RSInterfaceCodeAccessVerifierBase::IsInterfaceCodeAccessible common verification not passed.");
32 return false;
33 }
34 if (!IsExclusiveVerificationPassed(code)) {
35 RS_LOGE("RSInterfaceCodeAccessVerifierBase::IsInterfaceCodeAccessible exclusive verification not passed.");
36 return false;
37 }
38 #endif
39 return true;
40 }
41 #ifdef ENABLE_IPC_SECURITY
GetTokenType()42 Security::AccessToken::ATokenTypeEnum RSInterfaceCodeAccessVerifierBase::GetTokenType()
43 {
44 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
45 return Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
46 }
47
GetTokenID() const48 Security::AccessToken::AccessTokenID RSInterfaceCodeAccessVerifierBase::GetTokenID() const
49 {
50 return IPCSkeleton::GetCallingTokenID();
51 }
52
CheckNativePermission(const Security::AccessToken::AccessTokenID tokenID,const std::string & permission) const53 bool RSInterfaceCodeAccessVerifierBase::CheckNativePermission(
54 const Security::AccessToken::AccessTokenID tokenID, const std::string& permission) const
55 {
56 int result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenID, permission, false);
57 if (result != Security::AccessToken::PERMISSION_GRANTED) {
58 return false;
59 }
60 return true;
61 }
62
CheckHapPermission(const Security::AccessToken::AccessTokenID tokenID,const std::string & permission) const63 bool RSInterfaceCodeAccessVerifierBase::CheckHapPermission(
64 const Security::AccessToken::AccessTokenID tokenID, const std::string& permission) const
65 {
66 int result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenID, permission, false);
67 if (result != Security::AccessToken::PERMISSION_GRANTED) {
68 return false;
69 }
70 return true;
71 }
72
CheckPermission(CodeUnderlyingType code) const73 bool RSInterfaceCodeAccessVerifierBase::CheckPermission(CodeUnderlyingType code) const
74 {
75 std::vector<std::string> permissions = GetPermissions(code);
76 bool hasPermission = true;
77 auto tokenType = GetTokenType();
78 auto tokenID = GetTokenID();
79 for (auto& permission : permissions) {
80 switch (tokenType) {
81 case Security::AccessToken::ATokenTypeEnum::TOKEN_HAP:
82 hasPermission = CheckHapPermission(tokenID, permission);
83 break;
84 case Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE:
85 hasPermission = CheckNativePermission(tokenID, permission);
86 break;
87 case Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL:
88 hasPermission = CheckNativePermission(tokenID, permission);
89 break;
90 default:
91 break;
92 }
93 if (!hasPermission) {
94 RS_LOGD("%{public}d ipc interface code access denied: HAS NO PERMISSION", code);
95 return false;
96 }
97 }
98 return true;
99 }
100
PermissionEnumToString(PermissionType permission) const101 std::string RSInterfaceCodeAccessVerifierBase::PermissionEnumToString(PermissionType permission) const
102 {
103 if (PERMISSION_MAP.count(permission) > 0) {
104 return PERMISSION_MAP.at(permission);
105 } else {
106 return "unknown";
107 }
108 }
109
AddPermission(CodeUnderlyingType interfaceName,const std::string & newPermission)110 bool RSInterfaceCodeAccessVerifierBase::AddPermission(
111 CodeUnderlyingType interfaceName, const std::string& newPermission)
112 {
113 if (interfacePermissions_.count(interfaceName) > 0) {
114 auto& permissions = interfacePermissions_[interfaceName];
115 auto iter = std::find_if(permissions.cbegin(), permissions.cend(),
116 [newPermission](const auto& permission) { return newPermission == permission; });
117 if (iter == permissions.cend()) {
118 permissions.push_back(newPermission);
119 return true;
120 } else {
121 return false;
122 }
123 } else {
124 interfacePermissions_[interfaceName].push_back(newPermission);
125 }
126 return true;
127 }
128
GetPermissions(CodeUnderlyingType interfaceName) const129 std::vector<std::string> RSInterfaceCodeAccessVerifierBase::GetPermissions(CodeUnderlyingType interfaceName) const
130 {
131 if (interfacePermissions_.count(interfaceName) == 0) {
132 return {};
133 } else {
134 return interfacePermissions_.at(interfaceName);
135 }
136 }
137
GetInterfacePermissionSize() const138 int RSInterfaceCodeAccessVerifierBase::GetInterfacePermissionSize() const
139 {
140 uint32_t countSz = 0;
141 for (auto& [permissionKey, permissionVal] : interfacePermissions_) {
142 countSz += permissionVal.size();
143 }
144 return countSz;
145 }
146
IsSystemApp()147 bool RSInterfaceCodeAccessVerifierBase::IsSystemApp()
148 {
149 uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
150 return Security::AccessToken::AccessTokenKit::IsSystemAppByFullTokenID(fullTokenId);
151 }
152
IsSystemCalling(const std::string & callingCode)153 bool RSInterfaceCodeAccessVerifierBase::IsSystemCalling(const std::string& callingCode)
154 {
155 bool isSystemCalling = false;
156 auto tokenType = GetTokenType();
157 if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_HAP) {
158 isSystemCalling = IsSystemApp();
159 } else if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE) {
160 isSystemCalling = true;
161 } else if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) {
162 isSystemCalling = true;
163 }
164 if (!isSystemCalling) {
165 RS_LOGE("%{public}s ipc interface code access denied: not system calling", callingCode.c_str());
166 }
167 return isSystemCalling;
168 }
169
IsStartByHdcd(bool isLocalSysCalling)170 bool RSInterfaceCodeAccessVerifierBase::IsStartByHdcd(bool isLocalSysCalling)
171 {
172 uint32_t tokenId = isLocalSysCalling ?
173 static_cast<uint32_t>(IPCSkeleton::GetSelfTokenID()) :
174 IPCSkeleton::GetCallingTokenID();
175 OHOS::Security::AccessToken::NativeTokenInfo info;
176 if (Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(tokenId, info) != 0) {
177 return false;
178 }
179 if (info.processName.compare("hdcd") == 0) {
180 return true;
181 }
182 return false;
183 }
184
IsAncoCalling(const std::string & callingCode) const185 bool RSInterfaceCodeAccessVerifierBase::IsAncoCalling(const std::string& callingCode) const
186 {
187 static constexpr uint32_t ANCO_UID = 5557;
188 bool isAncoCalling = (OHOS::IPCSkeleton::GetCallingUid() == ANCO_UID);
189 if (!isAncoCalling) {
190 RS_LOGE("%{public}s ipc interface code access denied: not anco calling", callingCode.c_str());
191 }
192 return isAncoCalling;
193 }
194
IsFoundationCalling(const std::string & callingCode) const195 bool RSInterfaceCodeAccessVerifierBase::IsFoundationCalling(const std::string& callingCode) const
196 {
197 static constexpr uint32_t FOUNDATION_UID = 5523;
198 bool isFoundationCalling = (OHOS::IPCSkeleton::GetCallingUid() == FOUNDATION_UID);
199 if (!isFoundationCalling) {
200 RS_LOGE("%{public}s ipc interface code access denied: not foundation calling", callingCode.c_str());
201 }
202 return isFoundationCalling;
203 }
204
GetAccessType(bool & isTokenTypeValid,bool & isNonSystemAppCalling)205 void RSInterfaceCodeAccessVerifierBase::GetAccessType(bool& isTokenTypeValid, bool& isNonSystemAppCalling)
206 {
207 switch (GetTokenType()) {
208 case (Security::AccessToken::ATokenTypeEnum::TOKEN_HAP): {
209 isTokenTypeValid = true;
210 isNonSystemAppCalling = !IsSystemApp();
211 break;
212 }
213 case (Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE): {
214 isTokenTypeValid = true;
215 isNonSystemAppCalling = false;
216 break;
217 }
218 case (Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL): {
219 isTokenTypeValid = true;
220 isNonSystemAppCalling = false;
221 break;
222 }
223 default: { // TOKEN_INVALID and TOKEN_TYPE_BUTT
224 isTokenTypeValid = false;
225 isNonSystemAppCalling = false;
226 break;
227 }
228 }
229 }
230
IsStylusServiceCalling(const std::string & callingCode) const231 bool RSInterfaceCodeAccessVerifierBase::IsStylusServiceCalling(const std::string& callingCode) const
232 {
233 // Stylus service calls only
234 static constexpr uint32_t STYLUS_SERVICE_UID = 7555;
235 static const std::string STYLUS_SERVICE_PROCESS_NAME = "stylus_service";
236 Security::AccessToken::NativeTokenInfo tokenInfo;
237 int32_t ret = Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(GetTokenID(), tokenInfo);
238 if (ret == ERR_OK) {
239 bool isStylusServiceProcessName = (tokenInfo.processName == STYLUS_SERVICE_PROCESS_NAME);
240 bool isNativeCalling = (GetTokenType() == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE);
241 bool isStylusServiceUid = (OHOS::IPCSkeleton::GetCallingUid() == STYLUS_SERVICE_UID);
242 bool isStylusServiceCalling = isNativeCalling && isStylusServiceUid && isStylusServiceProcessName;
243 if (!isStylusServiceCalling) {
244 RS_LOGE("%{public}s ipc interface code access denied: not stylus service calling", callingCode.c_str());
245 }
246 return isStylusServiceCalling;
247 }
248 RS_LOGE("%{public}s ipc interface code access denied: GetNativeTokenInfo error", callingCode.c_str());
249 return false;
250 }
251 #else
IsSystemCalling(const std::string &)252 bool RSInterfaceCodeAccessVerifierBase::IsSystemCalling(const std::string& /* callingCode */)
253 {
254 return true;
255 }
256
IsStartByHdcd(bool isLocalSysCalling)257 bool RSInterfaceCodeAccessVerifierBase::IsStartByHdcd(bool isLocalSysCalling)
258 {
259 return false;
260 }
261
CheckPermission(CodeUnderlyingType code) const262 bool RSInterfaceCodeAccessVerifierBase::CheckPermission(CodeUnderlyingType code) const
263 {
264 return true;
265 }
266
IsAncoCalling(const std::string & callingCode) const267 bool RSInterfaceCodeAccessVerifierBase::IsAncoCalling(const std::string& callingCode) const
268 {
269 return true;
270 }
271
GetAccessType(bool & isTokenTypeValid,bool & isNonSystemAppCalling)272 void RSInterfaceCodeAccessVerifierBase::GetAccessType(bool& isTokenTypeValid, bool& isNonSystemAppCalling)
273 {
274 isTokenTypeValid = true;
275 isNonSystemAppCalling = false;
276 }
277
IsStylusServiceCalling(const std::string & callingCode) const278 bool RSInterfaceCodeAccessVerifierBase::IsStylusServiceCalling(const std::string& callingCode) const
279 {
280 return true;
281 }
282 #endif
283
IsCommonVerificationPassed(CodeUnderlyingType)284 bool RSInterfaceCodeAccessVerifierBase::IsCommonVerificationPassed(CodeUnderlyingType /* code */)
285 {
286 // Since no common verification rule is temporarily required, directly return true.
287 // If any common rule is required in the future, overwrite this function.
288 return true;
289 }
290
IsAccessTimesVerificationPassed(CodeUnderlyingType code,uint32_t times) const291 bool RSInterfaceCodeAccessVerifierBase::IsAccessTimesVerificationPassed(CodeUnderlyingType code, uint32_t times) const
292 {
293 return true;
294 }
295
296 } // namespace Rosen
297 } // namespace OHOS
298