• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "inner_shared_bundle_installer.h"
17 
18 #include "app_log_wrapper.h"
19 #include "app_provision_info_manager.h"
20 #include "bundle_mgr_service.h"
21 #include "bundle_util.h"
22 #include "installd_client.h"
23 #include "shared/base_shared_bundle_info.h"
24 
25 namespace OHOS {
26 namespace AppExecFwk {
27 using namespace OHOS::Security;
28 namespace {
29 const std::string HSP_VERSION_PREFIX = "v";
30 const int32_t MAX_FILE_NUMBER = 2;
31 }
32 
InnerSharedBundleInstaller(const std::string & path)33 InnerSharedBundleInstaller::InnerSharedBundleInstaller(const std::string &path)
34     : sharedBundlePath_(path), bundleInstallChecker_(std::make_unique<BundleInstallChecker>())
35 {
36     APP_LOGI("inner shared bundle installer instance is created");
37 }
38 
~InnerSharedBundleInstaller()39 InnerSharedBundleInstaller::~InnerSharedBundleInstaller()
40 {
41     APP_LOGI("inner shared bundle installer instance is destroyed");
42     BundleUtil::DeleteTempDirs(toDeleteTempHspPath_);
43 }
44 
ParseFiles(const InstallCheckParam & checkParam)45 ErrCode InnerSharedBundleInstaller::ParseFiles(const InstallCheckParam &checkParam)
46 {
47     APP_LOGD("parsing shared bundle files, path : %{private}s", sharedBundlePath_.c_str());
48     ErrCode result = ERR_OK;
49 
50     // check file paths
51     std::vector<std::string> inBundlePaths;
52     result = BundleUtil::CheckFilePath({sharedBundlePath_}, inBundlePaths);
53     CHECK_RESULT(result, "hsp files check failed %{public}d");
54 
55     if (!checkParam.isPreInstallApp) {
56         // copy the haps to the dir which cannot be accessed from caller
57         result = CopyHspToSecurityDir(inBundlePaths);
58         CHECK_RESULT(result, "copy file failed %{public}d");
59     }
60 
61     // check number and type of the hsp and sig files
62     std::vector<std::string> bundlePaths;
63     result = ObtainHspFileAndSignatureFilePath(inBundlePaths, bundlePaths, signatureFileDir_);
64     CHECK_RESULT(result, "obtain hsp file path or signature file path failed due to %{public}d");
65 
66     // check syscap
67     result = bundleInstallChecker_->CheckSysCap(bundlePaths);
68     CHECK_RESULT(result, "hap syscap check failed %{public}d");
69 
70     // verify signature info for all haps
71     std::vector<Security::Verify::HapVerifyResult> hapVerifyResults;
72     result = bundleInstallChecker_->CheckMultipleHapsSignInfo(bundlePaths, hapVerifyResults);
73     CHECK_RESULT(result, "hap files check signature info failed %{public}d");
74 
75     // parse bundle infos
76     result = bundleInstallChecker_->ParseHapFiles(bundlePaths, checkParam, hapVerifyResults, parsedBundles_);
77     CHECK_RESULT(result, "parse haps file failed %{public}d");
78 
79     // check device type
80     result = bundleInstallChecker_->CheckDeviceType(parsedBundles_);
81     CHECK_RESULT(result, "check device type failed %{public}d");
82 
83     // check label info
84     result = CheckAppLabelInfo();
85     CHECK_RESULT(result, "check label info failed %{public}d");
86 
87     // check native file
88     result = bundleInstallChecker_->CheckMultiNativeFile(parsedBundles_);
89     CHECK_RESULT(result, "native so is incompatible in all haps %{public}d");
90 
91     AddAppProvisionInfo(bundleName_, hapVerifyResults[0].GetProvisionInfo());
92     return result;
93 }
94 
Install(const InstallParam & installParam)95 ErrCode InnerSharedBundleInstaller::Install(const InstallParam &installParam)
96 {
97     if (parsedBundles_.empty()) {
98         APP_LOGD("no bundle to install");
99         return ERR_OK;
100     }
101 
102     ErrCode result = ERR_OK;
103     for (auto &item : parsedBundles_) {
104         result = ExtractSharedBundles(item.first, item.second);
105         CHECK_RESULT(result, "extract shared bundles failed %{public}d");
106     }
107 
108     MergeBundleInfos();
109 
110     result = SavePreInstallInfo(installParam);
111     CHECK_RESULT(result, "save pre install info failed %{public}d");
112 
113     result = SaveBundleInfoToStorage();
114     CHECK_RESULT(result, "save bundle info to storage failed %{public}d");
115 
116     // save specifiedDistributionType and additionalInfo
117     SaveInstallParamInfo(bundleName_, installParam);
118 
119     APP_LOGD("install shared bundle successfully: %{public}s", bundleName_.c_str());
120     return result;
121 }
122 
RollBack()123 void InnerSharedBundleInstaller::RollBack()
124 {
125     // delete created directories
126     for (auto iter = createdDirs_.crbegin(); iter != createdDirs_.crend(); ++iter) {
127         ErrCode err = InstalldClient::GetInstance()->RemoveDir(*iter);
128         if (err != ERR_OK) {
129             APP_LOGE("clean dir of %{public}s failed: %{public}s", bundleName_.c_str(), iter->c_str());
130         }
131     }
132 
133     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
134     if (dataMgr == nullptr) {
135         APP_LOGE("get dataMgr failed");
136         return;
137     }
138 
139     // rollback database
140     if (!isBundleExist_) {
141         if (dataMgr->DeleteSharedBundleInfo(bundleName_)) {
142             APP_LOGE("rollback new bundle failed : %{public}s", bundleName_.c_str());
143         }
144         if (!DelayedSingleton<AppProvisionInfoManager>::GetInstance()->DeleteAppProvisionInfo(bundleName_)) {
145             APP_LOGE("bundleName: %{public}s delete appProvisionInfo failed.", bundleName_.c_str());
146         }
147         return;
148     }
149 
150     if (dataMgr->UpdateInnerBundleInfo(oldBundleInfo_)) {
151         APP_LOGE("rollback old bundle failed : %{public}s", bundleName_.c_str());
152     }
153 }
154 
CheckDependency(const Dependency & dependency) const155 bool InnerSharedBundleInstaller::CheckDependency(const Dependency &dependency) const
156 {
157     if (dependency.bundleName != bundleName_) {
158         APP_LOGE("bundle name not match : %{public}s, %{public}s", bundleName_.c_str(), dependency.bundleName.c_str());
159         return false;
160     }
161 
162     for (const auto &item : parsedBundles_) {
163         const auto bundleInfo = item.second;
164         BaseSharedBundleInfo sharedBundle;
165         bool isModuleExist = bundleInfo.GetMaxVerBaseSharedBundleInfo(dependency.moduleName, sharedBundle);
166         if (isModuleExist && dependency.versionCode <= sharedBundle.versionCode) {
167             return true;
168         }
169     }
170 
171     APP_LOGE("dependency not match");
172     return false;
173 }
174 
SendBundleSystemEvent(const EventInfo & eventTemplate) const175 void InnerSharedBundleInstaller::SendBundleSystemEvent(const EventInfo &eventTemplate) const
176 {
177     EventInfo eventInfo = eventTemplate;
178     eventInfo.bundleName = bundleName_;
179     eventInfo.versionCode = newBundleInfo_.GetBaseBundleInfo().versionCode;
180     GetInstallEventInfo(eventInfo);
181 
182     BundleEventType eventType = isBundleExist_ ? BundleEventType::UPDATE : BundleEventType::INSTALL;
183     EventReport::SendBundleSystemEvent(eventType, eventInfo);
184 }
185 
CheckAppLabelInfo()186 ErrCode InnerSharedBundleInstaller::CheckAppLabelInfo()
187 {
188     if (parsedBundles_.empty()) {
189         return ERR_OK;
190     }
191     bundleName_ = parsedBundles_.begin()->second.GetBundleName();
192 
193     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
194     if (dataMgr == nullptr) {
195         APP_LOGE("Get dataMgr shared_ptr nullptr");
196         return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
197     }
198 
199     isBundleExist_ = dataMgr->FetchInnerBundleInfo(bundleName_, oldBundleInfo_);
200     if (isBundleExist_) {
201         ErrCode ret = CheckBundleTypeWithInstalledVersion();
202         CHECK_RESULT(ret, "check bundle type with installed version failed %{public}d");
203 
204         // check old InnerBundleInfo together
205         parsedBundles_.emplace(bundleName_, oldBundleInfo_);
206     } else {
207         if (parsedBundles_.begin()->second.GetApplicationBundleType() != BundleType::SHARED) {
208             APP_LOGE("installing bundle is not hsp");
209             return ERR_APPEXECFWK_INSTALL_PARAM_ERROR;
210         }
211     }
212 
213     ErrCode result = bundleInstallChecker_->CheckAppLabelInfo(parsedBundles_);
214     if (isBundleExist_) {
215         parsedBundles_.erase(bundleName_);
216     }
217     return result;
218 }
219 
CheckBundleTypeWithInstalledVersion()220 ErrCode InnerSharedBundleInstaller::CheckBundleTypeWithInstalledVersion()
221 {
222     if (oldBundleInfo_.GetApplicationBundleType() != BundleType::SHARED) {
223         APP_LOGE("old bundle is not shared");
224         return ERR_APPEXECFWK_INSTALL_COMPATIBLE_POLICY_NOT_SAME;
225     }
226 
227     for (const auto &item : parsedBundles_) {
228         auto& sharedModules = item.second.GetInnerSharedModuleInfos();
229         if (sharedModules.empty() || sharedModules.begin()->second.empty()) {
230             APP_LOGW("inner shared module infos not found (%{public}s)", item.second.GetBundleName().c_str());
231             continue;
232         }
233 
234         auto& sharedModule = sharedModules.begin()->second.front();
235         BaseSharedBundleInfo installedSharedModule;
236         if (oldBundleInfo_.GetMaxVerBaseSharedBundleInfo(sharedModule.moduleName, installedSharedModule) &&
237             installedSharedModule.versionCode > sharedModule.versionCode) {
238             APP_LOGE("installing lower version shared package");
239             return ERR_APPEXECFWK_INSTALL_VERSION_DOWNGRADE;
240         }
241     }
242     return ERR_OK;
243 }
244 
MkdirIfNotExist(const std::string & dir)245 ErrCode InnerSharedBundleInstaller::MkdirIfNotExist(const std::string &dir)
246 {
247     bool isDirExist = false;
248     ErrCode result = InstalldClient::GetInstance()->IsExistDir(dir, isDirExist);
249     CHECK_RESULT(result, "check if dir exist failed %{public}d");
250     if (!isDirExist) {
251         result = InstalldClient::GetInstance()->CreateBundleDir(dir);
252         CHECK_RESULT(result, "create dir failed %{public}d");
253         createdDirs_.emplace_back(dir);
254     }
255     return result;
256 }
257 
ExtractSharedBundles(const std::string & bundlePath,InnerBundleInfo & newInfo)258 ErrCode InnerSharedBundleInstaller::ExtractSharedBundles(const std::string &bundlePath, InnerBundleInfo &newInfo)
259 {
260     ErrCode result = ERR_OK;
261     std::string bundleDir = Constants::BUNDLE_CODE_DIR + Constants::PATH_SEPARATOR + bundleName_;
262     result = MkdirIfNotExist(bundleDir);
263     CHECK_RESULT(result, "check bundle dir failed %{public}d");
264     newInfo.SetAppCodePath(bundleDir);
265 
266     uint32_t versionCode = newInfo.GetVersionCode();
267     std::string versionDir = bundleDir + Constants::PATH_SEPARATOR + HSP_VERSION_PREFIX + std::to_string(versionCode);
268     result = MkdirIfNotExist(versionDir);
269     CHECK_RESULT(result, "check version dir failed %{public}d");
270 
271     auto &moduleName = newInfo.GetInnerModuleInfos().begin()->second.moduleName;
272     std::string moduleDir = versionDir + Constants::PATH_SEPARATOR + moduleName;
273     result = MkdirIfNotExist(moduleDir);
274     CHECK_RESULT(result, "check module dir failed %{public}d");
275 
276     result = ProcessNativeLibrary(bundlePath, moduleDir, moduleName, versionDir, newInfo);
277     CHECK_RESULT(result, "ProcessNativeLibrary failed %{public}d");
278 
279     if (newInfo.IsPreInstallApp()) {
280         // preInstallApp does not need to copy hsp
281         newInfo.SetModuleHapPath(bundlePath);
282     } else {
283         // save hsp and so files to installation dir
284         std::string realHspPath = moduleDir + Constants::PATH_SEPARATOR + moduleName +
285             Constants::INSTALL_SHARED_FILE_SUFFIX;
286         result = SaveHspToRealInstallationDir(bundlePath, moduleDir, moduleName, realHspPath);
287         CHECK_RESULT(result, "save hsp file failed %{public}d");
288         newInfo.SetModuleHapPath(realHspPath);
289     }
290     newInfo.AddModuleSrcDir(moduleDir);
291     newInfo.AddModuleResPath(moduleDir);
292     newInfo.UpdateSharedModuleInfo();
293     return ERR_OK;
294 }
295 
MergeBundleInfos()296 void InnerSharedBundleInstaller::MergeBundleInfos()
297 {
298     auto iter = parsedBundles_.begin();
299     if (isBundleExist_) {
300         newBundleInfo_ = oldBundleInfo_;
301     } else {
302         newBundleInfo_ = iter->second;
303         ++iter;
304     }
305 
306     for (; iter != parsedBundles_.end(); ++iter) {
307         const auto &currentBundle = iter->second;
308         const auto& infos = currentBundle.GetInnerSharedModuleInfos();
309         if (infos.empty()) {
310             continue;
311         }
312 
313         const auto& innerModuleInfos = infos.begin()->second;
314         if (!innerModuleInfos.empty()) {
315             const auto& innerModuleInfo = innerModuleInfos.front();
316             newBundleInfo_.InsertInnerSharedModuleInfo(innerModuleInfo.modulePackage, innerModuleInfo);
317         }
318         // update version
319         if (newBundleInfo_.GetBaseBundleInfo().versionCode < currentBundle.GetBaseBundleInfo().versionCode) {
320             newBundleInfo_.UpdateBaseBundleInfo(currentBundle.GetBaseBundleInfo(), false);
321             newBundleInfo_.UpdateBaseApplicationInfo(currentBundle.GetBaseApplicationInfo(), false);
322         }
323     }
324 
325     newBundleInfo_.SetBundleStatus(InnerBundleInfo::BundleStatus::ENABLED);
326     newBundleInfo_.SetHideDesktopIcon(true);
327 }
328 
SavePreInstallInfo(const InstallParam & installParam)329 ErrCode InnerSharedBundleInstaller::SavePreInstallInfo(const InstallParam &installParam)
330 {
331     if (!installParam.needSavePreInstallInfo) {
332         APP_LOGD("no need to save pre install info");
333         return ERR_OK;
334     }
335 
336     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
337     if (dataMgr == nullptr) {
338         APP_LOGE("get dataMgr failed");
339         return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
340     }
341 
342     PreInstallBundleInfo preInstallBundleInfo;
343     dataMgr->GetPreInstallBundleInfo(bundleName_, preInstallBundleInfo);
344     preInstallBundleInfo.SetVersionCode(newBundleInfo_.GetBaseBundleInfo().versionCode);
345     for (const auto &item : parsedBundles_) {
346         preInstallBundleInfo.AddBundlePath(item.first);
347     }
348 #ifdef USE_PRE_BUNDLE_PROFILE
349     preInstallBundleInfo.SetRemovable(installParam.removable);
350 #else
351     preInstallBundleInfo.SetRemovable(newBundleInfo_.IsRemovable());
352 #endif
353     dataMgr->SavePreInstallBundleInfo(bundleName_, preInstallBundleInfo);
354 
355     return ERR_OK;
356 }
357 
SaveBundleInfoToStorage()358 ErrCode InnerSharedBundleInstaller::SaveBundleInfoToStorage()
359 {
360     // update install mark
361     std::string packageName;
362     newBundleInfo_.SetInstallMark(bundleName_, packageName, InstallExceptionStatus::INSTALL_FINISH);
363 
364     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
365     if (dataMgr == nullptr) {
366         APP_LOGE("get dataMgr failed");
367         return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
368     }
369 
370     if (isBundleExist_) {
371         if (!dataMgr->UpdateInnerBundleInfo(newBundleInfo_)) {
372             APP_LOGE("save bundle failed : %{public}s", bundleName_.c_str());
373             return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
374         }
375         return ERR_OK;
376     }
377 
378     dataMgr->UpdateBundleInstallState(bundleName_, InstallState::INSTALL_START);
379     if (!dataMgr->AddInnerBundleInfo(bundleName_, newBundleInfo_)) {
380         dataMgr->UpdateBundleInstallState(bundleName_, InstallState::INSTALL_FAIL);
381         APP_LOGE("save bundle failed : %{public}s", bundleName_.c_str());
382         return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
383     }
384     dataMgr->UpdateBundleInstallState(bundleName_, InstallState::INSTALL_SUCCESS);
385     return ERR_OK;
386 }
387 
GetInstallEventInfo(EventInfo & eventInfo) const388 void InnerSharedBundleInstaller::GetInstallEventInfo(EventInfo &eventInfo) const
389 {
390     APP_LOGD("GetInstallEventInfo start, bundleName:%{public}s", bundleName_.c_str());
391     eventInfo.fingerprint = newBundleInfo_.GetCertificateFingerprint();
392     eventInfo.appDistributionType = newBundleInfo_.GetAppDistributionType();
393     eventInfo.hideDesktopIcon = newBundleInfo_.IsHideDesktopIcon();
394     eventInfo.timeStamp = BundleUtil::GetCurrentTimeMs();
395 
396     // report hapPath and hashValue
397     for (const auto &info : parsedBundles_) {
398         for (const auto &innerModuleInfo : info.second.GetInnerModuleInfos()) {
399             eventInfo.filePath.push_back(innerModuleInfo.second.hapPath);
400             eventInfo.hashValue.push_back(innerModuleInfo.second.hashValue);
401         }
402     }
403 }
404 
AddAppProvisionInfo(const std::string & bundleName,const Security::Verify::ProvisionInfo & provisionInfo) const405 void InnerSharedBundleInstaller::AddAppProvisionInfo(const std::string &bundleName,
406     const Security::Verify::ProvisionInfo &provisionInfo) const
407 {
408     AppProvisionInfo appProvisionInfo = bundleInstallChecker_->ConvertToAppProvisionInfo(provisionInfo);
409     if (!DelayedSingleton<AppProvisionInfoManager>::GetInstance()->AddAppProvisionInfo(
410         bundleName, appProvisionInfo)) {
411         APP_LOGW("bundleName: %{public}s add appProvisionInfo failed.", bundleName.c_str());
412     }
413 }
414 
SaveInstallParamInfo(const std::string & bundleName,const InstallParam & installParam) const415 void InnerSharedBundleInstaller::SaveInstallParamInfo(
416     const std::string &bundleName, const InstallParam &installParam) const
417 {
418     if (!installParam.specifiedDistributionType.empty()) {
419         if (!DelayedSingleton<AppProvisionInfoManager>::GetInstance()->SetSpecifiedDistributionType(
420             bundleName, installParam.specifiedDistributionType)) {
421             APP_LOGW("bundleName: %{public}s SetSpecifiedDistributionType failed.", bundleName.c_str());
422         }
423     }
424     if (!installParam.additionalInfo.empty()) {
425         if (!DelayedSingleton<AppProvisionInfoManager>::GetInstance()->SetAdditionalInfo(
426             bundleName, installParam.additionalInfo)) {
427             APP_LOGW("bundleName: %{public}s SetAdditionalInfo failed.", bundleName.c_str());
428         }
429     }
430 }
431 
CopyHspToSecurityDir(std::vector<std::string> & bundlePaths)432 ErrCode InnerSharedBundleInstaller::CopyHspToSecurityDir(std::vector<std::string> &bundlePaths)
433 {
434     for (size_t index = 0; index < bundlePaths.size(); ++index) {
435         auto destination = BundleUtil::CopyFileToSecurityDir(bundlePaths[index], DirType::STREAM_INSTALL_DIR,
436             toDeleteTempHspPath_);
437         if (destination.empty()) {
438             APP_LOGE("copy file %{public}s to security dir failed", bundlePaths[index].c_str());
439             return ERR_APPEXECFWK_INSTALL_COPY_HAP_FAILED;
440         }
441         bundlePaths[index] = destination;
442     }
443     return ERR_OK;
444 }
445 
ObtainHspFileAndSignatureFilePath(const std::vector<std::string> & inBundlePaths,std::vector<std::string> & bundlePaths,std::string & signatureFilePath)446 ErrCode InnerSharedBundleInstaller::ObtainHspFileAndSignatureFilePath(const std::vector<std::string> &inBundlePaths,
447     std::vector<std::string> &bundlePaths, std::string &signatureFilePath)
448 {
449     if (inBundlePaths.empty() || inBundlePaths.size() > MAX_FILE_NUMBER) {
450         APP_LOGE("number of files in single shared lib path is illegal");
451         return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
452     }
453     if (inBundlePaths.size() == 1) {
454         if (!BundleUtil::EndWith(inBundlePaths[0], Constants::INSTALL_SHARED_FILE_SUFFIX)) {
455             APP_LOGE("invalid file in shared bundle dir");
456             return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
457         }
458         bundlePaths.emplace_back(inBundlePaths[0]);
459         return ERR_OK;
460     }
461     int32_t numberOfHsp = 0;
462     int32_t numberOfSignatureFile = 0;
463     for (const auto &path : inBundlePaths) {
464         if ((path.find(Constants::INSTALL_SHARED_FILE_SUFFIX) == std::string::npos) &&
465             (path.find(Constants::CODE_SIGNATURE_FILE_SUFFIX) == std::string::npos)) {
466             APP_LOGE("only hsp or sig file can be contained in shared bundle dir");
467             return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
468         }
469         if (BundleUtil::EndWith(path, Constants::INSTALL_SHARED_FILE_SUFFIX)) {
470             numberOfHsp++;
471             bundlePaths.emplace_back(path);
472         }
473         if (BundleUtil::EndWith(path, Constants::CODE_SIGNATURE_FILE_SUFFIX)) {
474             numberOfSignatureFile++;
475             signatureFilePath = path;
476         }
477         if ((numberOfHsp >= MAX_FILE_NUMBER) || (numberOfSignatureFile >= MAX_FILE_NUMBER)) {
478             APP_LOGE("only one hsp and one signature file can be contained in a single shared bundle dir");
479             return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
480         }
481     }
482     APP_LOGD("signatureFilePath is %{public}s", signatureFilePath.c_str());
483     return ERR_OK;
484 }
485 
SaveHspToRealInstallationDir(const std::string & bundlePath,const std::string & moduleDir,const std::string & moduleName,const std::string & realHspPath)486 ErrCode InnerSharedBundleInstaller::SaveHspToRealInstallationDir(const std::string &bundlePath,
487     const std::string &moduleDir,
488     const std::string &moduleName,
489     const std::string &realHspPath)
490 {
491     // 1. create temp dir
492     ErrCode result = ERR_OK;
493     std::string tempHspDir = moduleDir + Constants::PATH_SEPARATOR + moduleName;
494     result = MkdirIfNotExist(tempHspDir);
495     CHECK_RESULT(result, "create tempHspDir dir failed %{public}d");
496 
497     // 2. copy hsp to installation dir, and then to verify code signature of hsp
498     std::string tempHspPath = tempHspDir + Constants::PATH_SEPARATOR + moduleName +
499         Constants::INSTALL_SHARED_FILE_SUFFIX;
500     result = InstalldClient::GetInstance()->CopyFile(bundlePath, tempHspPath, signatureFileDir_);
501     CHECK_RESULT(result, "copy hsp to install dir failed %{public}d");
502 
503     // 3. move hsp to real installation dir
504     APP_LOGD("move file from temp path %{public}s to real path %{public}s", tempHspPath.c_str(), realHspPath.c_str());
505     result = InstalldClient::GetInstance()->MoveFile(tempHspPath, realHspPath);
506     CHECK_RESULT(result, "move hsp to install dir failed %{public}d");
507 
508     // 4. remove temp dir
509     result = InstalldClient::GetInstance()->RemoveDir(tempHspDir);
510     if (result != ERR_OK) {
511         APP_LOGW("remove temp hsp dir %{public}s failed, error is %{public}d", tempHspDir.c_str(), result);
512     }
513     return ERR_OK;
514 }
515 
MoveSoToRealPath(const std::string & moduleName,const std::string & versionDir)516 ErrCode InnerSharedBundleInstaller::MoveSoToRealPath(const std::string &moduleName, const std::string &versionDir)
517 {
518     // 1. move so files to real installation dir
519     std::string realSoPath = versionDir + Constants::PATH_SEPARATOR + nativeLibraryPath_ +
520         Constants::PATH_SEPARATOR;
521     ErrCode result = MkdirIfNotExist(realSoPath);
522     CHECK_RESULT(result, "check module dir failed %{public}d");
523 
524     std::string tempNativeLibraryPath = ObtainTempSoPath(moduleName, nativeLibraryPath_);
525     if (tempNativeLibraryPath.empty()) {
526         APP_LOGI("no so libs existed");
527         return ERR_OK;
528     }
529     std::string tempSoPath = versionDir + Constants::PATH_SEPARATOR + tempNativeLibraryPath;
530     APP_LOGD("move so files from path %{public}s to path %{public}s", tempSoPath.c_str(), realSoPath.c_str());
531     result = InstalldClient::GetInstance()->MoveFiles(tempSoPath, realSoPath);
532     if (result != ERR_OK) {
533         APP_LOGE("move file to real path failed %{public}d", result);
534         return ERR_APPEXECFWK_INSTALLD_MOVE_FILE_FAILED;
535     }
536 
537     // 2. remove so temp dir
538     std::string deleteTempDir = versionDir + Constants::PATH_SEPARATOR + moduleName + Constants::TMP_SUFFIX;
539     result = InstalldClient::GetInstance()->RemoveDir(deleteTempDir);
540     if (result != ERR_OK) {
541         APP_LOGW("remove hsp temp so dir %{public}s failed, error is %{public}d", deleteTempDir.c_str(), result);
542     }
543     return ERR_OK;
544 }
545 
ObtainTempSoPath(const std::string & moduleName,const std::string & nativeLibPath)546 std::string InnerSharedBundleInstaller::ObtainTempSoPath(const std::string &moduleName,
547     const std::string &nativeLibPath)
548 {
549     std::string tempSoPath;
550     if (nativeLibPath.empty()) {
551         APP_LOGE("invalid native libs path");
552         return tempSoPath;
553     }
554     tempSoPath = nativeLibPath;
555     auto pos = tempSoPath.find(moduleName);
556     if (pos == std::string::npos) {
557         tempSoPath = moduleName + Constants::TMP_SUFFIX + Constants::PATH_SEPARATOR + tempSoPath;
558     } else {
559         std::string innerTempStr = moduleName + Constants::TMP_SUFFIX;
560         tempSoPath.replace(pos, moduleName.length(), innerTempStr);
561     }
562     return tempSoPath + Constants::PATH_SEPARATOR;
563 }
564 
ProcessNativeLibrary(const std::string & bundlePath,const std::string & moduleDir,const std::string & moduleName,const std::string & versionDir,InnerBundleInfo & newInfo)565 ErrCode InnerSharedBundleInstaller::ProcessNativeLibrary(
566     const std::string &bundlePath,
567     const std::string &moduleDir,
568     const std::string &moduleName,
569     const std::string &versionDir,
570     InnerBundleInfo &newInfo)
571 {
572     std::string cpuAbi;
573     if (!newInfo.FetchNativeSoAttrs(moduleName, cpuAbi, nativeLibraryPath_)) {
574         return ERR_OK;
575     }
576     if (newInfo.IsCompressNativeLibs(moduleName)) {
577         std::string tempNativeLibraryPath = ObtainTempSoPath(moduleName, nativeLibraryPath_);
578         if (tempNativeLibraryPath.empty()) {
579             return ERR_APPEXECFWK_INSTALLD_EXTRACT_FILES_FAILED;
580         }
581         std::string tempSoPath = versionDir + Constants::PATH_SEPARATOR + tempNativeLibraryPath;
582         APP_LOGD("tempSoPath=%{public}s,cpuAbi=%{public}s, bundlePath=%{public}s",
583             tempSoPath.c_str(), cpuAbi.c_str(), bundlePath.c_str());
584         auto result = InstalldClient::GetInstance()->ExtractModuleFiles(bundlePath, moduleDir, tempSoPath, cpuAbi);
585         CHECK_RESULT(result, "extract module files failed %{public}d");
586         // verify hap or hsp code signature for compressed so files
587         result = InstalldClient::GetInstance()->VerifyCodeSignature(bundlePath, cpuAbi, tempSoPath,
588             signatureFileDir_);
589         CHECK_RESULT(result, "fail to VerifyCodeSignature, error is %{public}d");
590         // move so to real path
591         result = MoveSoToRealPath(moduleName, versionDir);
592         CHECK_RESULT(result, "move so to real path failed %{public}d");
593     } else {
594         std::vector<std::string> fileNames;
595         auto result = InstalldClient::GetInstance()->GetNativeLibraryFileNames(bundlePath, cpuAbi, fileNames);
596         CHECK_RESULT(result, "fail to GetNativeLibraryFileNames, error is %{public}d");
597         newInfo.SetNativeLibraryFileNames(moduleName, fileNames);
598     }
599     return ERR_OK;
600 }
601 }  // namespace AppExecFwk
602 }  // namespace OHOS
603