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 "interceptor/start_other_app_interceptor.h"
17
18 #include "ability_record.h"
19 #include "hilog_tag_wrapper.h"
20 #include "parameters.h"
21 #include "permission_verification.h"
22 #include "start_ability_utils.h"
23 #include "tokenid_kit.h"
24
25 namespace OHOS {
26 namespace AAFwk {
27 namespace {
28 const uint32_t API_VERSION_MOD = 100;
29 const uint32_t API_SINCE_VISION = 12;
30 constexpr const char* ABILITY_SUPPORT_START_OTHER_APP = "persist.sys.abilityms.support.start_other_app";
31 constexpr const char* IS_DELEGATOR_CALL = "isDelegatorCall";
32 constexpr const char* OPEN_LINK_SCENE_IDENTIFICATION = "appLinkingOnly";
33 }
34
DoProcess(AbilityInterceptorParam param)35 ErrCode StartOtherAppInterceptor::DoProcess(AbilityInterceptorParam param)
36 {
37 if (StartAbilityUtils::skipStartOther) {
38 StartAbilityUtils::skipStartOther = false;
39 return ERR_OK;
40 }
41 std::string supportStart = OHOS::system::GetParameter(ABILITY_SUPPORT_START_OTHER_APP, "true");
42 if (supportStart == "true") {
43 TAG_LOGD(AAFwkTag::ABILITYMGR, "Abilityms support start other app.");
44 return ERR_OK;
45 }
46
47 if (!param.isWithUI || param.isStartAsCaller) {
48 return ERR_OK;
49 }
50 if (CheckNativeCall() || CheckCallerIsSystemApp() ||
51 (param.abilityInfo != nullptr && CheckTargetIsSystemApp(param.abilityInfo->applicationInfo))) {
52 return ERR_OK;
53 }
54
55 if (!CheckStartOtherApp(param.want)) {
56 return ERR_OK;
57 }
58
59 if (param.abilityInfo != nullptr && CheckAncoShellCall(param.abilityInfo->applicationInfo, param.want)) {
60 return ERR_OK;
61 }
62
63 if (param.want.HasParameter(OPEN_LINK_SCENE_IDENTIFICATION)) {
64 return ERR_OK;
65 }
66
67 AppExecFwk::ApplicationInfo callerApplicationInfo;
68 if (!GetApplicationInfo(param.callerToken, callerApplicationInfo)) {
69 if (IsDelegatorCall(param.want)) {
70 return ERR_OK;
71 }
72 TAG_LOGE(AAFwkTag::ABILITYMGR, "Can not find caller info");
73 return ERR_INVALID_CALLER;
74 }
75
76 if (CheckCallerApiBelow12(callerApplicationInfo)) {
77 return ERR_OK;
78 }
79 TAG_LOGE(AAFwkTag::ABILITYMGR, "Can not start other app when api version is above 11");
80 return ERR_START_OTHER_APP_FAILED;
81 }
82
CheckNativeCall()83 bool StartOtherAppInterceptor::CheckNativeCall()
84 {
85 auto isSaCall = AAFwk::PermissionVerification::GetInstance()->IsSACall();
86 auto isShellCall = AAFwk::PermissionVerification::GetInstance()->IsShellCall();
87 if (isSaCall || isShellCall) {
88 return true;
89 }
90 return false;
91 }
92
CheckCallerIsSystemApp()93 bool StartOtherAppInterceptor::CheckCallerIsSystemApp()
94 {
95 auto callerToken = IPCSkeleton::GetCallingFullTokenID();
96 if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(callerToken)) {
97 return false;
98 }
99 return true;
100 }
101
CheckTargetIsSystemApp(const AppExecFwk::ApplicationInfo & applicationInfo)102 bool StartOtherAppInterceptor::CheckTargetIsSystemApp(const AppExecFwk::ApplicationInfo &applicationInfo)
103 {
104 return applicationInfo.isSystemApp;
105 }
106
GetApplicationInfo(const sptr<IRemoteObject> & callerToken,AppExecFwk::ApplicationInfo & applicationInfo)107 bool StartOtherAppInterceptor::GetApplicationInfo(const sptr<IRemoteObject> &callerToken,
108 AppExecFwk::ApplicationInfo &applicationInfo)
109 {
110 if (callerToken == nullptr) {
111 int32_t callerPid = IPCSkeleton::GetCallingPid();
112 auto appScheduler = DelayedSingleton<AppScheduler>::GetInstance();
113 bool debug;
114 if (appScheduler != nullptr &&
115 appScheduler->GetApplicationInfoByProcessID(callerPid, applicationInfo, debug) == ERR_OK) {
116 return true;
117 }
118 return false;
119 }
120 auto abilityRecord = Token::GetAbilityRecordByToken(callerToken);
121 if (abilityRecord == nullptr) {
122 return false;
123 }
124 applicationInfo = abilityRecord->GetApplicationInfo();
125 return true;
126 }
127
CheckAncoShellCall(const AppExecFwk::ApplicationInfo & applicationInfo,const Want want)128 bool StartOtherAppInterceptor::CheckAncoShellCall(const AppExecFwk::ApplicationInfo &applicationInfo,
129 const Want want)
130 {
131 return (applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE) ||
132 applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE));
133 }
134
CheckStartOtherApp(const Want want)135 bool StartOtherAppInterceptor::CheckStartOtherApp(const Want want)
136 {
137 return want.GetStringParam(Want::PARAM_RESV_CALLER_BUNDLE_NAME) != want.GetElement().GetBundleName();
138 }
139
CheckCallerApiBelow12(const AppExecFwk::ApplicationInfo & applicationInfo)140 bool StartOtherAppInterceptor::CheckCallerApiBelow12(const AppExecFwk::ApplicationInfo &applicationInfo)
141 {
142 return (applicationInfo.apiTargetVersion % API_VERSION_MOD < API_SINCE_VISION);
143 }
144
IsDelegatorCall(const Want want)145 bool StartOtherAppInterceptor::IsDelegatorCall(const Want want)
146 {
147 AppExecFwk::RunningProcessInfo processInfo;
148 DelayedSingleton<AppScheduler>::GetInstance()->
149 GetRunningProcessInfoByPid(IPCSkeleton::GetCallingPid(), processInfo);
150 if (processInfo.isTestProcess && want.GetBoolParam(IS_DELEGATOR_CALL, false)) {
151 return true;
152 }
153 return false;
154 }
155 }
156 }