• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 "byte_buffer.h"
33 #include "code_sign_utils.h"
34 #endif
35 #if defined(CODE_ENCRYPTION_ENABLE)
36 #include "code_crypto_metadata_process.h"
37 #endif
38 #include "common_profile.h"
39 #include "directory_ex.h"
40 #ifdef WITH_SELINUX
41 #include "hap_restorecon.h"
42 #ifndef SELINUX_HAP_DEBUGGABLE
43 #define SELINUX_HAP_DEBUGGABLE 2
44 #endif
45 #endif // WITH_SELINUX
46 #include "installd/installd_operator.h"
47 #include "installd/installd_permission_mgr.h"
48 #include "parameters.h"
49 
50 namespace OHOS {
51 namespace AppExecFwk {
52 namespace {
53 const std::string ARK_CACHE_PATH = "/data/local/ark-cache/";
54 const std::string ARK_PROFILE_PATH = "/data/local/ark-profile/";
55 const std::vector<std::string> BUNDLE_DATA_DIR = {
56     "/cache",
57     "/files",
58     "/temp",
59     "/preferences",
60     "/haps"
61 };
62 const std::string CLOUD_FILE_PATH = "/data/service/el2/%/hmdfs/cloud/data/";
63 const std::string BUNDLE_BACKUP_HOME_PATH_EL2 = "/data/service/el2/%/backup/bundles/";
64 const std::string DISTRIBUTED_FILE = "/data/service/el2/%/hmdfs/account/data/";
65 const std::string SHARE_FILE_PATH = "/data/service/el2/%/share/";
66 const std::string BUNDLE_BACKUP_HOME_PATH_EL1 = "/data/service/el1/%/backup/bundles/";
67 const std::string DISTRIBUTED_FILE_NON_ACCOUNT = "/data/service/el2/%/hmdfs/non_account/data/";
68 enum class DirType {
69     DIR_EL1,
70     DIR_EL2,
71 };
72 #if defined(CODE_SIGNATURE_ENABLE)
73 using namespace OHOS::Security::CodeSign;
74 #endif
75 }
76 
InstalldHostImpl()77 InstalldHostImpl::InstalldHostImpl()
78 {
79     APP_LOGI("installd service instance is created");
80 }
81 
~InstalldHostImpl()82 InstalldHostImpl::~InstalldHostImpl()
83 {
84     APP_LOGI("installd service instance is destroyed");
85 }
86 
CreateBundleDir(const std::string & bundleDir)87 ErrCode InstalldHostImpl::CreateBundleDir(const std::string &bundleDir)
88 {
89     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
90         APP_LOGE("installd permission denied, only used for foundation process");
91         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
92     }
93     if (bundleDir.empty()) {
94         APP_LOGE("Calling the function CreateBundleDir with invalid param");
95         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
96     }
97     if (InstalldOperator::IsExistDir(bundleDir)) {
98         APP_LOGW("bundleDir %{public}s is exist", bundleDir.c_str());
99         OHOS::ForceRemoveDirectory(bundleDir);
100     }
101     if (!InstalldOperator::MkRecursiveDir(bundleDir, true)) {
102         APP_LOGE("create bundle dir %{public}s failed", bundleDir.c_str());
103         return ERR_APPEXECFWK_INSTALLD_CREATE_DIR_FAILED;
104     }
105     return ERR_OK;
106 }
107 
ExtractModuleFiles(const std::string & srcModulePath,const std::string & targetPath,const std::string & targetSoPath,const std::string & cpuAbi)108 ErrCode InstalldHostImpl::ExtractModuleFiles(const std::string &srcModulePath, const std::string &targetPath,
109     const std::string &targetSoPath, const std::string &cpuAbi)
110 {
111     APP_LOGD("ExtractModuleFiles extract original src %{public}s and target src %{public}s",
112         srcModulePath.c_str(), targetPath.c_str());
113     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
114         APP_LOGE("installd permission denied, only used for foundation process");
115         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
116     }
117     if (srcModulePath.empty() || targetPath.empty()) {
118         APP_LOGE("Calling the function ExtractModuleFiles with invalid param");
119         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
120     }
121     if (!InstalldOperator::MkRecursiveDir(targetPath, true)) {
122         APP_LOGE("create target dir %{public}s failed", targetPath.c_str());
123         return ERR_APPEXECFWK_INSTALLD_CREATE_DIR_FAILED;
124     }
125     if (!InstalldOperator::ExtractFiles(srcModulePath, targetSoPath, cpuAbi)) {
126         APP_LOGE("extract %{public}s to %{public}s failed", srcModulePath.c_str(), targetPath.c_str());
127         InstalldOperator::DeleteDir(targetPath);
128         return ERR_APPEXECFWK_INSTALL_DISK_MEM_INSUFFICIENT;
129     }
130     return ERR_OK;
131 }
132 
ExtractFiles(const ExtractParam & extractParam)133 ErrCode InstalldHostImpl::ExtractFiles(const ExtractParam &extractParam)
134 {
135     APP_LOGD("ExtractFiles extractParam %{public}s", extractParam.ToString().c_str());
136     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
137         APP_LOGE("installd permission denied, only used for foundation process");
138         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
139     }
140 
141     if (extractParam.srcPath.empty() || extractParam.targetPath.empty()) {
142         APP_LOGE("Calling the function ExtractFiles with invalid param");
143         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
144     }
145 
146     if (!InstalldOperator::ExtractFiles(extractParam)) {
147         APP_LOGE("extract failed");
148         return ERR_APPEXECFWK_INSTALL_DISK_MEM_INSUFFICIENT;
149     }
150 
151     return ERR_OK;
152 }
153 
ExecuteAOT(const AOTArgs & aotArgs)154 ErrCode InstalldHostImpl::ExecuteAOT(const AOTArgs &aotArgs)
155 {
156     APP_LOGD("begin to execute AOT, args : %{public}s", aotArgs.ToString().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     ErrCode ret = ERR_OK;
162     AOTExecutor::GetInstance().ExecuteAOT(aotArgs, ret);
163     APP_LOGD("execute AOT ret : %{public}d", ret);
164     return ret;
165 }
166 
RenameModuleDir(const std::string & oldPath,const std::string & newPath)167 ErrCode InstalldHostImpl::RenameModuleDir(const std::string &oldPath, const std::string &newPath)
168 {
169     APP_LOGD("rename %{public}s to %{public}s", oldPath.c_str(), newPath.c_str());
170     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
171         APP_LOGE("installd permission denied, only used for foundation process");
172         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
173     }
174     if (oldPath.empty() || newPath.empty()) {
175         APP_LOGE("Calling the function RenameModuleDir with invalid param");
176         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
177     }
178     if (!InstalldOperator::RenameDir(oldPath, newPath)) {
179         APP_LOGE("rename module dir %{public}s to %{public}s failed", oldPath.c_str(), newPath.c_str());
180         return ERR_APPEXECFWK_INSTALLD_RNAME_DIR_FAILED;
181     }
182     return ERR_OK;
183 }
184 
GetBackupExtDirByType(std::string & bundleBackupDir,const std::string & bundleName,const DirType dirType)185 static void GetBackupExtDirByType(std::string &bundleBackupDir, const std::string &bundleName, const DirType dirType)
186 {
187     switch (dirType) {
188         case DirType::DIR_EL1:
189             bundleBackupDir = BUNDLE_BACKUP_HOME_PATH_EL1 + bundleName;
190             break;
191         case DirType::DIR_EL2:
192             bundleBackupDir = BUNDLE_BACKUP_HOME_PATH_EL2 + bundleName;
193             break;
194         default:
195             break;
196     }
197 }
198 
CreateBackupExtHomeDir(const std::string & bundleName,const int32_t userid,const int32_t uid,std::string & bundleBackupDir,const DirType dirType)199 static void CreateBackupExtHomeDir(const std::string &bundleName, const int32_t userid, const int32_t uid,
200     std::string &bundleBackupDir, const DirType dirType)
201 {
202     GetBackupExtDirByType(bundleBackupDir, bundleName, dirType);
203     APP_LOGD("CreateBackupExtHomeDir begin, type %{public}d, path %{public}s.", dirType, bundleBackupDir.c_str());
204     if (bundleBackupDir.empty()) {
205         APP_LOGW("CreateBackupExtHomeDir backup dir empty, type  %{public}d.", dirType);
206         return;
207     }
208     // Setup BackupExtensionAbility's home directory in a harmless way
209     bundleBackupDir = bundleBackupDir.replace(bundleBackupDir.find("%"), 1, std::to_string(userid));
210     if (!InstalldOperator::MkOwnerDir(bundleBackupDir, S_IRWXU | S_IRWXG | S_ISGID, uid, Constants::BACKU_HOME_GID)) {
211         static std::once_flag logOnce;
212         std::call_once(logOnce, []() {
213             APP_LOGW("CreateBackupExtHomeDir MkOwnerDir(backup's home dir) failed");
214         });
215     }
216 }
217 
CreateShareDir(const std::string & bundleName,const int32_t userid,const int32_t uid,const int32_t gid)218 static void CreateShareDir(const std::string &bundleName, const int32_t userid, const int32_t uid, const int32_t gid)
219 {
220     std::string bundleShareDir = SHARE_FILE_PATH + bundleName;
221     bundleShareDir = bundleShareDir.replace(bundleShareDir.find("%"), 1, std::to_string(userid));
222     if (!InstalldOperator::MkOwnerDir(bundleShareDir, S_IRWXU | S_IRWXG | S_ISGID, uid, gid)) {
223         static std::once_flag logOnce;
224         std::call_once(logOnce, []() {
225             APP_LOGW("CreateShareDir MkOwnerDir(share's home dir) failed");
226         });
227     }
228 }
229 
CreateCloudDir(const std::string & bundleName,const int32_t userid,const int32_t uid,const int32_t gid)230 static void CreateCloudDir(const std::string &bundleName, const int32_t userid, const int32_t uid, const int32_t gid)
231 {
232     std::string bundleCloudDir = CLOUD_FILE_PATH + bundleName;
233     bundleCloudDir = bundleCloudDir.replace(bundleCloudDir.find("%"), 1, std::to_string(userid));
234     if (!InstalldOperator::MkOwnerDir(bundleCloudDir, S_IRWXU | S_IRWXG | S_ISGID, uid, gid)) {
235         static std::once_flag logOnce;
236         std::call_once(logOnce, []() {
237             APP_LOGW("CreateCloudDir MkOwnerDir(cloud's home dir) failed");
238         });
239     }
240 }
CreateBundleDataDirWithVector(const std::vector<CreateDirParam> & createDirParams)241 ErrCode InstalldHostImpl::CreateBundleDataDirWithVector(const std::vector<CreateDirParam> &createDirParams)
242 {
243     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
244         APP_LOGE("installd permission denied, only used for foundation process");
245         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
246     }
247     ErrCode res = ERR_OK;
248     for (const auto &item : createDirParams) {
249         auto result = CreateBundleDataDir(item);
250         if (result != ERR_OK) {
251             APP_LOGE("CreateBundleDataDir failed in %{public}s, errCode is %{public}d",
252                 item.bundleName.c_str(), result);
253             res = result;
254         }
255     }
256     return res;
257 }
258 
CreateBundleDataDir(const CreateDirParam & createDirParam)259 ErrCode InstalldHostImpl::CreateBundleDataDir(const CreateDirParam &createDirParam)
260 {
261     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
262         APP_LOGE("installd permission denied, only used for foundation process");
263         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
264     }
265     if (createDirParam.bundleName.empty() || createDirParam.userId < 0 ||
266         createDirParam.uid < 0 || createDirParam.gid < 0) {
267         APP_LOGE("Calling the function CreateBundleDataDir with invalid param");
268         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
269     }
270     for (const auto &el : Constants::BUNDLE_EL) {
271         if ((createDirParam.createDirFlag == CreateDirFlag::CREATE_DIR_UNLOCKED) &&
272             (el == Constants::BUNDLE_EL[0])) {
273             continue;
274         }
275 
276         std::string bundleDataDir = GetBundleDataDir(el, createDirParam.userId) + Constants::BASE;
277         if (access(bundleDataDir.c_str(), F_OK) != 0) {
278             APP_LOGW("Base directory %{public}s does not existed, bundleName:%{public}s",
279                 bundleDataDir.c_str(), createDirParam.bundleName.c_str());
280             return ERR_OK;
281         }
282         bundleDataDir += createDirParam.bundleName;
283         if (!InstalldOperator::MkOwnerDir(bundleDataDir, S_IRWXU, createDirParam.uid, createDirParam.gid)) {
284             APP_LOGE("CreateBundledatadir MkOwnerDir failed");
285             return ERR_APPEXECFWK_INSTALLD_CREATE_DIR_FAILED;
286         }
287         if (el == Constants::BUNDLE_EL[1]) {
288             for (const auto &dir : BUNDLE_DATA_DIR) {
289                 if (!InstalldOperator::MkOwnerDir(bundleDataDir + dir, S_IRWXU,
290                     createDirParam.uid, createDirParam.gid)) {
291                     APP_LOGE("CreateBundledatadir MkOwnerDir el2 failed");
292                     return ERR_APPEXECFWK_INSTALLD_CREATE_DIR_FAILED;
293                 }
294             }
295             std::string logDir = GetBundleDataDir(el, createDirParam.userId) +
296                 Constants::LOG + createDirParam.bundleName;
297             if (!InstalldOperator::MkOwnerDir(
298                 logDir, S_IRWXU | S_IRWXG, createDirParam.uid, Constants::LOG_DIR_GID)) {
299                 APP_LOGE("create log dir failed");
300                 return ERR_APPEXECFWK_INSTALLD_CREATE_DIR_FAILED;
301             }
302         }
303         ErrCode ret = SetDirApl(bundleDataDir, createDirParam.bundleName, createDirParam.apl,
304             createDirParam.isPreInstallApp, createDirParam.debug);
305         if (ret != ERR_OK) {
306             APP_LOGE("CreateBundleDataDir SetDirApl failed");
307             return ret;
308         }
309         std::string databaseDir = GetBundleDataDir(el, createDirParam.userId) + Constants::DATABASE
310             + createDirParam.bundleName;
311         if (!InstalldOperator::MkOwnerDir(
312             databaseDir, S_IRWXU | S_IRWXG | S_ISGID, createDirParam.uid, Constants::DATABASE_DIR_GID)) {
313             APP_LOGE("CreateBundle databaseDir MkOwnerDir failed");
314             return ERR_APPEXECFWK_INSTALLD_CREATE_DIR_FAILED;
315         }
316         ret = SetDirApl(databaseDir, createDirParam.bundleName, createDirParam.apl,
317             createDirParam.isPreInstallApp, createDirParam.debug);
318         if (ret != ERR_OK) {
319             APP_LOGE("CreateBundleDataDir SetDirApl failed");
320             return ret;
321         }
322     }
323     std::string distributedfile = DISTRIBUTED_FILE;
324     distributedfile = distributedfile.replace(distributedfile.find("%"), 1, std::to_string(createDirParam.userId));
325     if (!InstalldOperator::MkOwnerDir(distributedfile + createDirParam.bundleName,
326         S_IRWXU | S_IRWXG | S_ISGID, createDirParam.uid, Constants::DFS_GID)) {
327         APP_LOGE("Failed to mk dir for distributedfile");
328     }
329 
330     distributedfile = DISTRIBUTED_FILE_NON_ACCOUNT;
331     distributedfile = distributedfile.replace(distributedfile.find("%"), 1, std::to_string(createDirParam.userId));
332     if (!InstalldOperator::MkOwnerDir(distributedfile + createDirParam.bundleName,
333         S_IRWXU | S_IRWXG | S_ISGID, createDirParam.uid, Constants::DFS_GID)) {
334         APP_LOGE("Failed to mk dir for non account distributedfile");
335     }
336 
337     std::string bundleBackupDir;
338     CreateBackupExtHomeDir(createDirParam.bundleName, createDirParam.userId, createDirParam.uid, bundleBackupDir,
339         DirType::DIR_EL2);
340     ErrCode ret = SetDirApl(bundleBackupDir, createDirParam.bundleName, createDirParam.apl,
341         createDirParam.isPreInstallApp, createDirParam.debug);
342     if (ret != ERR_OK) {
343         APP_LOGE("CreateBackupExtHomeDir DIR_EL2 SetDirApl failed, errno is %{public}d", ret);
344     }
345 
346     CreateBackupExtHomeDir(createDirParam.bundleName, createDirParam.userId, createDirParam.uid, bundleBackupDir,
347         DirType::DIR_EL1);
348     ret = SetDirApl(bundleBackupDir, createDirParam.bundleName, createDirParam.apl,
349         createDirParam.isPreInstallApp, createDirParam.debug);
350     if (ret != ERR_OK) {
351         APP_LOGE("CreateBackupExtHomeDir DIR_EL1 SetDirApl failed, errno is %{public}d", ret);
352     }
353 
354     CreateShareDir(createDirParam.bundleName, createDirParam.userId, createDirParam.uid, createDirParam.gid);
355     CreateCloudDir(createDirParam.bundleName, createDirParam.userId, createDirParam.uid, Constants::DFS_GID);
356     return ERR_OK;
357 }
358 
RemoveBackupExtHomeDir(const std::string & bundleName,const int userid,DirType dirType)359 static ErrCode RemoveBackupExtHomeDir(const std::string &bundleName, const int userid, DirType dirType)
360 {
361     std::string bundleBackupDir;
362     GetBackupExtDirByType(bundleBackupDir, bundleName, dirType);
363     APP_LOGD("RemoveBackupExtHomeDir begin, type %{public}d, path %{public}s.", dirType, bundleBackupDir.c_str());
364     if (bundleBackupDir.empty()) {
365         APP_LOGW("RemoveBackupExtHomeDir backup dir empty, type  %{public}d.", dirType);
366         return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
367     }
368     bundleBackupDir = bundleBackupDir.replace(bundleBackupDir.find("%"), 1, std::to_string(userid));
369     if (!InstalldOperator::DeleteDir(bundleBackupDir)) {
370         APP_LOGE("remove dir %{public}s failed, errno is %{public}d", bundleBackupDir.c_str(), errno);
371         return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
372     }
373     return ERR_OK;
374 }
375 
CleanBackupExtHomeDir(const std::string & bundleName,const int userid,DirType dirType)376 static void CleanBackupExtHomeDir(const std::string &bundleName, const int userid, DirType dirType)
377 {
378     std::string bundleBackupDir;
379     GetBackupExtDirByType(bundleBackupDir, bundleName, dirType);
380     APP_LOGD("CleanBackupExtHomeDir begin, type %{public}d, path %{public}s.", dirType, bundleBackupDir.c_str());
381     if (bundleBackupDir.empty()) {
382         APP_LOGW("CleanBackupExtHomeDir backup dir empty, type %{public}d.", dirType);
383         return;
384     }
385     bundleBackupDir = bundleBackupDir.replace(bundleBackupDir.find("%"), 1, std::to_string(userid));
386     if (!InstalldOperator::DeleteFiles(bundleBackupDir)) {
387         APP_LOGW("clean dir %{public}s failed, errno is %{public}d", bundleBackupDir.c_str(), errno);
388     }
389 }
390 
RemoveDistributedDir(const std::string & bundleName,const int userid)391 static ErrCode RemoveDistributedDir(const std::string &bundleName, const int userid)
392 {
393     std::string distributedFile = DISTRIBUTED_FILE + bundleName;
394     distributedFile = distributedFile.replace(distributedFile.find("%"), 1, std::to_string(userid));
395     if (!InstalldOperator::DeleteDir(distributedFile)) {
396         APP_LOGE("remove dir %{public}s failed, errno is %{public}d", distributedFile.c_str(), errno);
397         return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
398     }
399     std::string fileNonAccount = DISTRIBUTED_FILE_NON_ACCOUNT + bundleName;
400     fileNonAccount = fileNonAccount.replace(fileNonAccount.find("%"), 1, std::to_string(userid));
401     if (!InstalldOperator::DeleteDir(fileNonAccount)) {
402         APP_LOGE("remove dir %{public}s failed, errno is %{public}d", fileNonAccount.c_str(), errno);
403         return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
404     }
405     return ERR_OK;
406 }
407 
CleanDistributedDir(const std::string & bundleName,const int userid)408 static void CleanDistributedDir(const std::string &bundleName, const int userid)
409 {
410     std::string distributedFile = DISTRIBUTED_FILE + bundleName;
411     distributedFile = distributedFile.replace(distributedFile.find("%"), 1, std::to_string(userid));
412     if (!InstalldOperator::DeleteFiles(distributedFile)) {
413         APP_LOGW("clean dir %{public}s failed, errno is %{public}d", distributedFile.c_str(), errno);
414     }
415     std::string fileNonAccount = DISTRIBUTED_FILE_NON_ACCOUNT + bundleName;
416     fileNonAccount = fileNonAccount.replace(fileNonAccount.find("%"), 1, std::to_string(userid));
417     if (!InstalldOperator::DeleteFiles(fileNonAccount)) {
418         APP_LOGW("clean dir %{public}s failed, errno is %{public}d", fileNonAccount.c_str(), errno);
419     }
420 }
421 
RemoveShareDir(const std::string & bundleName,const int userid)422 static ErrCode RemoveShareDir(const std::string &bundleName, const int userid)
423 {
424     std::string shareFileDir = SHARE_FILE_PATH + bundleName;
425     shareFileDir = shareFileDir.replace(shareFileDir.find("%"), 1, std::to_string(userid));
426     if (!InstalldOperator::DeleteDir(shareFileDir)) {
427         APP_LOGE("remove dir %{public}s failed", shareFileDir.c_str());
428         return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
429     }
430     return ERR_OK;
431 }
432 
CleanShareDir(const std::string & bundleName,const int userid)433 static void CleanShareDir(const std::string &bundleName, const int userid)
434 {
435     std::string shareFileDir = SHARE_FILE_PATH + bundleName;
436     shareFileDir = shareFileDir.replace(shareFileDir.find("%"), 1, std::to_string(userid));
437     if (!InstalldOperator::DeleteFiles(shareFileDir)) {
438         APP_LOGW("clean dir %{public}s failed", shareFileDir.c_str());
439     }
440 }
441 
RemoveCloudDir(const std::string & bundleName,const int userid)442 static ErrCode RemoveCloudDir(const std::string &bundleName, const int userid)
443 {
444     std::string cloudFileDir = CLOUD_FILE_PATH + bundleName;
445     cloudFileDir = cloudFileDir.replace(cloudFileDir.find("%"), 1, std::to_string(userid));
446     if (!InstalldOperator::DeleteDir(cloudFileDir)) {
447         APP_LOGE("remove dir %{public}s failed", cloudFileDir.c_str());
448         return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
449     }
450     return ERR_OK;
451 }
452 
CleanCloudDir(const std::string & bundleName,const int userid)453 static void CleanCloudDir(const std::string &bundleName, const int userid)
454 {
455     std::string cloudFileDir = CLOUD_FILE_PATH + bundleName;
456     cloudFileDir = cloudFileDir.replace(cloudFileDir.find("%"), 1, std::to_string(userid));
457     if (!InstalldOperator::DeleteFiles(cloudFileDir)) {
458         APP_LOGW("clean dir %{public}s failed", cloudFileDir.c_str());
459     }
460 }
461 
CleanBundleDataForEl2(const std::string & bundleName,const int userid)462 static void CleanBundleDataForEl2(const std::string &bundleName, const int userid)
463 {
464     std::string dataDir = Constants::BUNDLE_APP_DATA_BASE_DIR + Constants::BUNDLE_EL[1] +
465         Constants::PATH_SEPARATOR + std::to_string(userid);
466     std::string databaseDir = dataDir + Constants::DATABASE + bundleName;
467     if (!InstalldOperator::DeleteFiles(databaseDir)) {
468         APP_LOGW("clean dir %{public}s failed", databaseDir.c_str());
469     }
470     std::string logDir = dataDir + Constants::LOG + bundleName;
471     if (!InstalldOperator::DeleteFiles(logDir)) {
472         APP_LOGW("clean dir %{public}s failed", logDir.c_str());
473     }
474     std::string bundleDataDir = dataDir + Constants::BASE + bundleName;
475     for (const auto &dir : BUNDLE_DATA_DIR) {
476         std::string subDir = bundleDataDir + dir;
477         if (!InstalldOperator::DeleteFiles(subDir)) {
478             APP_LOGW("clean dir %{public}s failed", subDir.c_str());
479         }
480     }
481     if (!InstalldOperator::DeleteFilesExceptDirs(bundleDataDir, BUNDLE_DATA_DIR)) {
482         APP_LOGW("clean dir %{public}s failed", bundleDataDir.c_str());
483     }
484 }
485 
RemoveBundleDataDir(const std::string & bundleName,const int userid)486 ErrCode InstalldHostImpl::RemoveBundleDataDir(const std::string &bundleName, const int userid)
487 {
488     APP_LOGD("InstalldHostImpl::RemoveBundleDataDir bundleName:%{public}s", bundleName.c_str());
489     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
490         APP_LOGE("installd permission denied, only used for foundation process");
491         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
492     }
493     if (bundleName.empty() || userid < 0) {
494         APP_LOGE("Calling the function CreateBundleDataDir with invalid param");
495         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
496     }
497     for (const auto &el : Constants::BUNDLE_EL) {
498         std::string bundleDataDir = GetBundleDataDir(el, userid) + Constants::BASE + bundleName;
499         if (!InstalldOperator::DeleteDir(bundleDataDir)) {
500             APP_LOGE("remove dir %{public}s failed", bundleDataDir.c_str());
501             return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
502         }
503         std::string databaseDir = GetBundleDataDir(el, userid) + Constants::DATABASE + bundleName;
504         if (!InstalldOperator::DeleteDir(databaseDir)) {
505             APP_LOGE("remove dir %{public}s failed", databaseDir.c_str());
506             return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
507         }
508         if (el == Constants::BUNDLE_EL[1]) {
509             std::string logDir = GetBundleDataDir(el, userid) + Constants::LOG + bundleName;
510             if (!InstalldOperator::DeleteDir(logDir)) {
511                 APP_LOGE("remove dir %{public}s failed", logDir.c_str());
512                 return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
513             }
514         }
515     }
516     if (RemoveShareDir(bundleName, userid) != ERR_OK) {
517         APP_LOGE("failed to remove share dir");
518         return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
519     }
520     if (RemoveCloudDir(bundleName, userid) != ERR_OK) {
521         APP_LOGE("failed to remove cloud dir");
522         return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
523     }
524     if (RemoveBackupExtHomeDir(bundleName, userid, DirType::DIR_EL2) != ERR_OK ||
525         RemoveBackupExtHomeDir(bundleName, userid, DirType::DIR_EL1) != ERR_OK) {
526         APP_LOGE("failed to remove backup ext home dir");
527         return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
528     }
529     if (RemoveDistributedDir(bundleName, userid) != ERR_OK) {
530         APP_LOGE("failed to remove distributed file dir");
531         return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
532     }
533     return ERR_OK;
534 }
535 
RemoveModuleDataDir(const std::string & ModuleDir,const int userid)536 ErrCode InstalldHostImpl::RemoveModuleDataDir(const std::string &ModuleDir, const int userid)
537 {
538     APP_LOGD("InstalldHostImpl::RemoveModuleDataDir ModuleDir:%{public}s", ModuleDir.c_str());
539     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
540         APP_LOGE("installd permission denied, only used for foundation process");
541         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
542     }
543     if (ModuleDir.empty() || userid < 0) {
544         APP_LOGE("Calling the function CreateModuleDataDir with invalid param");
545         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
546     }
547 
548     for (const auto &el : Constants::BUNDLE_EL) {
549         std::string moduleDataDir = GetBundleDataDir(el, userid) + Constants::BASE + ModuleDir;
550         if (!InstalldOperator::DeleteDir(moduleDataDir)) {
551             APP_LOGE("remove dir %{public}s failed", moduleDataDir.c_str());
552         }
553     }
554     return ERR_OK;
555 }
556 
RemoveDir(const std::string & dir)557 ErrCode InstalldHostImpl::RemoveDir(const std::string &dir)
558 {
559     APP_LOGD("InstalldHostImpl::RemoveDir:%{public}s", dir.c_str());
560     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
561         APP_LOGE("installd permission denied, only used for foundation process");
562         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
563     }
564     if (dir.empty()) {
565         APP_LOGE("Calling the function RemoveDir with invalid param");
566         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
567     }
568     if (!InstalldOperator::DeleteDir(dir)) {
569         APP_LOGE("remove dir %{public}s failed", dir.c_str());
570         return ERR_APPEXECFWK_INSTALLD_REMOVE_DIR_FAILED;
571     }
572     return ERR_OK;
573 }
574 
CleanBundleDataDir(const std::string & dataDir)575 ErrCode InstalldHostImpl::CleanBundleDataDir(const std::string &dataDir)
576 {
577     APP_LOGD("InstalldHostImpl::CleanBundleDataDir start");
578     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
579         APP_LOGE("installd permission denied, only used for foundation process");
580         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
581     }
582     if (dataDir.empty()) {
583         APP_LOGE("Calling the function CleanBundleDataDir with invalid param");
584         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
585     }
586 
587     if (!InstalldOperator::DeleteFiles(dataDir)) {
588         APP_LOGE("CleanBundleDataDir delete files failed");
589         return ERR_APPEXECFWK_INSTALLD_CLEAN_DIR_FAILED;
590     }
591     return ERR_OK;
592 }
593 
CleanBundleDataDirByName(const std::string & bundleName,const int userid)594 ErrCode InstalldHostImpl::CleanBundleDataDirByName(const std::string &bundleName, const int userid)
595 {
596     APP_LOGD("InstalldHostImpl::CleanBundleDataDirByName bundleName:%{public}s", bundleName.c_str());
597     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
598         APP_LOGE("installd permission denied, only used for foundation process");
599         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
600     }
601     if (bundleName.empty() || userid < 0) {
602         APP_LOGE("Calling the function CleanBundleDataDirByName with invalid param");
603         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
604     }
605     for (const auto &el : Constants::BUNDLE_EL) {
606         if (el == Constants::BUNDLE_EL[1]) {
607             CleanBundleDataForEl2(bundleName, userid);
608             continue;
609         }
610         std::string bundleDataDir = GetBundleDataDir(el, userid) + Constants::BASE + bundleName;
611         if (!InstalldOperator::DeleteFiles(bundleDataDir)) {
612             APP_LOGW("clean dir %{public}s failed", bundleDataDir.c_str());
613         }
614         std::string databaseDir = GetBundleDataDir(el, userid) + Constants::DATABASE + bundleName;
615         if (!InstalldOperator::DeleteFiles(databaseDir)) {
616             APP_LOGW("clean dir %{public}s failed", databaseDir.c_str());
617         }
618     }
619     CleanShareDir(bundleName, userid);
620     CleanCloudDir(bundleName, userid);
621     CleanBackupExtHomeDir(bundleName, userid, DirType::DIR_EL2);
622     CleanBackupExtHomeDir(bundleName, userid, DirType::DIR_EL1);
623     CleanDistributedDir(bundleName, userid);
624     return ERR_OK;
625 }
626 
GetBundleDataDir(const std::string & el,const int userid) const627 std::string InstalldHostImpl::GetBundleDataDir(const std::string &el, const int userid) const
628 {
629     std::string dataDir = Constants::BUNDLE_APP_DATA_BASE_DIR +
630                           el +
631                           Constants::PATH_SEPARATOR +
632                           std::to_string(userid);
633     return dataDir;
634 }
635 
GetBundleStats(const std::string & bundleName,const int32_t userId,std::vector<int64_t> & bundleStats,const int32_t uid)636 ErrCode InstalldHostImpl::GetBundleStats(
637     const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats, const int32_t uid)
638 {
639     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
640         APP_LOGE("installd permission denied, only used for foundation process");
641         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
642     }
643     if (bundleName.empty()) {
644         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
645     }
646     std::vector<std::string> bundlePath;
647     bundlePath.push_back(Constants::BUNDLE_CODE_DIR + Constants::PATH_SEPARATOR + bundleName); // bundle code
648     bundlePath.push_back(ARK_CACHE_PATH + bundleName); // ark cache file
649     // ark profile
650     bundlePath.push_back(ARK_PROFILE_PATH + std::to_string(userId) + Constants::PATH_SEPARATOR + bundleName);
651     int64_t fileSize = InstalldOperator::GetDiskUsageFromPath(bundlePath);
652     bundlePath.clear();
653     std::vector<std::string> cachePath;
654     int64_t allBundleLocalSize = 0;
655     for (const auto &el : Constants::BUNDLE_EL) {
656         std::string filePath = Constants::BUNDLE_APP_DATA_BASE_DIR + el + Constants::PATH_SEPARATOR +
657             std::to_string(userId) + Constants::BASE + bundleName;
658         allBundleLocalSize += InstalldOperator::GetDiskUsage(filePath);
659         if (el == Constants::BUNDLE_EL[1]) {
660             for (const auto &dataDir : BUNDLE_DATA_DIR) {
661                 bundlePath.push_back(filePath + dataDir);
662             }
663         } else {
664             bundlePath.push_back(filePath);
665         }
666         InstalldOperator::TraverseCacheDirectory(filePath, cachePath);
667     }
668     int64_t bundleLocalSize = InstalldOperator::GetDiskUsageFromPath(bundlePath);
669     int64_t systemFolderSize = allBundleLocalSize - bundleLocalSize;
670     // index 0 : bundle data size
671     bundleStats.push_back(fileSize + systemFolderSize);
672     int64_t bundleDataSize = InstalldOperator::GetDiskUsageFromQuota(uid);
673     // index 1 : local bundle data size
674     bundleStats.push_back(bundleDataSize);
675     bundleStats.push_back(0);
676     bundleStats.push_back(0);
677     int64_t cacheSize = InstalldOperator::GetDiskUsageFromPath(cachePath);
678     // index 4 : cache size
679     bundleStats.push_back(cacheSize);
680     return ERR_OK;
681 }
682 
GetAllBundleStats(const std::vector<std::string> & bundleNames,const int32_t userId,std::vector<int64_t> & bundleStats,const std::vector<int32_t> & uids)683 ErrCode InstalldHostImpl::GetAllBundleStats(const std::vector<std::string> &bundleNames, const int32_t userId,
684     std::vector<int64_t> &bundleStats, const std::vector<int32_t> &uids)
685 {
686     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
687         APP_LOGE("installd permission denied, only used for foundation process");
688         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
689     }
690     if (bundleNames.empty() || bundleNames.size() != uids.size()) {
691         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
692     }
693     int64_t totalFileSize = 0;
694     int64_t totalDataSize = 0;
695     for (size_t index = 0; index < bundleNames.size(); ++index) {
696         const auto &bundleName = bundleNames[index];
697         const auto &uid = uids[index];
698         std::vector<std::string> bundlePath;
699         bundlePath.push_back(Constants::BUNDLE_CODE_DIR + Constants::PATH_SEPARATOR + bundleName); // bundle code
700         bundlePath.push_back(ARK_CACHE_PATH + bundleName); // ark cache file
701         // ark profile
702         bundlePath.push_back(ARK_PROFILE_PATH + std::to_string(userId) + Constants::PATH_SEPARATOR + bundleName);
703         int64_t fileSize = InstalldOperator::GetDiskUsageFromPath(bundlePath);
704         // index 0 : bundle data size
705         totalFileSize += fileSize;
706         int64_t bundleDataSize = InstalldOperator::GetDiskUsageFromQuota(uid);
707         // index 1 : local bundle data size
708         totalDataSize += bundleDataSize;
709     }
710     bundleStats.push_back(totalFileSize);
711     bundleStats.push_back(totalDataSize);
712     bundleStats.push_back(0);
713     bundleStats.push_back(0);
714     bundleStats.push_back(0);
715     return ERR_OK;
716 }
717 
SetDirApl(const std::string & dir,const std::string & bundleName,const std::string & apl,bool isPreInstallApp,bool debug)718 ErrCode InstalldHostImpl::SetDirApl(const std::string &dir, const std::string &bundleName, const std::string &apl,
719     bool isPreInstallApp, bool debug)
720 {
721 #ifdef WITH_SELINUX
722     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
723         APP_LOGE("installd permission denied, only used for foundation process");
724         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
725     }
726     if (dir.empty() || bundleName.empty()) {
727         APP_LOGE("Calling the function SetDirApl with invalid param");
728         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
729     }
730     HapFileInfo hapFileInfo;
731     hapFileInfo.pathNameOrig.push_back(dir);
732     hapFileInfo.apl = apl;
733     hapFileInfo.packageName = bundleName;
734     hapFileInfo.flags = SELINUX_HAP_RESTORECON_RECURSE;
735     hapFileInfo.hapFlags = isPreInstallApp ? SELINUX_HAP_RESTORECON_PREINSTALLED_APP : 0;
736     hapFileInfo.hapFlags |= debug ? SELINUX_HAP_DEBUGGABLE : 0;
737     HapContext hapContext;
738     int ret = hapContext.HapFileRestorecon(hapFileInfo);
739     if (ret != 0) {
740         APP_LOGE("HapFileRestorecon path: %{public}s failed, apl: %{public}s, errcode:%{public}d",
741             dir.c_str(), apl.c_str(), ret);
742         return ERR_APPEXECFWK_INSTALLD_SET_SELINUX_LABEL_FAILED;
743     }
744     return ret;
745 #else
746     return ERR_OK;
747 #endif // WITH_SELINUX
748 }
749 
GetBundleCachePath(const std::string & dir,std::vector<std::string> & cachePath)750 ErrCode InstalldHostImpl::GetBundleCachePath(const std::string &dir, std::vector<std::string> &cachePath)
751 {
752     APP_LOGD("InstalldHostImpl::GetBundleCachePath start");
753     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
754         APP_LOGE("installd permission denied, only used for foundation process");
755         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
756     }
757     if (dir.empty()) {
758         APP_LOGE("Calling the function GetBundleCachePath with invalid param");
759         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
760     }
761     InstalldOperator::TraverseCacheDirectory(dir, cachePath);
762     return ERR_OK;
763 }
764 
ScanDir(const std::string & dir,ScanMode scanMode,ResultMode resultMode,std::vector<std::string> & paths)765 ErrCode InstalldHostImpl::ScanDir(
766     const std::string &dir, ScanMode scanMode, ResultMode resultMode, std::vector<std::string> &paths)
767 {
768     APP_LOGD("InstalldHostImpl::Scan start %{public}s", dir.c_str());
769     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
770         APP_LOGE("installd permission denied, only used for foundation process");
771         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
772     }
773     if (dir.empty()) {
774         APP_LOGE("Calling the function Scan with invalid param");
775         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
776     }
777 
778     InstalldOperator::ScanDir(dir, scanMode, resultMode, paths);
779     return ERR_OK;
780 }
781 
MoveFile(const std::string & oldPath,const std::string & newPath)782 ErrCode InstalldHostImpl::MoveFile(const std::string &oldPath, const std::string &newPath)
783 {
784     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
785         APP_LOGE("installd permission denied, only used for foundation process");
786         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
787     }
788     if (!InstalldOperator::MoveFile(oldPath, newPath)) {
789         APP_LOGE("Move file %{public}s to %{public}s failed",
790             oldPath.c_str(), newPath.c_str());
791         return ERR_APPEXECFWK_INSTALLD_MOVE_FILE_FAILED;
792     }
793     return ERR_OK;
794 }
795 
CopyFile(const std::string & oldPath,const std::string & newPath,const std::string & signatureFilePath)796 ErrCode InstalldHostImpl::CopyFile(const std::string &oldPath, const std::string &newPath,
797     const std::string &signatureFilePath)
798 {
799     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
800         APP_LOGE("installd permission denied, only used for foundation process");
801         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
802     }
803     if (!InstalldOperator::CopyFileFast(oldPath, newPath)) {
804         APP_LOGE("Copy file %{public}s to %{public}s failed",
805             oldPath.c_str(), newPath.c_str());
806         return ERR_APPEXECFWK_INSTALLD_COPY_FILE_FAILED;
807     }
808     mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
809     if (!OHOS::ChangeModeFile(newPath, mode)) {
810         APP_LOGE("change mode failed");
811         return ERR_APPEXECFWK_INSTALLD_COPY_FILE_FAILED;
812     }
813 
814     if (signatureFilePath.empty()) {
815         APP_LOGD("signature file path is empty and no need to process code signature");
816         return ERR_OK;
817     }
818 
819 #if defined(CODE_SIGNATURE_ENABLE)
820     Security::CodeSign::EntryMap entryMap = {{ Constants::CODE_SIGNATURE_HAP, newPath }};
821     ErrCode ret = Security::CodeSign::CodeSignUtils::EnforceCodeSignForApp(entryMap, signatureFilePath);
822     if (ret != ERR_OK) {
823         APP_LOGE("hap or hsp code signature failed due to %{public}d", ret);
824         return ERR_BUNDLEMANAGER_INSTALL_CODE_SIGNATURE_FAILED;
825     }
826 #endif
827     return ERR_OK;
828 }
829 
Mkdir(const std::string & dir,const int32_t mode,const int32_t uid,const int32_t gid)830 ErrCode InstalldHostImpl::Mkdir(
831     const std::string &dir, const int32_t mode, const int32_t uid, const int32_t gid)
832 {
833     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
834         APP_LOGE("installd permission denied, only used for foundation process");
835         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
836     }
837     APP_LOGD("Mkdir start %{public}s", dir.c_str());
838     if (dir.empty()) {
839         APP_LOGE("Calling the function Mkdir with invalid param");
840         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
841     }
842 
843     if (!InstalldOperator::MkOwnerDir(dir, mode, uid, gid)) {
844         APP_LOGE("Mkdir %{public}s failed", dir.c_str());
845         return ERR_APPEXECFWK_INSTALLD_MKDIR_FAILED;
846     }
847 
848     return ERR_OK;
849 }
850 
GetFileStat(const std::string & file,FileStat & fileStat)851 ErrCode InstalldHostImpl::GetFileStat(const std::string &file, FileStat &fileStat)
852 {
853     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
854         APP_LOGE("installd permission denied, only used for foundation process");
855         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
856     }
857 
858     APP_LOGD("GetFileStat start %{public}s", file.c_str());
859     struct stat s;
860     if (stat(file.c_str(), &s) != 0) {
861         APP_LOGE("Stat file(%{public}s) failed", file.c_str());
862         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
863     }
864 
865     fileStat.uid = static_cast<int32_t>(s.st_uid);
866     fileStat.gid = static_cast<int32_t>(s.st_gid);
867     fileStat.lastModifyTime = static_cast<int64_t>(s.st_mtime);
868     fileStat.isDir = s.st_mode & S_IFDIR;
869     fileStat.mode = static_cast<int32_t>(s.st_mode);
870     return ERR_OK;
871 }
872 
ExtractDiffFiles(const std::string & filePath,const std::string & targetPath,const std::string & cpuAbi)873 ErrCode InstalldHostImpl::ExtractDiffFiles(const std::string &filePath, const std::string &targetPath,
874     const std::string &cpuAbi)
875 {
876     if (filePath.empty() || targetPath.empty()) {
877         APP_LOGE("Calling the function ExtractDiffFiles with invalid param");
878         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
879     }
880     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
881         APP_LOGE("installd permission denied, only used for foundation process");
882         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
883     }
884     if (!InstalldOperator::ExtractDiffFiles(filePath, targetPath, cpuAbi)) {
885         return ERR_BUNDLEMANAGER_QUICK_FIX_EXTRACT_DIFF_FILES_FAILED;
886     }
887     return ERR_OK;
888 }
889 
ApplyDiffPatch(const std::string & oldSoPath,const std::string & diffFilePath,const std::string & newSoPath,int32_t uid)890 ErrCode InstalldHostImpl::ApplyDiffPatch(const std::string &oldSoPath, const std::string &diffFilePath,
891     const std::string &newSoPath, int32_t uid)
892 {
893     if (oldSoPath.empty() || diffFilePath.empty() || newSoPath.empty()) {
894         APP_LOGE("Calling the function ExtractDiffFiles with invalid param");
895         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
896     }
897     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
898         APP_LOGE("installd permission denied, only used for foundation process");
899         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
900     }
901     if (!InstalldOperator::ApplyDiffPatch(oldSoPath, diffFilePath, newSoPath, uid)) {
902         return ERR_BUNDLEMANAGER_QUICK_FIX_APPLY_DIFF_PATCH_FAILED;
903     }
904     return ERR_OK;
905 }
906 
IsExistDir(const std::string & dir,bool & isExist)907 ErrCode InstalldHostImpl::IsExistDir(const std::string &dir, bool &isExist)
908 {
909     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
910         APP_LOGE("installd permission denied, only used for foundation process");
911         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
912     }
913     isExist = InstalldOperator::IsExistDir(dir);
914     return ERR_OK;
915 }
916 
IsExistFile(const std::string & path,bool & isExist)917 ErrCode InstalldHostImpl::IsExistFile(const std::string &path, bool &isExist)
918 {
919     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
920         APP_LOGE("installd permission denied, only used for foundation process");
921         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
922     }
923     isExist = InstalldOperator::IsExistFile(path);
924     return ERR_OK;
925 }
926 
IsExistApFile(const std::string & path,bool & isExist)927 ErrCode InstalldHostImpl::IsExistApFile(const std::string &path, bool &isExist)
928 {
929     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
930         APP_LOGE("installd permission denied, only used for foundation process");
931         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
932     }
933     isExist = InstalldOperator::IsExistApFile(path);
934     return ERR_OK;
935 }
936 
IsDirEmpty(const std::string & dir,bool & isDirEmpty)937 ErrCode InstalldHostImpl::IsDirEmpty(const std::string &dir, bool &isDirEmpty)
938 {
939     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
940         APP_LOGE("installd permission denied, only used for foundation process");
941         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
942     }
943     isDirEmpty = InstalldOperator::IsDirEmpty(dir);
944     return ERR_OK;
945 }
946 
ObtainQuickFixFileDir(const std::string & dir,std::vector<std::string> & dirVec)947 ErrCode InstalldHostImpl::ObtainQuickFixFileDir(const std::string &dir, std::vector<std::string> &dirVec)
948 {
949     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
950         APP_LOGE("installd permission denied, only used for foundation process");
951         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
952     }
953     InstalldOperator::ObtainQuickFixFileDir(dir, dirVec);
954     return ERR_OK;
955 }
956 
CopyFiles(const std::string & sourceDir,const std::string & destinationDir)957 ErrCode InstalldHostImpl::CopyFiles(const std::string &sourceDir, const std::string &destinationDir)
958 {
959     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
960         APP_LOGE("installd permission denied, only used for foundation process");
961         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
962     }
963 
964     InstalldOperator::CopyFiles(sourceDir, destinationDir);
965     return ERR_OK;
966 }
967 
GetNativeLibraryFileNames(const std::string & filePath,const std::string & cpuAbi,std::vector<std::string> & fileNames)968 ErrCode InstalldHostImpl::GetNativeLibraryFileNames(const std::string &filePath, const std::string &cpuAbi,
969     std::vector<std::string> &fileNames)
970 {
971     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
972         APP_LOGE("installd permission denied, only used for foundation process");
973         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
974     }
975     if (filePath.empty()) {
976         APP_LOGE("Calling the function ExtractDiffFiles with invalid param");
977         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
978     }
979     InstalldOperator::GetNativeLibraryFileNames(filePath, cpuAbi, fileNames);
980     return ERR_OK;
981 }
982 
VerifyCodeSignature(const CodeSignatureParam & codeSignatureParam)983 ErrCode InstalldHostImpl::VerifyCodeSignature(const CodeSignatureParam &codeSignatureParam)
984 {
985     APP_LOGD("start to process the code signature for so files");
986     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
987         APP_LOGE("installd permission denied, only used for foundation process");
988         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
989     }
990     APP_LOGD("code sign param is %{public}s", codeSignatureParam.ToString().c_str());
991     if (codeSignatureParam.modulePath.empty()) {
992         APP_LOGE("Calling the function VerifyCodeSignature with invalid param");
993         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
994     }
995     if (!InstalldOperator::VerifyCodeSignature(codeSignatureParam)) {
996         APP_LOGE("verify code signature failed");
997         return ERR_BUNDLEMANAGER_INSTALL_CODE_SIGNATURE_FAILED;
998     }
999     return ERR_OK;
1000 }
1001 
CheckEncryption(const CheckEncryptionParam & checkEncryptionParam,bool & isEncryption)1002 ErrCode InstalldHostImpl::CheckEncryption(const CheckEncryptionParam &checkEncryptionParam, bool &isEncryption)
1003 {
1004     APP_LOGD("start to process check encryption");
1005     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
1006         APP_LOGE("installd permission denied, only used for foundation process");
1007         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
1008     }
1009 
1010     if (checkEncryptionParam.modulePath.empty()) {
1011         APP_LOGE("Calling the function CheckEncryption with invalid param");
1012         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
1013     }
1014     if (!InstalldOperator::CheckEncryption(checkEncryptionParam, isEncryption)) {
1015         APP_LOGE("check encryption failed");
1016         return ERR_APPEXECFWK_INSTALL_CHECK_ENCRYPTION_FAILED;
1017     }
1018     return ERR_OK;
1019 }
1020 
MoveFiles(const std::string & srcDir,const std::string & desDir)1021 ErrCode InstalldHostImpl::MoveFiles(const std::string &srcDir, const std::string &desDir)
1022 {
1023     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
1024         APP_LOGE("installd permission denied, only used for foundation process");
1025         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
1026     }
1027 
1028     if (srcDir.empty() || desDir.empty()) {
1029         APP_LOGE("Calling the function MoveFiles with invalid param");
1030         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
1031     }
1032     if (!InstalldOperator::MoveFiles(srcDir, desDir)) {
1033         APP_LOGE("move files failed");
1034         return ERR_APPEXECFWK_INSTALLD_MOVE_FILE_FAILED;
1035     }
1036     return ERR_OK;
1037 }
1038 
ExtractDriverSoFiles(const std::string & srcPath,const std::unordered_multimap<std::string,std::string> & dirMap)1039 ErrCode InstalldHostImpl::ExtractDriverSoFiles(const std::string &srcPath,
1040     const std::unordered_multimap<std::string, std::string> &dirMap)
1041 {
1042     APP_LOGD("start to copy driver so files");
1043     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
1044         APP_LOGE("installd permission denied, only used for foundation process");
1045         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
1046     }
1047     if (dirMap.empty()) {
1048         APP_LOGE("Calling the function ExtractDriverSoFiles with invalid param");
1049         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
1050     }
1051 
1052     if (!InstalldOperator::ExtractDriverSoFiles(srcPath, dirMap)) {
1053         APP_LOGE("copy driver so files failed");
1054         return ERR_APPEXECFWK_INSTALLD_COPY_FILE_FAILED;
1055     }
1056     return ERR_OK;
1057 }
1058 
ExtractEncryptedSoFiles(const std::string & hapPath,const std::string & realSoFilesPath,const std::string & cpuAbi,const std::string & tmpSoPath,int32_t uid)1059 ErrCode InstalldHostImpl::ExtractEncryptedSoFiles(const std::string &hapPath, const std::string &realSoFilesPath,
1060     const std::string &cpuAbi, const std::string &tmpSoPath, int32_t uid)
1061 {
1062     APP_LOGD("start to obtain decoded so files");
1063 #if defined(CODE_ENCRYPTION_ENABLE)
1064     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
1065         APP_LOGE("installd permission denied, only used for foundation process");
1066         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
1067     }
1068 
1069     if (hapPath.empty() || tmpSoPath.empty()) {
1070         APP_LOGE("hapPath %{public}s or tmpSoPath %{public}s is empty", hapPath.c_str(), tmpSoPath.c_str());
1071         return ERR_BUNDLEMANAGER_QUICK_FIX_INVALID_PATH;
1072     }
1073 
1074     if (!CheckPathValid(hapPath, Constants::BUNDLE_CODE_DIR) ||
1075         !CheckPathValid(realSoFilesPath, Constants::BUNDLE_CODE_DIR) ||
1076         !CheckPathValid(tmpSoPath, Constants::HAP_COPY_PATH)) {
1077         return ERR_BUNDLEMANAGER_QUICK_FIX_INVALID_PATH;
1078     }
1079     if (realSoFilesPath.empty()) {
1080         /* obtain the decoded so files from hapPath*/
1081         return InstalldOperator::ExtractSoFilesToTmpHapPath(hapPath, cpuAbi, tmpSoPath, uid);
1082     } else {
1083         /* obtain the decoded so files from realSoFilesPath*/
1084         return InstalldOperator::ExtractSoFilesToTmpSoPath(hapPath, realSoFilesPath, cpuAbi, tmpSoPath, uid);
1085     }
1086 #else
1087     APP_LOGD("code encryption is not supported");
1088     return ERR_BUNDLEMANAGER_QUICK_FIX_NOT_SUPPORT_CODE_ENCRYPTION;
1089 #endif
1090 }
1091 
1092 #if defined(CODE_SIGNATURE_ENABLE)
PrepareEntryMap(const CodeSignatureParam & codeSignatureParam,Security::CodeSign::EntryMap & entryMap)1093 ErrCode InstalldHostImpl::PrepareEntryMap(const CodeSignatureParam &codeSignatureParam,
1094     Security::CodeSign::EntryMap &entryMap)
1095 {
1096     APP_LOGD("PrepareEntryMap target so path is %{public}s", codeSignatureParam.targetSoPath.c_str());
1097     if (codeSignatureParam.modulePath.empty()) {
1098         APP_LOGE("real path of the installed hap is empty");
1099         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
1100     }
1101     if (codeSignatureParam.targetSoPath.empty()) {
1102         APP_LOGW("target so path is empty");
1103         return ERR_OK;
1104     }
1105     std::vector<std::string> fileNames;
1106     if (!InstalldOperator::GetNativeLibraryFileNames(
1107         codeSignatureParam.modulePath, codeSignatureParam.cpuAbi, fileNames)) {
1108         APP_LOGE("get native library file names failed");
1109         return ERR_BUNDLEMANAGER_INSTALL_CODE_SIGNATURE_FAILED;
1110     }
1111     const std::string prefix = Constants::LIBS + codeSignatureParam.cpuAbi + Constants::PATH_SEPARATOR;
1112     for (const auto &fileName : fileNames) {
1113         std::string entryName = prefix + fileName;
1114         std::string path = codeSignatureParam.targetSoPath;
1115         if (path.back() != Constants::FILE_SEPARATOR_CHAR) {
1116             path += Constants::FILE_SEPARATOR_CHAR;
1117         }
1118         entryMap.emplace(entryName, path + fileName);
1119         APP_LOGD("entryMap add soEntry %{public}s: %{public}s", entryName.c_str(), (path + fileName).c_str());
1120     }
1121     return ERR_OK;
1122 }
1123 #endif
1124 
VerifyCodeSignatureForHap(const CodeSignatureParam & codeSignatureParam)1125 ErrCode InstalldHostImpl::VerifyCodeSignatureForHap(const CodeSignatureParam &codeSignatureParam)
1126 {
1127     APP_LOGD("code sign param is %{public}s", codeSignatureParam.ToString().c_str());
1128 #if defined(CODE_SIGNATURE_ENABLE)
1129     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
1130         APP_LOGE("installd permission denied, only used for foundation process");
1131         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
1132     }
1133     ErrCode ret = ERR_OK;
1134     if (codeSignatureParam.isCompileSdkOpenHarmony && !Security::CodeSign::CodeSignUtils::IsSupportOHCodeSign()) {
1135         APP_LOGD("code signature is not supported");
1136         return ret;
1137     }
1138     Security::CodeSign::EntryMap entryMap;
1139     if ((ret = PrepareEntryMap(codeSignatureParam, entryMap)) != ERR_OK) {
1140         APP_LOGE("prepare entry map failed");
1141         return ret;
1142     }
1143     if (codeSignatureParam.signatureFileDir.empty()) {
1144         std::shared_ptr<CodeSignHelper> codeSignHelper = std::make_shared<CodeSignHelper>();
1145         Security::CodeSign::FileType fileType = codeSignatureParam.isPreInstalledBundle ?
1146             FILE_ENTRY_ONLY : FILE_ALL;
1147         if (codeSignatureParam.isEnterpriseBundle) {
1148             APP_LOGD("Verify code signature for enterprise bundle");
1149             ret = codeSignHelper->EnforceCodeSignForAppWithOwnerId(codeSignatureParam.appIdentifier,
1150                 codeSignatureParam.modulePath, entryMap, fileType);
1151         } else {
1152             APP_LOGD("Verify code signature for non-enterprise bundle");
1153             ret = codeSignHelper->EnforceCodeSignForApp(codeSignatureParam.modulePath, entryMap, fileType);
1154         }
1155         APP_LOGI("Verify code signature for hap %{public}s", codeSignatureParam.modulePath.c_str());
1156     } else {
1157         APP_LOGD("Verify code signature with: %{public}s", codeSignatureParam.signatureFileDir.c_str());
1158         ret = Security::CodeSign::CodeSignUtils::EnforceCodeSignForApp(entryMap, codeSignatureParam.signatureFileDir);
1159     }
1160     if (ret == VerifyErrCode::CS_CODE_SIGN_NOT_EXISTS) {
1161         APP_LOGW("no code sign file in the bundle");
1162         return ERR_OK;
1163     }
1164     if (ret != ERR_OK) {
1165         APP_LOGE("hap or hsp code signature failed due to %{public}d", ret);
1166         return ERR_BUNDLEMANAGER_INSTALL_CODE_SIGNATURE_FAILED;
1167     }
1168 #else
1169     APP_LOGW("code signature feature is not supported");
1170 #endif
1171     return ERR_OK;
1172 }
1173 
DeliverySignProfile(const std::string & bundleName,int32_t profileBlockLength,const unsigned char * profileBlock)1174 ErrCode InstalldHostImpl::DeliverySignProfile(const std::string &bundleName, int32_t profileBlockLength,
1175     const unsigned char *profileBlock)
1176 {
1177     APP_LOGD("start to delivery sign profile");
1178 #if defined(CODE_SIGNATURE_ENABLE)
1179     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
1180         APP_LOGE("installd permission denied, only used for foundation process");
1181         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
1182     }
1183 
1184     if (bundleName.empty() || profileBlock == nullptr || profileBlockLength == 0) {
1185         APP_LOGE("Calling the function DeliverySignProfile with invalid param");
1186         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
1187     }
1188 
1189     APP_LOGD("delivery profile of bundle %{public}s and profile size is %{public}d", bundleName.c_str(),
1190         profileBlockLength);
1191     Security::CodeSign::ByteBuffer byteBuffer;
1192     byteBuffer.CopyFrom(reinterpret_cast<const uint8_t *>(profileBlock), profileBlockLength);
1193     ErrCode ret = Security::CodeSign::CodeSignUtils::EnableKeyInProfile(bundleName, byteBuffer);
1194     if (ret != ERR_OK) {
1195         APP_LOGE("delivery code sign profile failed due to error %{public}d", ret);
1196         return ERR_BUNDLE_MANAGER_CODE_SIGNATURE_DELIVERY_FILE_FAILED;
1197     }
1198 #else
1199     APP_LOGW("code signature feature is not supported");
1200 #endif
1201     return ERR_OK;
1202 }
1203 
RemoveSignProfile(const std::string & bundleName)1204 ErrCode InstalldHostImpl::RemoveSignProfile(const std::string &bundleName)
1205 {
1206     APP_LOGD("start to remove sign profile");
1207 #if defined(CODE_SIGNATURE_ENABLE)
1208     if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
1209         APP_LOGE("installd permission denied, only used for foundation process");
1210         return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED;
1211     }
1212 
1213     if (bundleName.empty()) {
1214         APP_LOGE("Calling the function RemoveSignProfile with invalid param");
1215         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
1216     }
1217 
1218     ErrCode ret = Security::CodeSign::CodeSignUtils::RemoveKeyInProfile(bundleName);
1219     if (ret != ERR_OK) {
1220         APP_LOGE("remove code sign profile failed due to error %{public}d", ret);
1221         return ERR_BUNDLE_MANAGER_CODE_SIGNATURE_REMOVE_FILE_FAILED;
1222     }
1223 #else
1224     APP_LOGW("code signature feature is not supported");
1225 #endif
1226     return ERR_OK;
1227 }
1228 
CheckPathValid(const std::string & path,const std::string & prefix)1229 bool InstalldHostImpl::CheckPathValid(const std::string &path, const std::string &prefix)
1230 {
1231     if (path.empty()) {
1232         return true;
1233     }
1234     if (path.find(Constants::RELATIVE_PATH) != std::string::npos) {
1235         APP_LOGE("path(%{public}s) contain relevant path", path.c_str());
1236         return false;
1237     }
1238     if (path.find(prefix) == std::string::npos) {
1239         APP_LOGE("prefix(%{public}s) cannot be found", prefix.c_str());
1240         return false;
1241     }
1242     return true;
1243 }
1244 }  // namespace AppExecFwk
1245 }  // namespace OHOS
1246