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