1 /*
2 * Copyright (c) 2021-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 "installd/installd_host_impl.h"
17
18 #include <cstdio>
19 #include <fstream>
20 #include <map>
21 #include <memory>
22 #include <sstream>
23 #include <string>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27
28 #include "aot/aot_executor.h"
29 #include "app_log_wrapper.h"
30 #include "bundle_constants.h"
31 #if defined(CODE_SIGNATURE_ENABLE)
32 #include "code_sign_utils.h"
33 #endif
34 #include "common_profile.h"
35 #include "directory_ex.h"
36 #ifdef WITH_SELINUX
37 #include "hap_restorecon.h"
38 #ifndef SELINUX_HAP_DEBUGGABLE
39 #define SELINUX_HAP_DEBUGGABLE 2
40 #endif
41 #endif // WITH_SELINUX
42 #include "installd/installd_operator.h"
43 #include "installd/installd_permission_mgr.h"
44 #include "parameters.h"
45
46 namespace OHOS {
47 namespace AppExecFwk {
48 namespace {
49 const std::string ARK_CACHE_PATH = "/data/local/ark-cache/";
50 const std::string ARK_PROFILE_PATH = "/data/local/ark-profile/";
51 const std::vector<std::string> BUNDLE_DATA_DIR = {
52 "/cache",
53 "/files",
54 "/temp",
55 "/preferences",
56 "/haps"
57 };
58 const std::string BUNDLE_BACKUP_HOME_PATH = "/data/service/el2/%/backup/bundles/";
59 const std::string DISTRIBUTED_FILE = "/data/service/el2/%/hmdfs/account/data/";
60 const std::string SHARE_FILE_PATH = "/data/service/el2/%/share/";
61 const std::string DISTRIBUTED_FILE_NON_ACCOUNT = "/data/service/el2/%/hmdfs/non_account/data/";
62 }
63
InstalldHostImpl()64 InstalldHostImpl::InstalldHostImpl()
65 {
66 APP_LOGI("installd service instance is created");
67 }
68
~InstalldHostImpl()69 InstalldHostImpl::~InstalldHostImpl()
70 {
71 APP_LOGI("installd service instance is destroyed");
72 }
73
CreateBundleDir(const std::string & bundleDir)74 ErrCode InstalldHostImpl::CreateBundleDir(const std::string &bundleDir)
75 {
76 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
77 APP_LOGE("installd permission denied, only used for foundation process");
78 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
79 }
80 if (bundleDir.empty()) {
81 APP_LOGE("Calling the function CreateBundleDir with invalid param");
82 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
83 }
84 if (InstalldOperator::IsExistDir(bundleDir)) {
85 APP_LOGW("bundleDir %{public}s is exist", bundleDir.c_str());
86 OHOS::ForceRemoveDirectory(bundleDir);
87 }
88 if (!InstalldOperator::MkRecursiveDir(bundleDir, true)) {
89 APP_LOGE("create bundle dir %{public}s failed", bundleDir.c_str());
90 return ERR_APPEXECFWK_INSTALLD_CREATE_DIR_FAILED;
91 }
92 return ERR_OK;
93 }
94
ExtractModuleFiles(const std::string & srcModulePath,const std::string & targetPath,const std::string & targetSoPath,const std::string & cpuAbi)95 ErrCode InstalldHostImpl::ExtractModuleFiles(const std::string &srcModulePath, const std::string &targetPath,
96 const std::string &targetSoPath, const std::string &cpuAbi)
97 {
98 APP_LOGD("ExtractModuleFiles extract original src %{public}s and target src %{public}s",
99 srcModulePath.c_str(), targetPath.c_str());
100 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
101 APP_LOGE("installd permission denied, only used for foundation process");
102 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
103 }
104 if (srcModulePath.empty() || targetPath.empty()) {
105 APP_LOGE("Calling the function ExtractModuleFiles with invalid param");
106 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
107 }
108 if (!InstalldOperator::MkRecursiveDir(targetPath, true)) {
109 APP_LOGE("create target dir %{private}s failed", targetPath.c_str());
110 return ERR_APPEXECFWK_INSTALLD_CREATE_DIR_FAILED;
111 }
112 if (!InstalldOperator::ExtractFiles(srcModulePath, targetSoPath, cpuAbi)) {
113 APP_LOGE("extract %{private}s to %{private}s failed", srcModulePath.c_str(), targetPath.c_str());
114 InstalldOperator::DeleteDir(targetPath);
115 return ERR_APPEXECFWK_INSTALL_DISK_MEM_INSUFFICIENT;
116 }
117 return ERR_OK;
118 }
119
ExtractFiles(const ExtractParam & extractParam)120 ErrCode InstalldHostImpl::ExtractFiles(const ExtractParam &extractParam)
121 {
122 APP_LOGD("ExtractFiles extractParam %{public}s", extractParam.ToString().c_str());
123 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
124 APP_LOGE("installd permission denied, only used for foundation process");
125 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
126 }
127
128 if (extractParam.srcPath.empty() || extractParam.targetPath.empty()) {
129 APP_LOGE("Calling the function ExtractFiles with invalid param");
130 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
131 }
132
133 if (!InstalldOperator::ExtractFiles(extractParam)) {
134 APP_LOGE("extract failed");
135 return ERR_APPEXECFWK_INSTALL_DISK_MEM_INSUFFICIENT;
136 }
137
138 return ERR_OK;
139 }
140
ExecuteAOT(const AOTArgs & aotArgs)141 ErrCode InstalldHostImpl::ExecuteAOT(const AOTArgs &aotArgs)
142 {
143 APP_LOGD("begin to execute AOT, args : %{public}s", aotArgs.ToString().c_str());
144 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
145 APP_LOGE("installd permission denied, only used for foundation process");
146 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
147 }
148 ErrCode ret = ERR_OK;
149 AOTExecutor::GetInstance().ExecuteAOT(aotArgs, ret);
150 APP_LOGD("execute AOT ret : %{public}d", ret);
151 return ret;
152 }
153
RenameModuleDir(const std::string & oldPath,const std::string & newPath)154 ErrCode InstalldHostImpl::RenameModuleDir(const std::string &oldPath, const std::string &newPath)
155 {
156 APP_LOGD("rename %{private}s to %{private}s", oldPath.c_str(), newPath.c_str());
157 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
158 APP_LOGE("installd permission denied, only used for foundation process");
159 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
160 }
161 if (oldPath.empty() || newPath.empty()) {
162 APP_LOGE("Calling the function RenameModuleDir with invalid param");
163 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
164 }
165 if (!InstalldOperator::RenameDir(oldPath, newPath)) {
166 APP_LOGE("rename module dir %{private}s to %{private}s failed", oldPath.c_str(), newPath.c_str());
167 return ERR_APPEXECFWK_INSTALLD_RNAME_DIR_FAILED;
168 }
169 return ERR_OK;
170 }
171
CreateBackupExtHomeDir(const std::string & bundleName,const int userid,const int uid)172 static void CreateBackupExtHomeDir(const std::string &bundleName, const int userid, const int uid)
173 {
174 // Setup BackupExtensionAbility's home directory in a harmless way
175 std::string bundleBackupDir = BUNDLE_BACKUP_HOME_PATH + bundleName;
176 bundleBackupDir = bundleBackupDir.replace(bundleBackupDir.find("%"), 1, std::to_string(userid));
177 if (!InstalldOperator::MkOwnerDir(bundleBackupDir, S_IRWXU | S_IRWXG | S_ISGID, uid, Constants::BACKU_HOME_GID)) {
178 static std::once_flag logOnce;
179 std::call_once(logOnce, []() {
180 APP_LOGW("CreateBundledatadir MkOwnerDir(backup's home dir) failed");
181 });
182 }
183 }
184
CreateShareDir(const std::string & bundleName,const int userid,const int uid,const int gid)185 static void CreateShareDir(const std::string &bundleName, const int userid, const int uid, const int gid)
186 {
187 std::string bundleShareDir = SHARE_FILE_PATH + bundleName;
188 bundleShareDir = bundleShareDir.replace(bundleShareDir.find("%"), 1, std::to_string(userid));
189 if (!InstalldOperator::MkOwnerDir(bundleShareDir, S_IRWXU | S_IRWXG | S_ISGID, uid, gid)) {
190 static std::once_flag logOnce;
191 std::call_once(logOnce, []() {
192 APP_LOGW("CreateBundledatadir MkOwnerDir(share's home dir) failed");
193 });
194 }
195 }
196
CreateBundleDataDir(const CreateDirParam & createDirParam)197 ErrCode InstalldHostImpl::CreateBundleDataDir(const CreateDirParam &createDirParam)
198 {
199 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
200 APP_LOGE("installd permission denied, only used for foundation process");
201 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
202 }
203 if (createDirParam.bundleName.empty() || createDirParam.userId < 0 ||
204 createDirParam.uid < 0 || createDirParam.gid < 0) {
205 APP_LOGE("Calling the function CreateBundleDataDir with invalid param");
206 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
207 }
208 for (const auto &el : Constants::BUNDLE_EL) {
209 if ((createDirParam.createDirFlag == CreateDirFlag::CREATE_DIR_UNLOCKED) &&
210 (el == Constants::BUNDLE_EL[0])) {
211 continue;
212 }
213
214 std::string bundleDataDir = GetBundleDataDir(el, createDirParam.userId) + Constants::BASE;
215 if (access(bundleDataDir.c_str(), F_OK) != 0) {
216 APP_LOGW("CreateBundleDataDir base directory does not existed.");
217 return ERR_OK;
218 }
219 bundleDataDir += createDirParam.bundleName;
220 if (!InstalldOperator::MkOwnerDir(bundleDataDir, S_IRWXU, createDirParam.uid, createDirParam.gid)) {
221 APP_LOGE("CreateBundledatadir MkOwnerDir failed");
222 return ERR_APPEXECFWK_INSTALLD_CREATE_DIR_FAILED;
223 }
224 if (el == Constants::BUNDLE_EL[1]) {
225 for (const auto &dir : BUNDLE_DATA_DIR) {
226 if (!InstalldOperator::MkOwnerDir(bundleDataDir + dir, S_IRWXU,
227 createDirParam.uid, createDirParam.gid)) {
228 APP_LOGE("CreateBundledatadir MkOwnerDir el2 failed");
229 return ERR_APPEXECFWK_INSTALLD_CREATE_DIR_FAILED;
230 }
231 }
232 }
233 ErrCode ret = SetDirApl(bundleDataDir, createDirParam.bundleName, createDirParam.apl,
234 createDirParam.isPreInstallApp, createDirParam.debug);
235 if (ret != ERR_OK) {
236 APP_LOGE("CreateBundleDataDir SetDirApl failed");
237 return ret;
238 }
239 std::string databaseDir = GetBundleDataDir(el, createDirParam.userId) + Constants::DATABASE
240 + createDirParam.bundleName;
241 if (!InstalldOperator::MkOwnerDir(
242 databaseDir, S_IRWXU | S_IRWXG | S_ISGID, createDirParam.uid, Constants::DATABASE_DIR_GID)) {
243 APP_LOGE("CreateBundle databaseDir MkOwnerDir failed");
244 return ERR_APPEXECFWK_INSTALLD_CREATE_DIR_FAILED;
245 }
246 ret = SetDirApl(databaseDir, createDirParam.bundleName, createDirParam.apl,
247 createDirParam.isPreInstallApp, createDirParam.debug);
248 if (ret != ERR_OK) {
249 APP_LOGE("CreateBundleDataDir SetDirApl failed");
250 return ret;
251 }
252 }
253 std::string distributedfile = DISTRIBUTED_FILE;
254 distributedfile = distributedfile.replace(distributedfile.find("%"), 1, std::to_string(createDirParam.userId));
255 if (!InstalldOperator::MkOwnerDir(distributedfile + createDirParam.bundleName,
256 S_IRWXU | S_IRWXG | S_ISGID, createDirParam.uid, Constants::DFS_GID)) {
257 APP_LOGE("Failed to mk dir for distributedfile");
258 }
259
260 distributedfile = DISTRIBUTED_FILE_NON_ACCOUNT;
261 distributedfile = distributedfile.replace(distributedfile.find("%"), 1, std::to_string(createDirParam.userId));
262 if (!InstalldOperator::MkOwnerDir(distributedfile + createDirParam.bundleName,
263 S_IRWXU | S_IRWXG | S_ISGID, createDirParam.uid, Constants::DFS_GID)) {
264 APP_LOGE("Failed to mk dir for non account distributedfile");
265 }
266
267 CreateBackupExtHomeDir(createDirParam.bundleName, createDirParam.userId, createDirParam.uid);
268 CreateShareDir(createDirParam.bundleName, createDirParam.userId, createDirParam.uid, createDirParam.gid);
269 return ERR_OK;
270 }
271
RemoveBackupExtHomeDir(const std::string & bundleName,const int userid)272 static ErrCode RemoveBackupExtHomeDir(const std::string &bundleName, const int userid)
273 {
274 std::string bundleBackupDir = BUNDLE_BACKUP_HOME_PATH + bundleName;
275 bundleBackupDir = bundleBackupDir.replace(bundleBackupDir.find("%"), 1, std::to_string(userid));
276 if (!InstalldOperator::DeleteDir(bundleBackupDir)) {
277 APP_LOGE("remove dir %{public}s failed, errno is %{public}d", bundleBackupDir.c_str(), errno);
278 return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
279 }
280 return ERR_OK;
281 }
282
RemoveDistributedDir(const std::string & bundleName,const int userid)283 static ErrCode RemoveDistributedDir(const std::string &bundleName, const int userid)
284 {
285 std::string distributedFile = DISTRIBUTED_FILE + bundleName;
286 distributedFile = distributedFile.replace(distributedFile.find("%"), 1, std::to_string(userid));
287 if (!InstalldOperator::DeleteDir(distributedFile)) {
288 APP_LOGE("remove dir %{public}s failed, errno is %{public}d", distributedFile.c_str(), errno);
289 return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
290 }
291 std::string fileNonAccount = DISTRIBUTED_FILE_NON_ACCOUNT + bundleName;
292 fileNonAccount = fileNonAccount.replace(fileNonAccount.find("%"), 1, std::to_string(userid));
293 if (!InstalldOperator::DeleteDir(fileNonAccount)) {
294 APP_LOGE("remove dir %{public}s failed, errno is %{public}d", fileNonAccount.c_str(), errno);
295 return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
296 }
297 return ERR_OK;
298 }
299
RemoveShareDir(const std::string & bundleName,const int userid)300 static ErrCode RemoveShareDir(const std::string &bundleName, const int userid)
301 {
302 std::string shareFileDir = SHARE_FILE_PATH + bundleName;
303 shareFileDir = shareFileDir.replace(shareFileDir.find("%"), 1, std::to_string(userid));
304 if (!InstalldOperator::DeleteDir(shareFileDir)) {
305 APP_LOGE("remove dir %{public}s failed", shareFileDir.c_str());
306 return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
307 }
308 return ERR_OK;
309 }
310
RemoveBundleDataDir(const std::string & bundleName,const int userid)311 ErrCode InstalldHostImpl::RemoveBundleDataDir(const std::string &bundleName, const int userid)
312 {
313 APP_LOGD("InstalldHostImpl::RemoveBundleDataDir bundleName:%{public}s", bundleName.c_str());
314 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
315 APP_LOGE("installd permission denied, only used for foundation process");
316 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
317 }
318 if (bundleName.empty() || userid < 0) {
319 APP_LOGE("Calling the function CreateBundleDataDir with invalid param");
320 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
321 }
322 for (const auto &el : Constants::BUNDLE_EL) {
323 std::string bundleDataDir = GetBundleDataDir(el, userid) + Constants::BASE + bundleName;
324 if (!InstalldOperator::DeleteDir(bundleDataDir)) {
325 APP_LOGE("remove dir %{public}s failed", bundleDataDir.c_str());
326 return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
327 }
328 std::string databaseDir = GetBundleDataDir(el, userid) + Constants::DATABASE + bundleName;
329 if (!InstalldOperator::DeleteDir(databaseDir)) {
330 APP_LOGE("remove dir %{public}s failed", databaseDir.c_str());
331 return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
332 }
333 }
334 if (RemoveShareDir(bundleName, userid) != ERR_OK) {
335 APP_LOGE("failed to remove share dir");
336 return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
337 }
338 if (RemoveBackupExtHomeDir(bundleName, userid) != ERR_OK) {
339 APP_LOGE("failed to remove backup ext home dir");
340 return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
341 }
342 if (RemoveDistributedDir(bundleName, userid) != ERR_OK) {
343 APP_LOGE("failed to remove distributed file dir");
344 return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
345 }
346 return ERR_OK;
347 }
348
RemoveModuleDataDir(const std::string & ModuleDir,const int userid)349 ErrCode InstalldHostImpl::RemoveModuleDataDir(const std::string &ModuleDir, const int userid)
350 {
351 APP_LOGD("InstalldHostImpl::RemoveModuleDataDir ModuleDir:%{public}s", ModuleDir.c_str());
352 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
353 APP_LOGE("installd permission denied, only used for foundation process");
354 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
355 }
356 if (ModuleDir.empty() || userid < 0) {
357 APP_LOGE("Calling the function CreateModuleDataDir with invalid param");
358 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
359 }
360
361 for (const auto &el : Constants::BUNDLE_EL) {
362 std::string moduleDataDir = GetBundleDataDir(el, userid) + Constants::BASE + ModuleDir;
363 if (!InstalldOperator::DeleteDir(moduleDataDir)) {
364 APP_LOGE("remove dir %{public}s failed", moduleDataDir.c_str());
365 }
366 }
367 return ERR_OK;
368 }
369
RemoveDir(const std::string & dir)370 ErrCode InstalldHostImpl::RemoveDir(const std::string &dir)
371 {
372 APP_LOGD("InstalldHostImpl::RemoveDir:%{public}s", dir.c_str());
373 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
374 APP_LOGE("installd permission denied, only used for foundation process");
375 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
376 }
377 if (dir.empty()) {
378 APP_LOGE("Calling the function RemoveDir with invalid param");
379 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
380 }
381 if (!InstalldOperator::DeleteDir(dir)) {
382 APP_LOGE("remove dir %{public}s failed", dir.c_str());
383 return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
384 }
385 return ERR_OK;
386 }
387
CleanBundleDataDir(const std::string & dataDir)388 ErrCode InstalldHostImpl::CleanBundleDataDir(const std::string &dataDir)
389 {
390 APP_LOGD("InstalldHostImpl::CleanBundleDataDir start");
391 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
392 APP_LOGE("installd permission denied, only used for foundation process");
393 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
394 }
395 if (dataDir.empty()) {
396 APP_LOGE("Calling the function CleanBundleDataDir with invalid param");
397 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
398 }
399
400 if (!InstalldOperator::DeleteFiles(dataDir)) {
401 APP_LOGE("CleanBundleDataDir delete files failed");
402 return ERR_APPEXECFWK_INSTALLD_CLEAN_DIR_FAILED;
403 }
404 return ERR_OK;
405 }
406
GetBundleDataDir(const std::string & el,const int userid) const407 std::string InstalldHostImpl::GetBundleDataDir(const std::string &el, const int userid) const
408 {
409 std::string dataDir = Constants::BUNDLE_APP_DATA_BASE_DIR +
410 el +
411 Constants::PATH_SEPARATOR +
412 std::to_string(userid);
413 return dataDir;
414 }
415
GetBundleStats(const std::string & bundleName,const int32_t userId,std::vector<int64_t> & bundleStats)416 ErrCode InstalldHostImpl::GetBundleStats(
417 const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats)
418 {
419 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
420 APP_LOGE("installd permission denied, only used for foundation process");
421 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
422 }
423 if (bundleName.empty()) {
424 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
425 }
426 std::vector<std::string> bundlePath;
427 bundlePath.push_back(Constants::BUNDLE_CODE_DIR + Constants::PATH_SEPARATOR + bundleName); // bundle code
428 bundlePath.push_back(ARK_CACHE_PATH + bundleName); // ark cache file
429 // ark profile
430 bundlePath.push_back(ARK_PROFILE_PATH + std::to_string(userId) + Constants::PATH_SEPARATOR + bundleName);
431 int64_t fileSize = InstalldOperator::GetDiskUsageFromPath(bundlePath);
432 bundlePath.clear();
433 std::vector<std::string> cachePath;
434 int64_t allBundleLocalSize = 0;
435 for (const auto &el : Constants::BUNDLE_EL) {
436 std::string filePath = Constants::BUNDLE_APP_DATA_BASE_DIR + el + Constants::PATH_SEPARATOR +
437 std::to_string(userId) + Constants::BASE + bundleName;
438 allBundleLocalSize += InstalldOperator::GetDiskUsage(filePath);
439 if (el == Constants::BUNDLE_EL[1]) {
440 for (const auto &dataDir : BUNDLE_DATA_DIR) {
441 bundlePath.push_back(filePath + dataDir);
442 }
443 } else {
444 bundlePath.push_back(filePath);
445 }
446 InstalldOperator::TraverseCacheDirectory(filePath, cachePath);
447 }
448 int64_t bundleLocalSize = InstalldOperator::GetDiskUsageFromPath(bundlePath);
449 int64_t systemFolderSize = allBundleLocalSize - bundleLocalSize;
450 // index 0 : bundle data size
451 bundleStats.push_back(fileSize + systemFolderSize);
452 int64_t cacheSize = InstalldOperator::GetDiskUsageFromPath(cachePath);
453 bundleLocalSize -= cacheSize;
454 // index 1 : local bundle data size
455 bundleStats.push_back(bundleLocalSize);
456
457 // index 2 : distributed data size
458 std::string distributedfilePath = DISTRIBUTED_FILE;
459 distributedfilePath = distributedfilePath.replace(distributedfilePath.find("%"), 1, std::to_string(userId)) +
460 bundleName;
461 int64_t distributedFileSize = InstalldOperator::GetDiskUsage(distributedfilePath);
462 bundleStats.push_back(distributedFileSize);
463
464 // index 3 : database size
465 std::vector<std::string> dataBasePath;
466 for (const auto &el : Constants::BUNDLE_EL) {
467 std::string filePath = Constants::BUNDLE_APP_DATA_BASE_DIR + el + Constants::PATH_SEPARATOR +
468 std::to_string(userId) + Constants::DATABASE + bundleName;
469 dataBasePath.push_back(filePath);
470 }
471 int64_t databaseFileSize = InstalldOperator::GetDiskUsageFromPath(dataBasePath);
472 bundleStats.push_back(databaseFileSize);
473
474 // index 4 : cache size
475 bundleStats.push_back(cacheSize);
476 return ERR_OK;
477 }
478
SetDirApl(const std::string & dir,const std::string & bundleName,const std::string & apl,bool isPreInstallApp,bool debug)479 ErrCode InstalldHostImpl::SetDirApl(const std::string &dir, const std::string &bundleName, const std::string &apl,
480 bool isPreInstallApp, bool debug)
481 {
482 #ifdef WITH_SELINUX
483 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
484 APP_LOGE("installd permission denied, only used for foundation process");
485 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
486 }
487 if (dir.empty() || bundleName.empty()) {
488 APP_LOGE("Calling the function SetDirApl with invalid param");
489 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
490 }
491 HapFileInfo hapFileInfo;
492 hapFileInfo.pathNameOrig.push_back(dir);
493 hapFileInfo.apl = apl;
494 hapFileInfo.packageName = bundleName;
495 hapFileInfo.flags = SELINUX_HAP_RESTORECON_RECURSE;
496 hapFileInfo.hapFlags = isPreInstallApp ? SELINUX_HAP_RESTORECON_PREINSTALLED_APP : 0;
497 hapFileInfo.hapFlags |= debug ? SELINUX_HAP_DEBUGGABLE : 0;
498 HapContext hapContext;
499 int ret = hapContext.HapFileRestorecon(hapFileInfo);
500 if (ret != 0) {
501 APP_LOGE("HapFileRestorecon path: %{private}s failed, apl: %{public}s, errcode:%{public}d",
502 dir.c_str(), apl.c_str(), ret);
503 return ERR_APPEXECFWK_INSTALLD_SET_SELINUX_LABEL_FAILED;
504 }
505 return ret;
506 #else
507 return ERR_OK;
508 #endif // WITH_SELINUX
509 }
510
GetBundleCachePath(const std::string & dir,std::vector<std::string> & cachePath)511 ErrCode InstalldHostImpl::GetBundleCachePath(const std::string &dir, std::vector<std::string> &cachePath)
512 {
513 APP_LOGD("InstalldHostImpl::GetBundleCachePath start");
514 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
515 APP_LOGE("installd permission denied, only used for foundation process");
516 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
517 }
518 if (dir.empty()) {
519 APP_LOGE("Calling the function GetBundleCachePath with invalid param");
520 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
521 }
522 InstalldOperator::TraverseCacheDirectory(dir, cachePath);
523 return ERR_OK;
524 }
525
ScanDir(const std::string & dir,ScanMode scanMode,ResultMode resultMode,std::vector<std::string> & paths)526 ErrCode InstalldHostImpl::ScanDir(
527 const std::string &dir, ScanMode scanMode, ResultMode resultMode, std::vector<std::string> &paths)
528 {
529 APP_LOGD("InstalldHostImpl::Scan start %{public}s", dir.c_str());
530 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
531 APP_LOGE("installd permission denied, only used for foundation process");
532 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
533 }
534 if (dir.empty()) {
535 APP_LOGE("Calling the function Scan with invalid param");
536 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
537 }
538
539 InstalldOperator::ScanDir(dir, scanMode, resultMode, paths);
540 return ERR_OK;
541 }
542
MoveFile(const std::string & oldPath,const std::string & newPath)543 ErrCode InstalldHostImpl::MoveFile(const std::string &oldPath, const std::string &newPath)
544 {
545 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
546 APP_LOGE("installd permission denied, only used for foundation process");
547 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
548 }
549 if (!InstalldOperator::RenameFile(oldPath, newPath)) {
550 APP_LOGE("Move file %{public}s to %{public}s failed",
551 oldPath.c_str(), newPath.c_str());
552 return ERR_APPEXECFWK_INSTALLD_MOVE_FILE_FAILED;
553 }
554 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
555 if (!OHOS::ChangeModeFile(newPath, mode)) {
556 APP_LOGE("change mode failed");
557 return ERR_APPEXECFWK_INSTALLD_MOVE_FILE_FAILED;
558 }
559 return ERR_OK;
560 }
561
CopyFile(const std::string & oldPath,const std::string & newPath,const std::string & signatureFilePath)562 ErrCode InstalldHostImpl::CopyFile(const std::string &oldPath, const std::string &newPath,
563 const std::string &signatureFilePath)
564 {
565 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
566 APP_LOGE("installd permission denied, only used for foundation process");
567 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
568 }
569 if (!InstalldOperator::CopyFile(oldPath, newPath)) {
570 APP_LOGE("Copy file %{public}s to %{public}s failed",
571 oldPath.c_str(), newPath.c_str());
572 return ERR_APPEXECFWK_INSTALLD_COPY_FILE_FAILED;
573 }
574 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
575 if (!OHOS::ChangeModeFile(newPath, mode)) {
576 APP_LOGE("change mode failed");
577 return ERR_APPEXECFWK_INSTALLD_COPY_FILE_FAILED;
578 }
579
580 if (signatureFilePath.empty()) {
581 APP_LOGD("signature file path is empty and no need to process code signature");
582 return ERR_OK;
583 }
584
585 #if defined(CODE_SIGNATURE_ENABLE)
586 Security::CodeSign::EntryMap entryMap = {{ Constants::CODE_SIGNATURE_HAP, newPath }};
587 ErrCode ret = Security::CodeSign::CodeSignUtils::EnforceCodeSignForApp(entryMap, signatureFilePath);
588 if (ret != ERR_OK) {
589 APP_LOGE("hap or hsp code signature failed due to %{public}d", ret);
590 return ERR_BUNDLEMANAGER_INSTALL_CODE_SIGNATURE_FAILED;
591 }
592 #endif
593 return ERR_OK;
594 }
595
Mkdir(const std::string & dir,const int32_t mode,const int32_t uid,const int32_t gid)596 ErrCode InstalldHostImpl::Mkdir(
597 const std::string &dir, const int32_t mode, const int32_t uid, const int32_t gid)
598 {
599 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
600 APP_LOGE("installd permission denied, only used for foundation process");
601 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
602 }
603 APP_LOGD("Mkdir start %{public}s", dir.c_str());
604 if (dir.empty()) {
605 APP_LOGE("Calling the function Mkdir with invalid param");
606 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
607 }
608
609 if (!InstalldOperator::MkOwnerDir(dir, mode, uid, gid)) {
610 APP_LOGE("Mkdir %{public}s failed", dir.c_str());
611 return ERR_APPEXECFWK_INSTALLD_MKDIR_FAILED;
612 }
613
614 return ERR_OK;
615 }
616
GetFileStat(const std::string & file,FileStat & fileStat)617 ErrCode InstalldHostImpl::GetFileStat(const std::string &file, FileStat &fileStat)
618 {
619 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
620 APP_LOGE("installd permission denied, only used for foundation process");
621 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
622 }
623
624 APP_LOGD("GetFileStat start %{public}s", file.c_str());
625 struct stat s;
626 if (stat(file.c_str(), &s) != 0) {
627 APP_LOGE("Stat file(%{public}s) failed", file.c_str());
628 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
629 }
630
631 fileStat.uid = static_cast<int32_t>(s.st_uid);
632 fileStat.gid = static_cast<int32_t>(s.st_gid);
633 fileStat.lastModifyTime = static_cast<int64_t>(s.st_mtime);
634 fileStat.isDir = s.st_mode & S_IFDIR;
635 return ERR_OK;
636 }
637
ExtractDiffFiles(const std::string & filePath,const std::string & targetPath,const std::string & cpuAbi)638 ErrCode InstalldHostImpl::ExtractDiffFiles(const std::string &filePath, const std::string &targetPath,
639 const std::string &cpuAbi)
640 {
641 if (filePath.empty() || targetPath.empty()) {
642 APP_LOGE("Calling the function ExtractDiffFiles with invalid param");
643 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
644 }
645 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
646 APP_LOGE("installd permission denied, only used for foundation process");
647 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
648 }
649 if (!InstalldOperator::ExtractDiffFiles(filePath, targetPath, cpuAbi)) {
650 return ERR_BUNDLEMANAGER_QUICK_FIX_EXTRACT_DIFF_FILES_FAILED;
651 }
652 return ERR_OK;
653 }
654
ApplyDiffPatch(const std::string & oldSoPath,const std::string & diffFilePath,const std::string & newSoPath)655 ErrCode InstalldHostImpl::ApplyDiffPatch(const std::string &oldSoPath, const std::string &diffFilePath,
656 const std::string &newSoPath)
657 {
658 if (oldSoPath.empty() || diffFilePath.empty() || newSoPath.empty()) {
659 APP_LOGE("Calling the function ExtractDiffFiles with invalid param");
660 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
661 }
662 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
663 APP_LOGE("installd permission denied, only used for foundation process");
664 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
665 }
666 if (!InstalldOperator::ApplyDiffPatch(oldSoPath, diffFilePath, newSoPath)) {
667 return ERR_BUNDLEMANAGER_QUICK_FIX_APPLY_DIFF_PATCH_FAILED;
668 }
669 return ERR_OK;
670 }
671
IsExistDir(const std::string & dir,bool & isExist)672 ErrCode InstalldHostImpl::IsExistDir(const std::string &dir, bool &isExist)
673 {
674 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
675 APP_LOGE("installd permission denied, only used for foundation process");
676 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
677 }
678 isExist = InstalldOperator::IsExistDir(dir);
679 return ERR_OK;
680 }
681
IsExistFile(const std::string & path,bool & isExist)682 ErrCode InstalldHostImpl::IsExistFile(const std::string &path, bool &isExist)
683 {
684 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
685 APP_LOGE("installd permission denied, only used for foundation process");
686 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
687 }
688 isExist = InstalldOperator::IsExistFile(path);
689 return ERR_OK;
690 }
691
IsDirEmpty(const std::string & dir,bool & isDirEmpty)692 ErrCode InstalldHostImpl::IsDirEmpty(const std::string &dir, bool &isDirEmpty)
693 {
694 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
695 APP_LOGE("installd permission denied, only used for foundation process");
696 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
697 }
698 isDirEmpty = InstalldOperator::IsDirEmpty(dir);
699 return ERR_OK;
700 }
701
ObtainQuickFixFileDir(const std::string & dir,std::vector<std::string> & dirVec)702 ErrCode InstalldHostImpl::ObtainQuickFixFileDir(const std::string &dir, std::vector<std::string> &dirVec)
703 {
704 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
705 APP_LOGE("installd permission denied, only used for foundation process");
706 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
707 }
708 InstalldOperator::ObtainQuickFixFileDir(dir, dirVec);
709 return ERR_OK;
710 }
711
CopyFiles(const std::string & sourceDir,const std::string & destinationDir)712 ErrCode InstalldHostImpl::CopyFiles(const std::string &sourceDir, const std::string &destinationDir)
713 {
714 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
715 APP_LOGE("installd permission denied, only used for foundation process");
716 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
717 }
718
719 InstalldOperator::CopyFiles(sourceDir, destinationDir);
720 return ERR_OK;
721 }
722
GetNativeLibraryFileNames(const std::string & filePath,const std::string & cpuAbi,std::vector<std::string> & fileNames)723 ErrCode InstalldHostImpl::GetNativeLibraryFileNames(const std::string &filePath, const std::string &cpuAbi,
724 std::vector<std::string> &fileNames)
725 {
726 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
727 APP_LOGE("installd permission denied, only used for foundation process");
728 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
729 }
730 if (filePath.empty()) {
731 APP_LOGE("Calling the function ExtractDiffFiles with invalid param");
732 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
733 }
734 InstalldOperator::GetNativeLibraryFileNames(filePath, cpuAbi, fileNames);
735 return ERR_OK;
736 }
737
VerifyCodeSignature(const std::string & modulePath,const std::string & cpuAbi,const std::string & targetSoPath,const std::string & signatureFileDir)738 ErrCode InstalldHostImpl::VerifyCodeSignature(const std::string &modulePath, const std::string &cpuAbi,
739 const std::string &targetSoPath, const std::string &signatureFileDir)
740 {
741 APP_LOGD("start to process the code signature for so files");
742 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
743 APP_LOGE("installd permission denied, only used for foundation process");
744 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
745 }
746
747 if (modulePath.empty()) {
748 APP_LOGE("Calling the function VerifyCodeSignature with invalid param");
749 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
750 }
751 if (!InstalldOperator::VerifyCodeSignature(modulePath, cpuAbi, targetSoPath, signatureFileDir)) {
752 APP_LOGE("verify code signature failed");
753 return ERR_BUNDLEMANAGER_INSTALL_CODE_SIGNATURE_FAILED;
754 }
755 return ERR_OK;
756 }
757
MoveFiles(const std::string & srcDir,const std::string & desDir)758 ErrCode InstalldHostImpl::MoveFiles(const std::string &srcDir, const std::string &desDir)
759 {
760 if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
761 APP_LOGE("installd permission denied, only used for foundation process");
762 return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
763 }
764
765 if (srcDir.empty() || desDir.empty()) {
766 APP_LOGE("Calling the function MoveFiles with invalid param");
767 return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
768 }
769 if (!InstalldOperator::MoveFiles(srcDir, desDir)) {
770 APP_LOGE("move files failed");
771 return ERR_APPEXECFWK_INSTALLD_MOVE_FILE_FAILED;
772 }
773 return ERR_OK;
774 }
775 } // namespace AppExecFwk
776 } // namespace OHOS
777