1 /* 2 * Copyright (c) 2024 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 #ifndef ECMASCRIPT_OHOS_OHOS_PKG_VERIFIER_H 17 #define ECMASCRIPT_OHOS_OHOS_PKG_VERIFIER_H 18 19 #include <fcntl.h> 20 21 #include "ecmascript/compiler/aot_compiler_preprocessor.h" 22 #include "ecmascript/ohos/ohos_pkg_args.h" 23 24 namespace panda::ecmascript::ohos { 25 using AotCompilerPreprocessor = kungfu::AotCompilerPreprocessor; 26 using CompilationOptions = kungfu::CompilationOptions; 27 using OhosPkgArgs = kungfu::OhosPkgArgs; 28 using ParseBundleNameAndAppIdentifierFunc = int32_t (*)(const int32_t, std::string&, std::string&); 29 30 class OhosPkgVerifier { 31 public: 32 constexpr static const char *const LIB_HAPVERIFY_SO_NAME = "libhapverify.z.so"; 33 VerifyPkgInfo(AotCompilerPreprocessor & cPreprocessor,CompilationOptions & cOptions)34 static bool VerifyPkgInfo(AotCompilerPreprocessor &cPreprocessor, CompilationOptions &cOptions) 35 { 36 // Processing only for application packages 37 if (!cPreprocessor.GetMainPkgArgs()) { 38 return true; 39 } 40 if (CheckBundleNameAndAppIdentifier(cPreprocessor) && 41 CheckArkProfile(cPreprocessor) && 42 CheckAOTOutputFilePath(cPreprocessor, cOptions)) { 43 return true; 44 } 45 return false; 46 } 47 CheckArkProfile(AotCompilerPreprocessor & cPreprocessor)48 static bool CheckArkProfile(AotCompilerPreprocessor &cPreprocessor) 49 { 50 std::regex pattern("/data/app/el1/\\d+/aot_compiler/ark_profile.*"); 51 std::string pgoDir = cPreprocessor.GetMainPkgArgs()->GetPgoDir(); 52 std::string bundleName = cPreprocessor.GetMainPkgArgs()->GetBundleName(); 53 if (!std::regex_search(pgoDir, pattern) || 54 pgoDir.find(bundleName) == std::string::npos) { 55 LOG_COMPILER(ERROR) << "verify ark-profile path wrong"; 56 return false; 57 } 58 return true; 59 } 60 CheckAOTOutputFilePath(AotCompilerPreprocessor & cPreprocessor,CompilationOptions & cOptions)61 static bool CheckAOTOutputFilePath(AotCompilerPreprocessor &cPreprocessor, CompilationOptions &cOptions) 62 { 63 std::string arkCachePath = "/data/app/el1/public/aot_compiler/ark_cache/"; 64 if (cOptions.outputFileName_.substr(0, arkCachePath.length()) != arkCachePath) { 65 LOG_COMPILER(ERROR) << "aot file name wrong"; 66 return false; 67 } 68 if (cOptions.outputFileName_.find(cPreprocessor.GetMainPkgArgs()->GetBundleName()) == std::string::npos) { 69 LOG_COMPILER(ERROR) << "verify main pkg bundleName wrong"; 70 return false; 71 } 72 return true; 73 } 74 CheckBundleNameAndAppIdentifier(AotCompilerPreprocessor & cPreprocessor)75 static bool CheckBundleNameAndAppIdentifier([[maybe_unused]] AotCompilerPreprocessor &cPreprocessor) 76 { 77 #if defined(PANDA_TARGET_OHOS) 78 void* handle = dlopen(LIB_HAPVERIFY_SO_NAME, RTLD_NOW); 79 if (handle == nullptr) { 80 LOG_COMPILER(ERROR) << "dlopen hapverify so fail"; 81 return false; 82 } 83 ParseBundleNameAndAppIdentifierFunc parseBundleNameAndAppIdentifierFunc = 84 reinterpret_cast<ParseBundleNameAndAppIdentifierFunc>(dlsym(handle, "ParseBundleNameAndAppIdentifier")); 85 if (parseBundleNameAndAppIdentifierFunc == nullptr) { 86 LOG_COMPILER(ERROR) << "dlsym ParseBundleNameAndAppIdentifier fail"; 87 dlclose(handle); 88 return false; 89 } 90 for (const auto& pkg : cPreprocessor.GetPkgsArgs()) { 91 std::string realPath; 92 if (!RealPath(pkg.second->GetPath().c_str(), realPath, true)) { 93 LOG_ECMA(ERROR) << "Fail to get realPath: " << pkg.second->GetPath().c_str(); 94 dlclose(handle); 95 return false; 96 } 97 fd_t fd = open(realPath.c_str(), FILE_RDONLY); 98 if (fd == INVALID_FD) { 99 LOG_ECMA(ERROR) << realPath.c_str() << " file open failed"; 100 dlclose(handle); 101 return false; 102 } 103 pkg.second->SetPkgFd(fd); 104 std::string bundleName; 105 std::string appIdentifier; 106 int32_t res = parseBundleNameAndAppIdentifierFunc(fd, bundleName, appIdentifier); 107 if (res != 0 || bundleName != pkg.second->GetBundleName()) { 108 dlclose(handle); 109 LOG_COMPILER(ERROR) << "parse bundleName: " << bundleName.c_str() << " fail, res: " << res; 110 return false; 111 } 112 // Only mainpkg carries appindetifier 113 if (IsMainPkg(cPreprocessor, pkg) && appIdentifier != pkg.second->GetAppSignature()) { 114 dlclose(handle); 115 LOG_COMPILER(ERROR) << "parse mainPkgName: " << cPreprocessor.GetMainPkgName().c_str() << 116 " appIdentifier fail"; 117 return false; 118 } 119 } 120 dlclose(handle); 121 return true; 122 #endif 123 return false; 124 } 125 IsMainPkg(AotCompilerPreprocessor & cPreprocessor,std::pair<const std::string,std::shared_ptr<OhosPkgArgs>> pkg)126 static bool IsMainPkg(AotCompilerPreprocessor &cPreprocessor, std::pair<const std::string, 127 std::shared_ptr<OhosPkgArgs>> pkg) 128 { 129 if (cPreprocessor.GetMainPkgName() == pkg.first) { 130 return true; 131 } 132 return false; 133 } 134 }; 135 } // namespace panda::ecmascript::ohos 136 #endif 137