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 "bundle_overlay_install_checker.h"
17
18 #include "bundle_overlay_manager.h"
19 #include "bundle_permission_mgr.h"
20
21 namespace OHOS {
22 namespace AppExecFwk {
23 namespace {
24 const std::string SHARED_TYPE = "shared";
25 } // namespace
26
CheckInternalBundle(const std::unordered_map<std::string,InnerBundleInfo> & newInfos,const InnerBundleInfo & innerBundleInfo) const27 ErrCode BundleOverlayInstallChecker::CheckInternalBundle(
28 const std::unordered_map<std::string, InnerBundleInfo> &newInfos,
29 const InnerBundleInfo &innerBundleInfo) const
30 {
31 APP_LOGD("start to check internal overlay installation");
32 // 1. check hap type
33 ErrCode result = CheckHapType(innerBundleInfo);
34 if (result != ERR_OK) {
35 APP_LOGE("check hap type failed");
36 return result;
37 }
38 // 2. check bundle type
39 if ((result = CheckBundleType(innerBundleInfo)) != ERR_OK) {
40 APP_LOGE("check bundle type failed");
41 return result;
42 }
43 // 3. check module target priority range
44 const std::map<std::string, InnerModuleInfo> &innerModuleInfos = innerBundleInfo.GetInnerModuleInfos();
45 if (innerModuleInfos.empty()) {
46 APP_LOGE("no module in the overlay hap");
47 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
48 }
49 std::string moduleName = innerBundleInfo.GetCurrentModulePackage();
50 if ((result = CheckTargetPriority(innerModuleInfos.at(moduleName).targetPriority)) != ERR_OK) {
51 APP_LOGE("target priority of module is invalid");
52 return result;
53 }
54 // 4. check TargetModule with moduleName
55 std::string targetModuleName = innerModuleInfos.at(moduleName).targetModuleName;
56 if (targetModuleName == moduleName) {
57 APP_LOGE("target moduleName cannot be same with moudleName");
58 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INVALID_MODULE_NAME;
59 }
60 // 5. check target module is non-overlay hap
61 if ((result = CheckTargetModule(innerBundleInfo.GetBundleName(), targetModuleName)) != ERR_OK) {
62 return result;
63 }
64 // 6. check version code, overlay hap has same version code with non-overlay hap
65 if ((result = CheckVersionCode(newInfos, innerBundleInfo)) != ERR_OK) {
66 return result;
67 }
68 APP_LOGD("check internal overlay installation successfully");
69 return ERR_OK;
70 }
71
CheckExternalBundle(const InnerBundleInfo & innerBundleInfo,int32_t userId) const72 ErrCode BundleOverlayInstallChecker::CheckExternalBundle(const InnerBundleInfo &innerBundleInfo, int32_t userId) const
73 {
74 APP_LOGD("start to check external overlay installation");
75 // 1. check bundle type
76 ErrCode result = CheckBundleType(innerBundleInfo);
77 if (result != ERR_OK) {
78 APP_LOGE("check bundle type failed");
79 return result;
80 }
81
82 result = CheckHapType(innerBundleInfo);
83 if (result != ERR_OK) {
84 APP_LOGE("check hap type failed");
85 return result;
86 }
87
88 // 2. check priority
89 // 2.1 check bundle priority range
90 // 2.2 check module priority range
91 int32_t priority = innerBundleInfo.GetTargetPriority();
92 if ((result = CheckTargetPriority(priority)) != ERR_OK) {
93 APP_LOGE("check bundle priority failed due to %{public}d", result);
94 return result;
95 }
96
97 const std::map<std::string, InnerModuleInfo> &innerModuleInfos = innerBundleInfo.GetInnerModuleInfos();
98 if (innerModuleInfos.empty()) {
99 APP_LOGE("no module in the overlay hap");
100 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
101 }
102 std::string moduleName = innerBundleInfo.GetCurrentModulePackage();
103 priority = innerModuleInfos.at(moduleName).targetPriority;
104 if ((result = CheckTargetPriority(priority)) != ERR_OK) {
105 APP_LOGE("target priority of module is invalid");
106 return result;
107 }
108
109 // 3. bundleName cannot be same with targetBundleName
110 if (innerBundleInfo.GetBundleName() == innerBundleInfo.GetTargetBundleName()) {
111 APP_LOGE("bundleName %{public}s is same with targetBundleName %{public}s",
112 innerBundleInfo.GetBundleName().c_str(), innerBundleInfo.GetTargetBundleName().c_str());
113 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_BUNDLE_NAME_SAME_WITH_TARGET_BUNDLE_NAME;
114 }
115
116 // 4. overlay hap should be preInstall application
117 if (!innerBundleInfo.IsPreInstallApp()) {
118 APP_LOGE("no preInstall application for external overlay installation");
119 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_NO_SYSTEM_APPLICATION_FOR_EXTERNAL_OVERLAY;
120 }
121
122 // 5. check target bundle
123 std::string targetModuleName = innerModuleInfos.at(moduleName).targetModuleName;
124 std::string fingerprint = innerBundleInfo.GetCertificateFingerprint();
125 if ((result =
126 CheckTargetBundle(innerBundleInfo.GetTargetBundleName(), targetModuleName, fingerprint, userId)) != ERR_OK) {
127 APP_LOGE("check target bundle failed");
128 return result;
129 }
130 APP_LOGD("check external overlay installation successfully");
131 return ERR_OK;
132 }
133
CheckHapType(const InnerBundleInfo & info) const134 ErrCode BundleOverlayInstallChecker::CheckHapType(const InnerBundleInfo &info) const
135 {
136 std::string currentPackageName = info.GetCurrentModulePackage();
137 APP_LOGD("current package is %{public}s", currentPackageName.c_str());
138 if (info.GetModuleTypeByPackage(currentPackageName) != SHARED_TYPE) {
139 APP_LOGE("overlay hap only support shared entry hap in internal overlay installation");
140 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_ERROR_HAP_TYPE;
141 }
142 return ERR_OK;
143 }
144
CheckBundleType(const InnerBundleInfo & info) const145 ErrCode BundleOverlayInstallChecker::CheckBundleType(const InnerBundleInfo &info) const
146 {
147 if (info.GetEntryInstallationFree()) {
148 APP_LOGE("overlay hap cannot be service type");
149 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_ERROR_BUNDLE_TYPE;
150 }
151 return ERR_OK;
152 }
153
CheckTargetPriority(int32_t priority) const154 ErrCode BundleOverlayInstallChecker::CheckTargetPriority(int32_t priority) const
155 {
156 APP_LOGD("start to check overlay priority");
157 if ((priority < Constants::OVERLAY_MINIMUM_PRIORITY) || (priority > Constants::OVERLAY_MAXIMUM_PRIORITY)) {
158 APP_LOGE("overlay hap has invalid module priority %{public}d", priority);
159 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INVALID_PRIORITY;
160 }
161 return ERR_OK;
162 }
163
CheckVersionCode(const std::unordered_map<std::string,InnerBundleInfo> & newInfos,const InnerBundleInfo & info) const164 ErrCode BundleOverlayInstallChecker::CheckVersionCode(
165 const std::unordered_map<std::string, InnerBundleInfo> &newInfos,
166 const InnerBundleInfo &info) const
167 {
168 APP_LOGD("start to check version code");
169 for (const auto &innerBundleInfo : newInfos) {
170 if (!innerBundleInfo.second.isOverlayModule(innerBundleInfo.second.GetCurrentModulePackage())) {
171 return ERR_OK;
172 }
173 }
174
175 std::string bundleName = info.GetBundleName();
176 InnerBundleInfo oldInfo;
177 ErrCode result = ERR_OK;
178 auto isExisted = BundleOverlayManager::GetInstance()->GetInnerBundleInfo(bundleName, oldInfo);
179 auto isNonOverlayHapExisted = BundleOverlayManager::GetInstance()->IsExistedNonOverlayHap(bundleName);
180 if (isExisted) {
181 if (isNonOverlayHapExisted && (info.GetVersionCode() != oldInfo.GetVersionCode())) {
182 APP_LOGE("overlay hap needs has same version code with current bundle");
183 result = ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INCONSISTENT_VERSION_CODE;
184 }
185 }
186 return result;
187 }
188
CheckTargetBundle(const std::string & targetBundleName,const std::string & targetModuleName,const std::string & fingerprint,int32_t userId) const189 ErrCode BundleOverlayInstallChecker::CheckTargetBundle(const std::string &targetBundleName,
190 const std::string &targetModuleName, const std::string &fingerprint, int32_t userId) const
191 {
192 APP_LOGD("start to check target bundle");
193 if (targetBundleName.empty()) {
194 APP_LOGE("invalid target bundle name");
195 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INVALID_BUNDLE_NAME;
196 }
197 InnerBundleInfo oldInfo;
198 if (!BundleOverlayManager::GetInstance()->GetInnerBundleInfo(targetBundleName, oldInfo)) {
199 APP_LOGW("target bundle is not installed");
200 return ERR_OK;
201 }
202 // 1. check target bundle is not external overlay bundle
203 if (oldInfo.GetOverlayType() == OVERLAY_EXTERNAL_BUNDLE) {
204 APP_LOGE("target bundle is cannot be external overlay bundle");
205 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_IS_OVERLAY_BUNDLE;
206 }
207 // 2. check target bundle is system application
208 if (!oldInfo.IsPreInstallApp()) {
209 APP_LOGE("target bundle is not preInstall application");
210 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_NO_SYSTEM_APPLICATION_FOR_EXTERNAL_OVERLAY;
211 }
212
213 // 3. check fingerprint of current bundle with target bundle
214 if (oldInfo.GetCertificateFingerprint() != fingerprint) {
215 APP_LOGE("target bundle has different fingerprint with current bundle");
216 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_DIFFERENT_SIGNATURE_CERTIFICATE;
217 }
218
219 // 4. check target module is non-overlay hap
220 auto result = CheckTargetModule(targetBundleName, targetModuleName);
221 if (result != ERR_OK) {
222 return result;
223 }
224
225 // 5. check target bundle is not fa module
226 if (!oldInfo.GetIsNewVersion()) {
227 APP_LOGE("target bundle is not stage model");
228 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_IS_NOT_STAGE_MODULE;
229 }
230 // 6. check target bundle is not service
231 if (CheckBundleType(oldInfo) != ERR_OK) {
232 APP_LOGE("target bundle is service");
233 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_IS_SERVICE;
234 }
235 return ERR_OK;
236 }
237
CheckTargetModule(const std::string & bundleName,const std::string & targetModuleName) const238 ErrCode BundleOverlayInstallChecker::CheckTargetModule(const std::string &bundleName,
239 const std::string &targetModuleName) const
240 {
241 InnerBundleInfo oldInfo;
242 if (BundleOverlayManager::GetInstance()->GetInnerBundleInfo(bundleName, oldInfo)) {
243 if (oldInfo.FindModule(targetModuleName) && oldInfo.isOverlayModule(targetModuleName)) {
244 APP_LOGE("check target module failed");
245 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_TARGET_MODULE_IS_OVERLAY_MODULE;
246 }
247 }
248 return ERR_OK;
249 }
250 } // AppExecFwk
251 } // OHOS