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