• 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 "module_file_repository.h"
17 
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 
22 #include "directory_ex.h"
23 #include "log/log.h"
24 #include "module_constants.h"
25 #include "module_utils.h"
26 #include "module_error_code.h"
27 #include "scope_guard.h"
28 #include "unique_fd.h"
29 
30 namespace OHOS {
31 namespace SysInstaller {
32 using namespace Updater;
33 using std::string;
34 
~ModuleFileRepository()35 ModuleFileRepository::~ModuleFileRepository()
36 {
37     Clear();
38 }
39 
GetInstance()40 ModuleFileRepository &ModuleFileRepository::GetInstance()
41 {
42     static ModuleFileRepository instance;
43     return instance;
44 }
45 
InitRepository(const std::unordered_set<int32_t> & saIdSet)46 void ModuleFileRepository::InitRepository(const std::unordered_set<int32_t> &saIdSet)
47 {
48     string allPath[] = {MODULE_PREINSTALL_DIR, UPDATE_INSTALL_DIR, UPDATE_ACTIVE_DIR};
49     for (string &path : allPath) {
50         std::vector<string> files;
51         GetDirFiles(path, files);
52         std::unordered_map<int32_t, ModuleFile> fileMap;
53         for (string &file : files) {
54             ProcessFile(saIdSet, path, file, fileMap);
55         }
56         moduleFileMap_.emplace(path, std::move(fileMap));
57     }
58 }
59 
SaveInstallerResult(const std::string & path,const std::string & hmpName,int result,const std::string & resultInfo) const60 void ModuleFileRepository::SaveInstallerResult(const std::string &path, const std::string &hmpName,
61     int result, const std::string &resultInfo) const
62 {
63     if (path.find(UPDATE_INSTALL_DIR) == std::string::npos && path.find(UPDATE_ACTIVE_DIR) == std::string::npos) {
64         return;
65     }
66     if (!CheckFileSuffix(path, MODULE_PACKAGE_SUFFIX)) {
67         return;
68     }
69     if (!CheckPathExists(MODULE_RESULT_PATH)) {
70         LOG(ERROR) << MODULE_RESULT_PATH << " not exist";
71         return;
72     }
73     LOG(INFO) << "path:" << path << "hmp:" << hmpName << "result:" << result << "Info:" << resultInfo << "\n";
74 
75     UniqueFd fd(open(MODULE_RESULT_PATH, O_APPEND | O_RDWR | O_CLOEXEC));
76     if (fd.Get() == -1) {
77         LOG(ERROR) << "Failed to open file";
78         return;
79     }
80 
81     std::string writeInfo = hmpName + ";" + std::to_string(result) + ";" + resultInfo + "\n";
82     if (write(fd, writeInfo.data(), writeInfo.length()) <= 0) {
83         LOG(WARNING) << "write result file failed, err:" << errno;
84     }
85     fsync(fd.Get());
86 }
87 
ProcessFile(const std::unordered_set<int32_t> & saIdSet,const string & path,const string & file,std::unordered_map<int32_t,ModuleFile> & fileMap) const88 void ModuleFileRepository::ProcessFile(const std::unordered_set<int32_t> &saIdSet, const string &path,
89     const string &file, std::unordered_map<int32_t, ModuleFile> &fileMap) const
90 {
91     if (!CheckFileSuffix(file, MODULE_PACKAGE_SUFFIX)) {
92         return;
93     }
94     std::unique_ptr<ModuleFile> moduleFile = ModuleFile::Open(file);
95     if (moduleFile == nullptr || saIdSet.find(moduleFile->GetSaId()) == saIdSet.end()) {
96         return;
97     }
98     string pubkey = moduleFile->GetPublicKey();
99     if (path != MODULE_PREINSTALL_DIR) {
100         pubkey = GetPublicKey(moduleFile->GetSaId());
101         if (!CheckFilePath(*moduleFile, path)) {
102             LOG(ERROR) << "Open " << file << " failed";
103             SaveInstallerResult(path, GetHmpName(moduleFile->GetPath()),
104                 ModuleErrorCode::ERR_VERIFY_SIGN_FAIL, "get pub key fail");
105             return;
106         }
107         if (VerifyModulePackageSign(file) != 0) {
108             LOG(ERROR) << "VerifyModulePackageSign failed of " << file;
109             SaveInstallerResult(path, GetHmpName(moduleFile->GetPath()),
110                 ModuleErrorCode::ERR_VERIFY_SIGN_FAIL, "verify fail");
111             return;
112         }
113     }
114     if (moduleFile->GetImageStat().has_value() && !moduleFile->VerifyModuleVerity(pubkey)) {
115         SaveInstallerResult(path, GetHmpName(moduleFile->GetPath()),
116             ModuleErrorCode::ERR_VERIFY_SIGN_FAIL, "hvb fail");
117         LOG(ERROR) << "verify verity failed of " << file;
118         return;
119     }
120     LOG(INFO) << "ProcessFile  " << file << " successful";
121     fileMap.emplace(moduleFile->GetSaId(), std::move(*moduleFile));
122 }
123 
GetModuleFile(const std::string & pathPrefix,const int32_t saId) const124 std::unique_ptr<ModuleFile> ModuleFileRepository::GetModuleFile(const std::string &pathPrefix, const int32_t saId) const
125 {
126     auto mapIter = moduleFileMap_.find(pathPrefix);
127     if (mapIter == moduleFileMap_.end()) {
128         LOG(ERROR) << "Invalid path prefix " << pathPrefix;
129         return nullptr;
130     }
131     std::unordered_map<int32_t, ModuleFile> fileMap = mapIter->second;
132     auto fileIter = fileMap.find(saId);
133     if (fileIter == fileMap.end()) {
134         LOG(INFO) << saId << " not found in " << pathPrefix;
135         return nullptr;
136     }
137     ModuleFile file = fileIter->second;
138     return std::make_unique<ModuleFile>(std::move(file));
139 }
140 
IsPreInstalledModule(const ModuleFile & moduleFile) const141 bool ModuleFileRepository::IsPreInstalledModule(const ModuleFile &moduleFile) const
142 {
143     std::unique_ptr<ModuleFile> preInstalledModule = GetModuleFile(MODULE_PREINSTALL_DIR, moduleFile.GetSaId());
144     if (preInstalledModule == nullptr) {
145         return false;
146     }
147     return preInstalledModule->GetPath() == moduleFile.GetPath();
148 }
149 
GetPublicKey(const int32_t saId) const150 string ModuleFileRepository::GetPublicKey(const int32_t saId) const
151 {
152     std::unique_ptr<ModuleFile> preInstalledModule = GetModuleFile(MODULE_PREINSTALL_DIR, saId);
153     if (preInstalledModule == nullptr) {
154         return "";
155     }
156     return preInstalledModule->GetPublicKey();
157 }
158 
CheckFilePath(const ModuleFile & moduleFile,const string & prefix) const159 bool ModuleFileRepository::CheckFilePath(const ModuleFile &moduleFile, const string &prefix) const
160 {
161     std::unique_ptr<ModuleFile> preInstalledModule = GetModuleFile(MODULE_PREINSTALL_DIR, moduleFile.GetSaId());
162     if (preInstalledModule == nullptr) {
163         return false;
164     }
165     string prePath = preInstalledModule->GetPath();
166     string curPath = moduleFile.GetPath();
167     return prePath.substr(strlen(MODULE_PREINSTALL_DIR), prePath.length()) ==
168         curPath.substr(prefix.length(), curPath.length());
169 }
170 
Clear()171 void ModuleFileRepository::Clear()
172 {
173     for (auto mapIter = moduleFileMap_.begin(); mapIter != moduleFileMap_.end(); ++mapIter) {
174         std::unordered_map<int32_t, ModuleFile> &fileMap = mapIter->second;
175         for (auto fileIter = fileMap.begin(); fileIter != fileMap.end(); ++fileIter) {
176             fileIter->second.ClearVerifiedData();
177         }
178         fileMap.clear();
179     }
180     moduleFileMap_.clear();
181 }
182 } // SysInstaller
183 } // namespace OHOS
184