• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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_stream_installer_host_impl.h"
17 
18 #include "bundle_mgr_service.h"
19 #include "bundle_permission_mgr.h"
20 #include "ipc_skeleton.h"
21 namespace OHOS {
22 namespace AppExecFwk {
23 namespace {
24 constexpr const char* ILLEGAL_PATH_FIELD = "../";
25 }
26 
BundleStreamInstallerHostImpl(uint32_t installerId,int32_t installedUid)27 BundleStreamInstallerHostImpl::BundleStreamInstallerHostImpl(uint32_t installerId, int32_t installedUid)
28 {
29     APP_LOGD("create bundle stream installer host impl instance");
30     installerId_ = installerId;
31     installedUid_ = installedUid;
32 }
33 
~BundleStreamInstallerHostImpl()34 BundleStreamInstallerHostImpl::~BundleStreamInstallerHostImpl()
35 {
36     APP_LOGD("destory bundle stream installer host impl instance");
37     UnInit();
38 }
39 
Init(const InstallParam & installParam,const sptr<IStatusReceiver> & statusReceiver)40 bool BundleStreamInstallerHostImpl::Init(const InstallParam &installParam, const sptr<IStatusReceiver> &statusReceiver)
41 {
42     installParam_ = installParam;
43     receiver_ = statusReceiver;
44     std::string tempDir = BundleUtil::CreateInstallTempDir(installerId_, DirType::STREAM_INSTALL_DIR);
45     if (tempDir.empty()) {
46         APP_LOGE("tempDir is empty");
47         return false;
48     }
49     tempDir_ = tempDir;
50 
51     installParam_.sharedBundleDirPaths.clear();
52     uint32_t size = static_cast<uint32_t>(installParam.sharedBundleDirPaths.size());
53     for (uint32_t i = 0; i < size; ++i) {
54         tempDir = BundleUtil::CreateSharedBundleTempDir(installerId_, i);
55         if (tempDir.empty()) {
56             APP_LOGE("create temp dir for hsp failed");
57             return false;
58         }
59         installParam_.sharedBundleDirPaths.emplace_back(tempDir);
60     }
61 
62     installParam_.pgoParams.clear();
63 
64     tempSignatureFileDir_ = BundleUtil::CreateInstallTempDir(installerId_, DirType::SIG_FILE_DIR);
65     if (tempSignatureFileDir_.empty()) {
66         APP_LOGE("tempSignatureFileDir_ is empty");
67         return false;
68     }
69 
70     tempPgoFileDir_ = BundleUtil::CreateInstallTempDir(installerId_, DirType::PGO_FILE_DIR);
71     if (tempPgoFileDir_.empty()) {
72         APP_LOGE("tempPgoFileDir_ is empty");
73         return false;
74     }
75     return true;
76 }
77 
UnInit()78 void BundleStreamInstallerHostImpl::UnInit()
79 {
80     APP_LOGD("destory stream installer with installerId %{public}d and temp dir %{public}s", installerId_,
81         tempDir_.c_str());
82     std::lock_guard<std::mutex> lock(fdVecMutex_);
83     BundleUtil::CloseFileDescriptor(streamFdVec_);
84     BundleUtil::DeleteDir(tempDir_);
85     for (const auto &path : installParam_.sharedBundleDirPaths) {
86         BundleUtil::DeleteDir(path);
87     }
88     BundleUtil::DeleteDir(tempSignatureFileDir_);
89     BundleUtil::DeleteDir(tempPgoFileDir_);
90 }
91 
CreateStream(const std::string & fileName)92 int32_t BundleStreamInstallerHostImpl::CreateStream(const std::string &fileName)
93 {
94     if (fileName.empty()) {
95         APP_LOGE("CreateStream param fileName is empty");
96         return Constants::DEFAULT_STREAM_FD;
97     }
98 
99     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(Constants::PERMISSION_INSTALL_BUNDLE) &&
100         !BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_INSTALL_ENTERPRISE_BUNDLE) &&
101         !BundlePermissionMgr::VerifyCallingPermissionForAll(
102             ServiceConstants::PERMISSION_INSTALL_ENTERPRISE_NORMAL_BUNDLE) &&
103         !BundlePermissionMgr::VerifyCallingPermissionForAll(
104             ServiceConstants::PERMISSION_INSTALL_ENTERPRISE_MDM_BUNDLE) &&
105         !BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_INSTALL_SELF_BUNDLE) &&
106         !BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_INSTALL_SANDBOX_BUNDLE) &&
107         !BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_INSTALL_QUICK_FIX_BUNDLE)) {
108         APP_LOGE("CreateStream permission denied");
109         return Constants::DEFAULT_STREAM_FD;
110     }
111 
112     int32_t callingUid = IPCSkeleton::GetCallingUid();
113     if (callingUid != installedUid_) {
114         APP_LOGE("calling uid is inconsistent");
115         return Constants::DEFAULT_STREAM_FD;
116     }
117 
118     if (!BundleUtil::CheckFileType(fileName, ServiceConstants::INSTALL_FILE_SUFFIX) &&
119         !BundleUtil::CheckFileType(fileName, ServiceConstants::HSP_FILE_SUFFIX)) {
120         APP_LOGE("file is not hap or hsp");
121         return Constants::DEFAULT_STREAM_FD;
122     }
123     // to prevent the hap copied to relevant path
124     if (fileName.find(ILLEGAL_PATH_FIELD) != std::string::npos) {
125         APP_LOGE("CreateStream failed due to invalid fileName");
126         return Constants::DEFAULT_STREAM_FD;
127     }
128     std::string filePath = tempDir_ + fileName;
129     int32_t fd = BundleUtil::CreateFileDescriptor(filePath, 0);
130     if (fd < 0) {
131         APP_LOGE("stream installer create file descriptor failed");
132     }
133     if (fd > 0) {
134         std::lock_guard<std::mutex> lock(fdVecMutex_);
135         streamFdVec_.emplace_back(fd);
136         isInstallSharedBundlesOnly_ = false;
137     }
138     return fd;
139 }
140 
CreateSignatureFileStream(const std::string & moduleName,const std::string & fileName)141 int32_t BundleStreamInstallerHostImpl::CreateSignatureFileStream(const std::string &moduleName,
142     const std::string &fileName)
143 {
144     if (moduleName.empty() || fileName.empty()) {
145         APP_LOGE("CreateSignatureFileStream params are invalid");
146         return Constants::DEFAULT_STREAM_FD;
147     }
148 
149     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(Constants::PERMISSION_INSTALL_BUNDLE) &&
150         !BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_INSTALL_ENTERPRISE_BUNDLE) &&
151         !BundlePermissionMgr::VerifyCallingPermissionForAll(
152             ServiceConstants::PERMISSION_INSTALL_ENTERPRISE_NORMAL_BUNDLE) &&
153         !BundlePermissionMgr::VerifyCallingPermissionForAll(
154             ServiceConstants::PERMISSION_INSTALL_ENTERPRISE_MDM_BUNDLE) &&
155         !BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_INSTALL_SELF_BUNDLE) &&
156         !BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_INSTALL_SANDBOX_BUNDLE) &&
157         !BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_INSTALL_QUICK_FIX_BUNDLE)) {
158         APP_LOGE("CreateSignatureFileStream permission denied");
159         return Constants::DEFAULT_STREAM_FD;
160     }
161 
162     int32_t callingUid = IPCSkeleton::GetCallingUid();
163     if (callingUid != installedUid_) {
164         APP_LOGE("calling uid is inconsistent");
165         return Constants::DEFAULT_STREAM_FD;
166     }
167 
168     if (!BundleUtil::CheckFileType(fileName, ServiceConstants::CODE_SIGNATURE_FILE_SUFFIX)) {
169         APP_LOGE("file is not sig");
170         return Constants::DEFAULT_STREAM_FD;
171     }
172 
173     auto iterator = installParam_.verifyCodeParams.find(moduleName);
174     if (iterator == installParam_.verifyCodeParams.end()) {
175         APP_LOGE("module name cannot be found");
176         return Constants::DEFAULT_STREAM_FD;
177     }
178 
179     // to prevent the sig copied to relevant path
180     if (fileName.find(ILLEGAL_PATH_FIELD) != std::string::npos) {
181         APP_LOGE("CreateStream failed due to invalid fileName");
182         return Constants::DEFAULT_STREAM_FD;
183     }
184     std::string filePath = tempSignatureFileDir_ + fileName;
185     int32_t fd = BundleUtil::CreateFileDescriptor(filePath, 0);
186     if (fd < 0) {
187         APP_LOGE("stream installer create file descriptor failed");
188     }
189 
190     if (fd > 0) {
191         std::lock_guard<std::mutex> lock(fdVecMutex_);
192         streamFdVec_.emplace_back(fd);
193         installParam_.verifyCodeParams.at(moduleName) = filePath;
194     }
195     return fd;
196 }
197 
CreateSharedBundleStream(const std::string & hspName,uint32_t index)198 int32_t BundleStreamInstallerHostImpl::CreateSharedBundleStream(const std::string &hspName, uint32_t index)
199 {
200     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(Constants::PERMISSION_INSTALL_BUNDLE) &&
201         !BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_INSTALL_ENTERPRISE_BUNDLE) &&
202         !BundlePermissionMgr::VerifyCallingPermissionForAll(
203             ServiceConstants::PERMISSION_INSTALL_ENTERPRISE_NORMAL_BUNDLE) &&
204         !BundlePermissionMgr::VerifyCallingPermissionForAll(
205             ServiceConstants::PERMISSION_INSTALL_ENTERPRISE_MDM_BUNDLE) &&
206         !BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_INSTALL_SELF_BUNDLE)) {
207         APP_LOGE("CreateSharedBundleStream permission denied");
208         return Constants::DEFAULT_STREAM_FD;
209     }
210 
211     int32_t callingUid = IPCSkeleton::GetCallingUid();
212     if (callingUid != installedUid_) {
213         APP_LOGE("calling uid is inconsistent");
214         return Constants::DEFAULT_STREAM_FD;
215     }
216 
217     if (!BundleUtil::CheckFileType(hspName, ServiceConstants::INSTALL_FILE_SUFFIX) &&
218         !BundleUtil::CheckFileType(hspName, ServiceConstants::HSP_FILE_SUFFIX) &&
219         !BundleUtil::CheckFileType(hspName, ServiceConstants::CODE_SIGNATURE_FILE_SUFFIX)) {
220         APP_LOGE("file is not hap or hsp");
221         return Constants::DEFAULT_STREAM_FD;
222     }
223 
224     // to prevent the hsp copied to relevant path
225     if (hspName.find(ILLEGAL_PATH_FIELD) != std::string::npos) {
226         APP_LOGE("CreateSharedBundleStream failed due to invalid hapName");
227         return Constants::DEFAULT_STREAM_FD;
228     }
229 
230     if (index >= installParam_.sharedBundleDirPaths.size()) {
231         APP_LOGE("invalid shared bundle index");
232         return Constants::DEFAULT_STREAM_FD;
233     }
234 
235     std::string bundlePath = installParam_.sharedBundleDirPaths[index] + hspName;
236     int32_t fd = BundleUtil::CreateFileDescriptor(bundlePath, 0);
237     if (fd < 0) {
238         APP_LOGE("stream installer create file descriptor failed");
239     }
240     if (fd > 0) {
241         std::lock_guard<std::mutex> lock(fdVecMutex_);
242         streamFdVec_.emplace_back(fd);
243     }
244     return fd;
245 }
246 
CreatePgoFileStream(const std::string & moduleName,const std::string & fileName)247 int32_t BundleStreamInstallerHostImpl::CreatePgoFileStream(const std::string &moduleName,
248     const std::string &fileName)
249 {
250     if (moduleName.empty() || fileName.empty()) {
251         APP_LOGE("CreatePgoFileStream params are invalid");
252         return Constants::DEFAULT_STREAM_FD;
253     }
254 
255     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(Constants::PERMISSION_INSTALL_BUNDLE) &&
256         !BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_INSTALL_ENTERPRISE_BUNDLE) &&
257         !BundlePermissionMgr::VerifyCallingPermissionForAll(
258             ServiceConstants::PERMISSION_INSTALL_ENTERPRISE_NORMAL_BUNDLE) &&
259         !BundlePermissionMgr::VerifyCallingPermissionForAll(
260             ServiceConstants::PERMISSION_INSTALL_ENTERPRISE_MDM_BUNDLE) &&
261         !BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_INSTALL_SELF_BUNDLE)) {
262         APP_LOGE("CreatePgoFileStream permission denied");
263         return Constants::DEFAULT_STREAM_FD;
264     }
265 
266     int32_t callingUid = IPCSkeleton::GetCallingUid();
267     if (callingUid != installedUid_) {
268         APP_LOGE("calling uid is inconsistent");
269         return Constants::DEFAULT_STREAM_FD;
270     }
271 
272     if (!BundleUtil::CheckFileType(fileName, ServiceConstants::PGO_FILE_SUFFIX)) {
273         APP_LOGE("file is not pgo");
274         return Constants::DEFAULT_STREAM_FD;
275     }
276 
277     // to prevent the pgo copied to relevant path
278     if (fileName.find(ILLEGAL_PATH_FIELD) != std::string::npos) {
279         APP_LOGE("CreateStream failed due to invalid fileName");
280         return Constants::DEFAULT_STREAM_FD;
281     }
282     std::string filePath = tempPgoFileDir_ + fileName;
283     int32_t fd = BundleUtil::CreateFileDescriptor(filePath, 0);
284     if (fd < 0) {
285         APP_LOGE("stream installer create file descriptor failed");
286     }
287 
288     if (fd > 0) {
289         std::lock_guard<std::mutex> lock(fdVecMutex_);
290         streamFdVec_.emplace_back(fd);
291         installParam_.pgoParams[moduleName] = filePath;
292     }
293     return fd;
294 }
295 
Install()296 bool BundleStreamInstallerHostImpl::Install()
297 {
298     if (receiver_ == nullptr) {
299         APP_LOGE("receiver_ is nullptr");
300         return false;
301     }
302     receiver_->SetStreamInstallId(installerId_);
303     auto installer = DelayedSingleton<BundleMgrService>::GetInstance()->GetBundleInstaller();
304     if (installer == nullptr) {
305         APP_LOGE("get bundle installer failed");
306         receiver_->OnFinished(ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR, "");
307         return false;
308     }
309     std::vector<std::string> pathVec;
310     if (!isInstallSharedBundlesOnly_) {
311         pathVec.emplace_back(tempDir_);
312     }
313     installParam_.withCopyHaps = true;
314 
315     bool res;
316     if (installParam_.isSelfUpdate) {
317         res = installer->UpdateBundleForSelf(pathVec, installParam_, receiver_);
318     } else {
319         res = installer->Install(pathVec, installParam_, receiver_);
320     }
321     if (!res) {
322         APP_LOGE("install bundle failed");
323         return false;
324     }
325     return true;
326 }
327 
GetInstallerId() const328 uint32_t BundleStreamInstallerHostImpl::GetInstallerId() const
329 {
330     return installerId_;
331 }
332 
SetInstallerId(uint32_t installerId)333 void BundleStreamInstallerHostImpl::SetInstallerId(uint32_t installerId)
334 {
335     installerId_ = installerId;
336 }
337 } // AppExecFwk
338 } // OHOS