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
16 #include "utils/ability_permission_util.h"
17
18 #include "ability_connect_manager.h"
19 #include "ability_info.h"
20 #include "ability_util.h"
21 #include "app_utils.h"
22 #include "accesstoken_kit.h"
23 #include "global_constant.h"
24 #include "hitrace_meter.h"
25 #include "insight_intent_execute_param.h"
26 #include "ipc_skeleton.h"
27 #include "multi_instance_utils.h"
28 #include "permission_constants.h"
29 #include "permission_verification.h"
30 #include "start_ability_utils.h"
31 #include "utils/app_mgr_util.h"
32
33 using OHOS::Security::AccessToken::AccessTokenKit;
34
35 namespace OHOS {
36 namespace AAFwk {
37 namespace {
38 constexpr const char* IS_DELEGATOR_CALL = "isDelegatorCall";
39 constexpr const char* SETTINGS = "settings";
40 constexpr int32_t BASE_USER_RANGE = 200000;
41 }
42
GetInstance()43 AbilityPermissionUtil &AbilityPermissionUtil::GetInstance()
44 {
45 static AbilityPermissionUtil instance;
46 return instance;
47 }
48
IsDelegatorCall(const AppExecFwk::RunningProcessInfo &processInfo, const AbilityRequest &abilityRequest) const49 inline bool AbilityPermissionUtil::IsDelegatorCall(const AppExecFwk::RunningProcessInfo &processInfo,
50 const AbilityRequest &abilityRequest) const
51 {
52 /* To make sure the AbilityDelegator is not counterfeited
53 * 1. The caller-process must be test-process
54 * 2. The callerToken must be nullptr
55 */
56 if (processInfo.isTestProcess &&
57 !abilityRequest.callerToken && abilityRequest.want.GetBoolParam(IS_DELEGATOR_CALL, false)) {
58 return true;
59 }
60 return false;
61 }
62
IsDominateScreen(const Want &want, bool isPendingWantCaller)63 bool AbilityPermissionUtil::IsDominateScreen(const Want &want, bool isPendingWantCaller)
64 {
65 if (!isPendingWantCaller &&
66 !PermissionVerification::GetInstance()->IsSACall() && !PermissionVerification::GetInstance()->IsShellCall()) {
67 auto callerPid = IPCSkeleton::GetCallingPid();
68 AppExecFwk::RunningProcessInfo processInfo;
69 DelayedSingleton<AppScheduler>::GetInstance()->GetRunningProcessInfoByPid(callerPid, processInfo);
70 bool isDelegatorCall = processInfo.isTestProcess && want.GetBoolParam(IS_DELEGATOR_CALL, false);
71 if (isDelegatorCall || InsightIntentExecuteParam::IsInsightIntentExecute(want)) {
72 TAG_LOGD(AAFwkTag::ABILITYMGR, "not dominate screen.");
73 return false;
74 }
75 // add temporarily
76 std::string bundleName = want.GetElement().GetBundleName();
77 std::string abilityName = want.GetElement().GetAbilityName();
78 bool withoutSettings = bundleName.find(SETTINGS) == std::string::npos &&
79 abilityName.find(SETTINGS) == std::string::npos;
80 if (withoutSettings && AppUtils::GetInstance().IsAllowStartAbilityWithoutCallerToken(bundleName, abilityName)) {
81 TAG_LOGD(AAFwkTag::ABILITYMGR, "not dominate screen, allow.");
82 return false;
83 } else if (AppUtils::GetInstance().IsAllowStartAbilityWithoutCallerToken(bundleName, abilityName)) {
84 auto bms = AbilityUtil::GetBundleManagerHelper();
85 CHECK_POINTER_RETURN_BOOL(bms);
86 int32_t callerUid = IPCSkeleton::GetCallingUid();
87 std::string callerBundleName;
88 if (IN_PROCESS_CALL(bms->GetNameForUid(callerUid, callerBundleName)) != ERR_OK) {
89 TAG_LOGE(AAFwkTag::ABILITYMGR, "failed to get caller bundle name.");
90 return false;
91 }
92 auto userId = callerUid / BASE_USER_RANGE;
93 AppExecFwk::BundleInfo info;
94 if (!IN_PROCESS_CALL(
95 bms->GetBundleInfo(callerBundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, info, userId))) {
96 TAG_LOGE(AAFwkTag::ABILITYMGR, "failed to get bundle info.");
97 return false;
98 }
99 if (info.applicationInfo.needAppDetail) {
100 TAG_LOGD(AAFwkTag::ABILITYMGR, "not dominate screen, app detail.");
101 return false;
102 }
103 }
104 TAG_LOGE(AAFwkTag::ABILITYMGR, "dominate screen.");
105 return true;
106 }
107 TAG_LOGD(AAFwkTag::ABILITYMGR, "not dominate screen.");
108 return false;
109 }
110
CheckMultiInstanceAndAppClone(Want &want, int32_t userId, int32_t appIndex, sptr<IRemoteObject> callerToken)111 int32_t AbilityPermissionUtil::CheckMultiInstanceAndAppClone(Want &want, int32_t userId, int32_t appIndex,
112 sptr<IRemoteObject> callerToken)
113 {
114 auto instanceKey = want.GetStringParam(Want::APP_INSTANCE_KEY);
115 auto isCreating = want.GetBoolParam(Want::CREATE_APP_INSTANCE_KEY, false);
116 AppExecFwk::ApplicationInfo appInfo;
117 auto isSupportMultiInstance = AppUtils::GetInstance().IsSupportMultiInstance();
118 if (isSupportMultiInstance) {
119 if (!StartAbilityUtils::GetApplicationInfo(want.GetBundle(), userId, appInfo)) {
120 TAG_LOGI(AAFwkTag::ABILITYMGR, "implicit start");
121 return ERR_OK;
122 }
123 if (appInfo.multiAppMode.multiAppModeType == AppExecFwk::MultiAppModeType::UNSPECIFIED) {
124 if (!instanceKey.empty() || isCreating ||
125 (appIndex != 0 && appIndex <= AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX)) {
126 TAG_LOGE(AAFwkTag::ABILITYMGR, "Not support multi-instance or appClone");
127 return ERR_MULTI_APP_NOT_SUPPORTED;
128 }
129 }
130 if (appInfo.multiAppMode.multiAppModeType == AppExecFwk::MultiAppModeType::MULTI_INSTANCE) {
131 if (appIndex != 0) {
132 TAG_LOGE(AAFwkTag::ABILITYMGR, "Not support appClone");
133 return ERR_NOT_SUPPORT_APP_CLONE;
134 }
135 return CheckMultiInstance(want, callerToken, isCreating, instanceKey, appInfo.multiAppMode.maxCount);
136 }
137 }
138 if (!isSupportMultiInstance || appInfo.multiAppMode.multiAppModeType == AppExecFwk::MultiAppModeType::APP_CLONE) {
139 if (!instanceKey.empty() || isCreating) {
140 TAG_LOGE(AAFwkTag::ABILITYMGR, "Not support multi-instance");
141 return ERR_MULTI_INSTANCE_NOT_SUPPORTED;
142 }
143 }
144 return ERR_OK;
145 }
146
CheckMultiInstance(Want &want, sptr<IRemoteObject> callerToken, bool isCreating, const std::string &instanceKey, int32_t maxCount)147 int32_t AbilityPermissionUtil::CheckMultiInstance(Want &want, sptr<IRemoteObject> callerToken,
148 bool isCreating, const std::string &instanceKey, int32_t maxCount)
149 {
150 auto appMgr = AppMgrUtil::GetAppMgr();
151 if (appMgr == nullptr) {
152 TAG_LOGE(AAFwkTag::FREE_INSTALL, "null appMgr");
153 return ERR_INVALID_VALUE;
154 }
155 auto callerRecord = Token::GetAbilityRecordByToken(callerToken);
156 std::vector<std::string> instanceKeyArray;
157 auto result = IN_PROCESS_CALL(appMgr->GetAllRunningInstanceKeysByBundleName(want.GetBundle(), instanceKeyArray));
158 if (result != ERR_OK) {
159 TAG_LOGE(AAFwkTag::FREE_INSTALL, "Failed to get instance key");
160 return ERR_INVALID_VALUE;
161 }
162 // in-app launch
163 if (callerRecord != nullptr && callerRecord->GetAbilityInfo().bundleName == want.GetBundle()) {
164 if (isCreating) {
165 if (!instanceKey.empty()) {
166 TAG_LOGE(AAFwkTag::ABILITYMGR, "Not allow to set instanceKey");
167 return ERR_APP_INSTANCE_KEY_NOT_SUPPORT;
168 }
169 if (static_cast<int32_t>(instanceKeyArray.size()) == maxCount) {
170 TAG_LOGE(AAFwkTag::ABILITYMGR, "reach upper limit");
171 return ERR_UPPER_LIMIT;
172 }
173 return ERR_OK;
174 }
175 return UpdateInstanceKey(want, instanceKey, instanceKeyArray, callerRecord->GetInstanceKey());
176 }
177 // inter-app launch
178 if (isCreating) {
179 TAG_LOGE(AAFwkTag::ABILITYMGR, "not support to create a new instance");
180 return ERR_CREATE_NEW_INSTANCE_NOT_SUPPORT;
181 }
182 std::string defaultInstanceKey = "app_instance_0";
183 return UpdateInstanceKey(want, instanceKey, instanceKeyArray, defaultInstanceKey);
184 }
185
UpdateInstanceKey(Want &want, const std::string &originInstanceKey, const std::vector<std::string> &instanceKeyArray, const std::string &instanceKey)186 int32_t AbilityPermissionUtil::UpdateInstanceKey(Want &want, const std::string &originInstanceKey,
187 const std::vector<std::string> &instanceKeyArray, const std::string &instanceKey)
188 {
189 if (originInstanceKey.empty()) {
190 want.SetParam(Want::APP_INSTANCE_KEY, instanceKey);
191 return ERR_OK;
192 }
193 for (const auto& key : instanceKeyArray) {
194 if (key == originInstanceKey) {
195 return ERR_OK;
196 }
197 }
198 TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid instanceKey");
199 return ERR_INVALID_APP_INSTANCE_KEY;
200 }
201
CheckMultiInstanceKeyForExtension(const AbilityRequest &abilityRequest)202 int32_t AbilityPermissionUtil::CheckMultiInstanceKeyForExtension(const AbilityRequest &abilityRequest)
203 {
204 if (abilityRequest.want.GetBoolParam(Want::CREATE_APP_INSTANCE_KEY, false)) {
205 TAG_LOGE(AAFwkTag::ABILITYMGR, "not support to create a new instance");
206 return ERR_CREATE_NEW_INSTANCE_NOT_SUPPORT;
207 }
208 auto instanceKey = MultiInstanceUtils::GetInstanceKey(abilityRequest.want);
209 if (instanceKey.empty()) {
210 return ERR_OK;
211 }
212 TAG_LOGI(AAFwkTag::ABILITYMGR, "instanceKey:%{public}s", instanceKey.c_str());
213 if (!AppUtils::GetInstance().IsSupportMultiInstance()) {
214 TAG_LOGE(AAFwkTag::ABILITYMGR, "not support multi-instance");
215 return ERR_CAPABILITY_NOT_SUPPORT;
216 }
217 if (!MultiInstanceUtils::IsMultiInstanceApp(abilityRequest.appInfo)) {
218 TAG_LOGE(AAFwkTag::ABILITYMGR, "not multi-instance app");
219 return ERR_MULTI_INSTANCE_NOT_SUPPORTED;
220 }
221 if (MultiInstanceUtils::IsDefaultInstanceKey(instanceKey)) {
222 return ERR_OK;
223 }
224 if (!MultiInstanceUtils::IsSupportedExtensionType(abilityRequest.abilityInfo.extensionAbilityType)) {
225 TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid extension type");
226 return ERR_INVALID_EXTENSION_TYPE;
227 }
228 if (!MultiInstanceUtils::IsInstanceKeyExist(abilityRequest.want.GetBundle(), instanceKey)) {
229 TAG_LOGE(AAFwkTag::ABILITYMGR, "key not found");
230 return ERR_INVALID_APP_INSTANCE_KEY;
231 }
232 return ERR_OK;
233 }
234 } // AAFwk
235 } // OHOS