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