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.h"
17
18 #include <dlfcn.h>
19 #include <fcntl.h>
20 #include <sys/stat.h>
21 #include <unistd.h>
22 #include <unordered_set>
23
24 #include "directory_ex.h"
25 #include "module_utils.h"
26 #include "json_node.h"
27 #include "log/log.h"
28 #include "module_constants.h"
29 #include "module_zip_helper.h"
30 #include "package/package.h"
31 #include "scope_guard.h"
32 #include "securec.h"
33 #include "string_ex.h"
34 #include "unique_fd.h"
35 #include "utils.h"
36
37 #ifdef SUPPORT_HVB
38 #include "hvb.h"
39 #include "hvb_footer.h"
40 #include "module_hvb_ops.h"
41 #include "module_hvb_utils.h"
42 #endif
43
44 namespace OHOS {
45 namespace SysInstaller {
46 using namespace Updater;
47 using std::string;
48
49 namespace {
50 constexpr const char *VERSION_DELIMITER = ".";
51 constexpr size_t API_VERSION_INDEX = 0;
52 constexpr size_t VERSION_CODE_INDEX = 1;
53 constexpr size_t PATCH_VERSION_INDEX = 2;
54 constexpr size_t VERSION_VECTOR_SIZE = 3;
55 constexpr size_t PACKINFO_VERSION_VECTOR_SIZE = 5;
56 constexpr size_t HMP_VERSION_TYPE_NUM = 4;
57 constexpr size_t SA_SDK_VERSION_TYPE_NUM = 3;
58
59 struct FsMagic {
60 const char *type;
61 int32_t offset;
62 int16_t len;
63 const char *magic;
64 };
65 constexpr const FsMagic FS_TYPES[] = {{"f2fs", 1024, 4, "\x10\x20\xF5\xF2"},
66 {"ext4", 1080, 2, "\x53\xEF"}};
67
RetrieveFsType(int fd,uint32_t imageOffset)68 const char *RetrieveFsType(int fd, uint32_t imageOffset)
69 {
70 for (const auto &fs : FS_TYPES) {
71 uint8_t buf[fs.len];
72 if (!ReadFullyAtOffset(fd, buf, fs.len, imageOffset + fs.offset)) {
73 LOG(ERROR) << "Couldn't read filesystem magic";
74 return nullptr;
75 }
76 if (memcmp(buf, fs.magic, fs.len) == 0) {
77 return fs.type;
78 }
79 }
80 LOG(ERROR) << "Couldn't find filesystem magic";
81 return nullptr;
82 }
83
ParseImageStat(const string & fpInfo,ImageStat & imageStat)84 bool ParseImageStat(const string &fpInfo, ImageStat &imageStat)
85 {
86 string realPath = GetRealPath(fpInfo);
87 if (realPath.empty() || !Utils::IsFileExist(realPath)) {
88 LOG(ERROR) << "Invalid path " << fpInfo;
89 return false;
90 }
91 struct stat buffer;
92 if (stat(realPath.c_str(), &buffer) != 0) {
93 LOG(ERROR) << "stat file " << fpInfo << " failed.";
94 return false;
95 }
96 imageStat.imageOffset = 0;
97 imageStat.imageSize = static_cast<uint32_t>(buffer.st_size);
98
99 UniqueFd fd(open(realPath.c_str(), O_RDONLY | O_CLOEXEC));
100 if (fd.Get() == -1) {
101 LOG(ERROR) << "Failed to open package " << fpInfo << ": I/O error";
102 return false;
103 }
104 const char *fsTypePtr = RetrieveFsType(fd.Get(), imageStat.imageOffset);
105 if (fsTypePtr == nullptr) {
106 LOG(ERROR) << "Failed to get fs type " << fpInfo;
107 return false;
108 }
109 errno_t ret = strcpy_s(imageStat.fsType, FS_TYPE_MAX_SIZE, fsTypePtr);
110 if (ret != EOK) {
111 LOG(ERROR) << "Failed to copy fs type " << fsTypePtr;
112 return false;
113 }
114 return true;
115 }
116
ParseHmpVersionInfo(const JsonNode & package,ModulePackageInfo & versionInfo)117 bool ParseHmpVersionInfo(const JsonNode &package, ModulePackageInfo &versionInfo)
118 {
119 std::optional<string> name = package["name"].As<string>();
120 if (!name.has_value()) {
121 LOG(ERROR) << "Hmpinfo: Failed to get hmp name val";
122 return false;
123 }
124 std::optional<string> version = package["version"].As<string>();
125 if (!version.has_value()) {
126 LOG(ERROR) << "Hmpinfo: Failed to get hmp version val";
127 return false;
128 }
129 std::optional<string> displayVersion = package["displayVersion"].As<string>();
130 if (!displayVersion.has_value()) {
131 LOG(ERROR) << "Hmpinfo: Failed to get hmp display version val";
132 return false;
133 }
134 versionInfo.hmpName = name.value();
135 versionInfo.version = version.value();
136 versionInfo.displayVersion = displayVersion.value();
137
138 if (versionInfo.type != HMP_SA_TYPE && versionInfo.type != HMP_SA_TYPE_OLD) {
139 std::optional<string> apiVersion = package[HMP_API_VERSION].As<string>();
140 if (!apiVersion.has_value()) {
141 LOG(ERROR) << "Hmpinfo: Failed to get apiVersion val";
142 return false;
143 }
144 versionInfo.apiVersion = Utils::String2Int<int>(apiVersion.value(), Utils::N_DEC);
145 } else if (versionInfo.type != HMP_APP_TYPE) {
146 std::optional<string> saSdkVersion = package[HMP_SA_SDK_VERSION].As<string>();
147 if (!saSdkVersion.has_value()) {
148 LOG(ERROR) << "Hmpinfo: Failed to get saSdkVersion val";
149 return false;
150 }
151 }
152 return true;
153 }
154
ParseSaVersion(const string & versionStr,SaInfo & info)155 bool ParseSaVersion(const string &versionStr, SaInfo &info)
156 {
157 std::vector<string> versionVec;
158 SplitStr(versionStr, VERSION_DELIMITER, versionVec);
159 if (versionVec.size() != VERSION_VECTOR_SIZE) {
160 LOG(ERROR) << "SaVersion: Invalid version: " << versionStr;
161 return false;
162 }
163 if (!Utils::ConvertToUnsignedLong(versionVec.at(API_VERSION_INDEX), info.version.apiVersion) ||
164 !Utils::ConvertToUnsignedLong(versionVec.at(VERSION_CODE_INDEX), info.version.versionCode) ||
165 !Utils::ConvertToUnsignedLong(versionVec.at(PATCH_VERSION_INDEX), info.version.patchVersion)) {
166 LOG(ERROR) << "ConvertToUnsignedLong failed";
167 return false;
168 }
169 return true;
170 }
171
ParseSaList(const JsonNode & package,ModuleInfo & versionInfo)172 bool ParseSaList(const JsonNode &package, ModuleInfo &versionInfo)
173 {
174 const auto &saListJson = package["saList"];
175 for (const auto &saInfo : saListJson) {
176 std::optional<string> saInfoStr = saInfo.get().As<string>();
177 if (!saInfoStr.has_value()) {
178 LOG(ERROR) << "SaList: Failed to get saInfoStr val";
179 return false;
180 }
181 std::vector<string> saInfoVec;
182 SplitStr(saInfoStr.value(), " ", saInfoVec);
183 if (saInfoVec.size() != 3) { // 3: name id version
184 LOG(ERROR) << "SaList: Invalid saInfoStr: " << saInfoStr.value();
185 return false;
186 }
187 SaInfo &infoTmp = versionInfo.saInfoList.emplace_back();
188 infoTmp.saName = saInfoVec.at(0); // 0:index of name
189 if (!Utils::ConvertToLong(saInfoVec.at(1), infoTmp.saId)) { // 1: index of saId
190 LOG(ERROR) << "ConvertToLong failed";
191 return false;
192 }
193 if (!ParseSaVersion(saInfoVec.at(2), infoTmp)) { // 2:index of version
194 return false;
195 }
196 }
197 return true;
198 }
199
ParseBundleList(const JsonNode & package,ModuleInfo & versionInfo)200 bool ParseBundleList(const JsonNode &package, ModuleInfo &versionInfo)
201 {
202 const auto &bundleListJson = package["bundleList"];
203 for (const auto &bundleInfo : bundleListJson) {
204 const auto &bundleInfoStr = bundleInfo.get().Key();
205 if (!bundleInfoStr.has_value()) {
206 LOG(ERROR) << "BundleList: Failed to get bundleInfo val";
207 return false;
208 }
209 std::vector<string> bundleInfoVec;
210 SplitStr(bundleInfoStr.value(), " ", bundleInfoVec);
211 if (bundleInfoVec.size() != 2) { // 2: name version
212 LOG(ERROR) << "BundleList: Invalid bundleInfoStr: " << bundleInfoStr.value();
213 return false;
214 }
215 BundleInfo &infoTmp = versionInfo.bundleInfoList.emplace_back();
216 infoTmp.bundleName = bundleInfoVec.at(0); // 0:index of bundleName
217 infoTmp.bundleVersion = bundleInfoVec.at(1); // 1:index of bundleVersion
218 }
219 return true;
220 }
221
ParseTrainInfo(const JsonNode & package,ModulePackageInfo & versionInfo)222 bool ParseTrainInfo(const JsonNode &package, ModulePackageInfo &versionInfo)
223 {
224 const auto &moduleList = package[HMP_MODULE_INFO];
225
226 for (const auto &moduleInfo : moduleList) {
227 ModuleInfo infoTmp;
228 const JsonNode &modulePackage = moduleInfo.get()["package"];
229 std::optional<string> name = modulePackage["name"].As<string>();
230 if (!name.has_value()) {
231 LOG(ERROR) << "Hmpinfo: Failed to get name val";
232 return false;
233 }
234 if (!ParseSaList(modulePackage, infoTmp)) {
235 return false;
236 }
237 if (!ParseBundleList(modulePackage, infoTmp)) {
238 return false;
239 }
240 versionInfo.moduleMap.emplace(name.value(), std::move(infoTmp));
241 }
242 return true;
243 }
244
ParseModuleInfo(const string & packInfo,ModulePackageInfo & versionInfo)245 bool ParseModuleInfo(const string &packInfo, ModulePackageInfo &versionInfo)
246 {
247 JsonNode root(packInfo);
248 const JsonNode &type = root["type"];
249 std::optional<string> hmpType = type.As<string>();
250 if (!hmpType.has_value()) {
251 LOG(ERROR) << "HmpInfo: Failed to get type val";
252 return false;
253 }
254 versionInfo.type = hmpType.value();
255
256 const JsonNode &package = root["package"];
257 if (!ParseHmpVersionInfo(package, versionInfo)) {
258 return false;
259 }
260
261 if (versionInfo.type == HMP_TRAIN_TYPE) {
262 return ParseTrainInfo(package, versionInfo);
263 }
264 ModuleInfo infoTmp;
265 // parse sa info
266 if (versionInfo.type == HMP_SA_TYPE || versionInfo.type == HMP_SA_TYPE_OLD ||
267 versionInfo.type == HMP_MIX_TYPE) {
268 if (!ParseSaList(package, infoTmp)) {
269 return false;
270 }
271 }
272 // parse bundle info
273 if (versionInfo.type == HMP_APP_TYPE || versionInfo.type == HMP_MIX_TYPE) {
274 if (!ParseBundleList(package, infoTmp)) {
275 return false;
276 }
277 }
278 versionInfo.moduleMap.emplace(versionInfo.hmpName, std::move(infoTmp));
279 return true;
280 }
281
282 // avp a= v>= p>=
CompareSaVersion(const SaVersion & smaller,const SaVersion & bigger)283 bool CompareSaVersion(const SaVersion &smaller, const SaVersion &bigger)
284 {
285 if (smaller.apiVersion != bigger.apiVersion) {
286 return false;
287 }
288 if (smaller.versionCode > bigger.versionCode) {
289 return false;
290 }
291 if (smaller.versionCode < bigger.versionCode) {
292 return true;
293 }
294 return bigger.patchVersion >= smaller.patchVersion;
295 }
296
CompareSaListVersion(const std::list<SaInfo> & smallList,const std::list<SaInfo> & bigList)297 bool CompareSaListVersion(const std::list<SaInfo> &smallList, const std::list<SaInfo> &bigList)
298 {
299 if (smallList.size() != bigList.size()) {
300 LOG(ERROR) << "smallList size: " << smallList.size() << " not equal to big: " << bigList.size();
301 return false;
302 }
303 std::unordered_map<int32_t, SaInfo> saMap {};
304 for (const auto &info : bigList) {
305 saMap.emplace(info.saId, info);
306 }
307 for (const auto &info : smallList) {
308 auto saIter = saMap.find(info.saId);
309 if (saIter == saMap.end()) {
310 LOG(ERROR) << info.saId << "not found when compare saList";
311 return false;
312 }
313 if (!CompareSaVersion(info.version, saIter->second.version)) {
314 return false;
315 }
316 }
317 return true;
318 }
319
CompareBundleList(const std::list<BundleInfo> & smallList,const std::list<BundleInfo> & bigList)320 bool CompareBundleList(const std::list<BundleInfo> &smallList, const std::list<BundleInfo> &bigList)
321 {
322 if (smallList.size() != bigList.size()) {
323 LOG(ERROR) << "Bundle smallList size: " << smallList.size() << " not equal to big: " << bigList.size();
324 return false;
325 }
326 std::unordered_set<std::string> bundleSet {};
327 for (const auto &info : bigList) {
328 bundleSet.insert(info.bundleName);
329 }
330 for (const auto &info : smallList) {
331 auto bundleIter = bundleSet.find(info.bundleName);
332 if (bundleIter == bundleSet.end()) {
333 LOG(ERROR) << info.bundleName << " not found when compare bundleList";
334 return false;
335 }
336 }
337 return true;
338 }
339 } // namespace
340
ExtractZipFile(ModuleZipHelper & helper,const string & fpInfo,string & buf)341 bool ExtractZipFile(ModuleZipHelper &helper, const string &fpInfo, string &buf)
342 {
343 if (!helper.LocateFile(fpInfo)) {
344 LOG(ERROR) << "Could not find " << fpInfo;
345 return false;
346 }
347 if (!helper.GetFileContent(buf)) {
348 LOG(ERROR) << "Failed to get content of " << fpInfo;
349 return false;
350 }
351 return true;
352 }
353
354 // MSFB M= S= F= B>
CompareHmpVersion(const std::vector<string> & smallVersion,const std::vector<string> & bigVersion)355 bool CompareHmpVersion(const std::vector<string> &smallVersion, const std::vector<string> &bigVersion)
356 {
357 if (smallVersion.size() != PACKINFO_VERSION_VECTOR_SIZE || bigVersion.size() != PACKINFO_VERSION_VECTOR_SIZE) {
358 LOG(ERROR) << "invalid smallVersion " << smallVersion.size() << " invalid bigVersion " << bigVersion.size();
359 return false;
360 }
361 if (smallVersion[0] != bigVersion[0]) {
362 LOG(ERROR) << "pre " << smallVersion[0] << " not same as pkg " << bigVersion[0];
363 return false;
364 }
365
366 int32_t smallVer[HMP_VERSION_TYPE_NUM + 1] = {0};
367 int32_t bigVer[HMP_VERSION_TYPE_NUM + 1] = {0};
368 for (size_t i = 1; i < HMP_VERSION_TYPE_NUM + 1; i++) {
369 if (!Utils::ConvertToLong(smallVersion.at(i), smallVer[i])) {
370 LOG(ERROR) << "smallVersion ConvertToLong failed, index: " << i;
371 return false;
372 }
373 if (!Utils::ConvertToLong(bigVersion.at(i), bigVer[i])) {
374 LOG(ERROR) << "bigVersion ConvertToLong failed, index: " << i;
375 return false;
376 }
377 }
378 if (smallVer[1] == bigVer[1] && // 1: index of M
379 smallVer[2] == bigVer[2] && // 2: index of S
380 smallVer[3] == bigVer[3] && // 3: index of F
381 smallVer[4] < bigVer[4]) { // 4: index of B
382 return true;
383 }
384 return false;
385 }
386
387 // MSFB M= S= F<=
CompareSaSdkVersion(const std::vector<string> & smallVersion,const std::vector<string> & bigVersion)388 bool CompareSaSdkVersion(const std::vector<string> &smallVersion, const std::vector<string> &bigVersion)
389 {
390 if (smallVersion.size() != PACKINFO_VERSION_VECTOR_SIZE || bigVersion.size() != PACKINFO_VERSION_VECTOR_SIZE) {
391 LOG(ERROR) << "invalid smallSaSdk " << smallVersion.size() << " ;invalid bigSaSdk " << bigVersion.size();
392 return false;
393 }
394 if (smallVersion[0] != bigVersion[0]) {
395 LOG(ERROR) << "pre " << smallVersion[0] << " not same as pkg " << bigVersion[0];
396 return false;
397 }
398
399 int32_t smallVer[SA_SDK_VERSION_TYPE_NUM + 1] = {0};
400 int32_t bigVer[SA_SDK_VERSION_TYPE_NUM + 1] = {0};
401 for (size_t i = 1; i < SA_SDK_VERSION_TYPE_NUM + 1; i++) {
402 if (!Utils::ConvertToLong(smallVersion.at(i), smallVer[i])) {
403 LOG(ERROR) << "smallVersion ConvertToLong failed, index: " << i;
404 return false;
405 }
406 if (!Utils::ConvertToLong(bigVersion.at(i), bigVer[i])) {
407 LOG(ERROR) << "bigVersion ConvertToLong failed, index: " << i;
408 return false;
409 }
410 }
411 if (smallVer[1] == bigVer[1] && // 1: index of M
412 smallVer[2] == bigVer[2] && // 2: index of S
413 smallVer[3] >= bigVer[3]) { // 3: index of F
414 return true;
415 }
416 return false;
417 }
418
ParseVersion(const string & version,const string & split,std::vector<string> & versionVec)419 bool ParseVersion(const string &version, const string &split, std::vector<string> &versionVec)
420 {
421 size_t index = version.rfind(split);
422 if (index == std::string::npos) {
423 LOG(ERROR) << "ParseVersion failed " << version;
424 return false;
425 }
426 versionVec.emplace_back(version.substr(0, index));
427 std::string versionNumber = version.substr(index + split.length());
428
429 std::vector<std::string> tmpVersionVec = Utils::SplitString(versionNumber, "."); // xxx-d01_4.10.0.1
430 if (tmpVersionVec.size() != 4) { // 4: version number size
431 LOG(ERROR) << version << " is not right";
432 return false;
433 }
434 versionVec.insert(versionVec.end(), tmpVersionVec.begin(), tmpVersionVec.end());
435 return true;
436 }
437
VerifyModulePackageSign(const std::string & fpInfo)438 __attribute__((weak)) int32_t VerifyModulePackageSign(const std::string &fpInfo)
439 {
440 LOG(INFO) << "VerifyModulePackageSign " << fpInfo;
441 return VerifyPackage(fpInfo.c_str(), Utils::GetCertName().c_str(), "", nullptr, 0);
442 }
443
~ModuleFile()444 ModuleFile::~ModuleFile()
445 {
446 ClearVerifiedData();
447 }
448
Open(const string & fpInfo)449 std::unique_ptr<ModuleFile> ModuleFile::Open(const string &fpInfo)
450 {
451 ModuleZipHelper helper(fpInfo);
452 if (!helper.IsValid()) {
453 LOG(ERROR) << "Failed to open file " << fpInfo;
454 return nullptr;
455 }
456
457 string moduleInfo;
458 if (!ExtractZipFile(helper, PACK_INFO_NAME, moduleInfo)) {
459 LOG(ERROR) << "Failed to extract " << PACK_INFO_NAME << " from package " << fpInfo;
460 return nullptr;
461 }
462 ModulePackageInfo versionInfo;
463 if (!ParseModuleInfo(moduleInfo, versionInfo)) {
464 LOG(ERROR) << "Failed to parse version info of package " << fpInfo;
465 return nullptr;
466 }
467
468 ImageStat tmpStat;
469 std::optional<ImageStat> imageStat;
470 string imagePath = ExtractFilePath(fpInfo) + IMG_FILE_NAME;
471 if (ParseImageStat(imagePath, tmpStat)) {
472 imageStat = std::move(tmpStat);
473 } else if (!StartsWith(imagePath, MODULE_PREINSTALL_DIR)) {
474 LOG(ERROR) << "Update package without image " << imagePath;
475 return nullptr;
476 }
477
478 return std::make_unique<ModuleFile>(fpInfo, versionInfo, imageStat);
479 }
480
CompareVersion(const ModuleFile & newFile,const ModuleFile & oldFile)481 bool ModuleFile::CompareVersion(const ModuleFile &newFile, const ModuleFile &oldFile)
482 {
483 if (newFile.GetPath() == oldFile.GetPath()) {
484 return true;
485 }
486 std::vector<string> newVersion {};
487 std::vector<string> oldVersion {};
488 // version: xxx-d01 M.S.F.B
489 if (!ParseVersion(newFile.GetVersionInfo().version, " ", newVersion) ||
490 !ParseVersion(oldFile.GetVersionInfo().version, " ", oldVersion)) {
491 LOG(ERROR) << "when compare version, parse version failed.";
492 return false;
493 }
494
495 if (!CompareHmpVersion(oldVersion, newVersion)) {
496 LOG(ERROR) << "old hmp version: " << oldFile.GetVersionInfo().version <<
497 "is higher than " << newFile.GetVersionInfo().version;
498 return false;
499 }
500 if (oldFile.GetVersionInfo().moduleMap.size() != newFile.GetVersionInfo().moduleMap.size()) {
501 LOG(ERROR) << "old hmp module size: " << oldFile.GetVersionInfo().moduleMap.size() <<
502 "; new hmp module size: " << newFile.GetVersionInfo().moduleMap.size();
503 return false;
504 }
505 for (const auto& [key, value] : oldFile.GetVersionInfo().moduleMap) {
506 if (newFile.GetVersionInfo().moduleMap.find(key) == newFile.GetVersionInfo().moduleMap.end()) {
507 LOG(ERROR) << key << " is not exist in new hmp.";
508 return false;
509 }
510 if (!CompareSaListVersion(value.saInfoList, newFile.GetVersionInfo().moduleMap.at(key).saInfoList)) {
511 LOG(ERROR) << "old hmp sa version is higher.";
512 return false;
513 }
514 if (!CompareBundleList(value.bundleInfoList, newFile.GetVersionInfo().moduleMap.at(key).bundleInfoList)) {
515 LOG(ERROR) << "new hmp bundle list do not meet expectation.";
516 return false;
517 }
518 }
519 return true;
520 }
521
ProcessModuleUpdateVerityInfo(const std::string & partition) const522 bool ModuleFile::ProcessModuleUpdateVerityInfo(const std::string &partition) const
523 {
524 #ifdef SUPPORT_HVB
525 string imagePath = ExtractFilePath(GetPath()) + IMG_FILE_NAME;
526 if (!DealModuleUpdateHvbInfo(imagePath, imageStat_->imageSize, partition)) {
527 LOG(ERROR) << "deal with module update partition hvb info fail";
528 return false;
529 }
530 return true;
531 #else
532 LOG(INFO) << "do not support hvb";
533 return true;
534 #endif
535 }
536
VerifyModuleVerity()537 bool ModuleFile::VerifyModuleVerity()
538 {
539 #ifdef SUPPORT_HVB
540 if (vd_ != nullptr) {
541 LOG(INFO) << "already verified verity";
542 return true;
543 }
544 struct hvb_buf pubkey;
545 vd_ = hvb_init_verified_data();
546 if (vd_ == nullptr) {
547 LOG(ERROR) << "init verified data failed";
548 return false;
549 }
550 ON_SCOPE_EXIT(clear) {
551 ClearVerifiedData();
552 };
553 string imagePath = ExtractFilePath(GetPath()) + IMG_FILE_NAME;
554 enum hvb_errno ret = footer_init_desc(ModuleHvbGetOps(), imagePath.c_str(), nullptr, &pubkey, vd_);
555 if (ret != HVB_OK) {
556 LOG(ERROR) << "hvb verify failed err=" << ret;
557 return false;
558 }
559 CANCEL_SCOPE_EXIT_GUARD(clear);
560 return true;
561 #else
562 LOG(INFO) << "do not support hvb";
563 return true;
564 #endif
565 }
566
ClearVerifiedData()567 void ModuleFile::ClearVerifiedData()
568 {
569 #ifdef SUPPORT_HVB
570 if (vd_ != nullptr) {
571 hvb_chain_verify_data_free(vd_);
572 vd_ = nullptr;
573 }
574 #endif
575 }
576 } // namespace SysInstaller
577 } // namespace OHOS