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