• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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