• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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