• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 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 "aot/aot_executor.h"
17 
18 #include <cerrno>
19 #include <csignal>
20 #include <cstdint>
21 #include <cstdlib>
22 #include <cstring>
23 #include <filesystem>
24 #include <iostream>
25 #include <sstream>
26 #include <string>
27 #include <sys/stat.h>
28 #include <sys/types.h>
29 #include <sys/wait.h>
30 #include <unistd.h>
31 
32 #include "app_log_tag_wrapper.h"
33 #include "app_log_wrapper.h"
34 #include "bundle_constants.h"
35 #include "bundle_extractor.h"
36 #include "bundle_service_constants.h"
37 #if defined(CODE_SIGNATURE_ENABLE)
38 #include "aot_compiler_client.h"
39 #include "code_sign_utils.h"
40 #endif
41 #include "installd/installd_operator.h"
42 #include "system_ability_definition.h"
43 
44 namespace OHOS {
45 namespace AppExecFwk {
46 namespace {
47 constexpr const char* ABC_RELATIVE_PATH = "ets/modules.abc";
48 constexpr const char* STATIC_ABC_RELATIVE_PATH = "ets/modules_static.abc";
49 constexpr const char* HEX_PREFIX = "0x";
50 constexpr const char* BUNDLE_NAME = "bundleName";
51 constexpr const char* MODULE_NAME = "moduleName";
52 constexpr const char* PKG_PATH = "pkgPath";
53 constexpr const char* ABC_NAME = "abcName";
54 constexpr const char* ABC_PATH = "ABC-Path";
55 constexpr const char* AN_FILE_NAME = "anFileName";
56 constexpr const char* ABC_OFFSET = "abcOffset";
57 constexpr const char* ABC_SIZE = "abcSize";
58 constexpr const char* PROCESS_UID = "processUid";
59 constexpr const char* BUNDLE_UID = "bundleUid";
60 constexpr const char* APP_IDENTIFIER = "appIdentifier";
61 constexpr const char* IS_ENCRYPTED_BUNDLE = "isEncryptedBundle";
62 constexpr const char* IS_SCREEN_OFF = "isScreenOff";
63 constexpr const char* PGO_DIR = "pgoDir";
64 constexpr const char* IS_SYS_COMP = "isSysComp";
65 constexpr const char* IS_SYS_COMP_FALSE = "0";
66 constexpr const char* IS_SYS_COMP_TRUE = "1";
67 #if defined(CODE_SIGNATURE_ENABLE)
68 constexpr int16_t ERR_AOT_COMPILER_SIGN_FAILED = 10004;
69 constexpr int16_t ERR_AOT_COMPILER_CALL_CRASH = 10008;
70 constexpr int16_t ERR_AOT_COMPILER_CALL_CANCELLED = 10009;
71 #endif
72 }
73 
GetInstance()74 AOTExecutor& AOTExecutor::GetInstance()
75 {
76     static AOTExecutor executor;
77     return executor;
78 }
79 
DecToHex(uint32_t decimal) const80 std::string AOTExecutor::DecToHex(uint32_t decimal) const
81 {
82     APP_LOGD("DecToHex begin, decimal : %{public}u", decimal);
83     std::stringstream ss;
84     ss << std::hex << decimal;
85     std::string hexString = HEX_PREFIX + ss.str();
86     APP_LOGD("hex : %{public}s", hexString.c_str());
87     return hexString;
88 }
89 
CheckArgs(const AOTArgs & aotArgs) const90 bool AOTExecutor::CheckArgs(const AOTArgs &aotArgs) const
91 {
92     if (aotArgs.compileMode.empty() || aotArgs.hapPath.empty() || aotArgs.outputPath.empty()) {
93         APP_LOGE("aotArgs check failed");
94         return false;
95     }
96     if (aotArgs.compileMode == ServiceConstants::COMPILE_PARTIAL && aotArgs.arkProfilePath.empty()) {
97         APP_LOGE("partial mode, arkProfilePath can't be empty");
98         return false;
99     }
100     return true;
101 }
102 
GetAbcRelativePath(const std::string & moduleArkTSMode) const103 std::string AOTExecutor::GetAbcRelativePath(const std::string &moduleArkTSMode) const
104 {
105     if (moduleArkTSMode == Constants::ARKTS_MODE_DYNAMIC) {
106         return ABC_RELATIVE_PATH;
107     }
108     if (moduleArkTSMode == Constants::ARKTS_MODE_STATIC || moduleArkTSMode == Constants::ARKTS_MODE_HYBRID) {
109         return STATIC_ABC_RELATIVE_PATH;
110     }
111     APP_LOGW("invalid moduleArkTSMode : %{public}s", moduleArkTSMode.c_str());
112     return Constants::EMPTY_STRING;
113 }
114 
GetAbcFileInfo(const std::string & hapPath,const std::string & moduleArkTSMode,uint32_t & offset,uint32_t & length) const115 bool AOTExecutor::GetAbcFileInfo(const std::string &hapPath, const std::string &moduleArkTSMode,
116     uint32_t &offset, uint32_t &length) const
117 {
118     BundleExtractor extractor(hapPath);
119     if (!extractor.Init()) {
120         APP_LOGE("init BundleExtractor failed");
121         return false;
122     }
123     std::string abcRelativePath = GetAbcRelativePath(moduleArkTSMode);
124     if (abcRelativePath.empty()) {
125         APP_LOGE("abcRelativePath empty");
126         return false;
127     }
128     if (!extractor.GetFileInfo(abcRelativePath, offset, length)) {
129         APP_LOGE("GetFileInfo failed");
130         return false;
131     }
132     APP_LOGD("GetFileInfo success, offset : %{public}u, length : %{public}u", offset, length);
133     return true;
134 }
135 
PrepareArgs(const AOTArgs & aotArgs,AOTArgs & completeArgs) const136 ErrCode AOTExecutor::PrepareArgs(const AOTArgs &aotArgs, AOTArgs &completeArgs) const
137 {
138     APP_LOGD("PrepareArgs begin");
139     if (aotArgs.isSysComp) {
140         APP_LOGD("sysComp, no need to prepare args");
141         completeArgs = aotArgs;
142         return ERR_OK;
143     }
144     if (!CheckArgs(aotArgs)) {
145         APP_LOGE("param check failed");
146         return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
147     }
148     completeArgs = aotArgs;
149     if (!GetAbcFileInfo(completeArgs.hapPath, completeArgs.moduleArkTSMode,
150         completeArgs.offset, completeArgs.length)) {
151         APP_LOGE("GetAbcFileInfo failed");
152         return ERR_APPEXECFWK_INSTALLD_AOT_ABC_NOT_EXIST;
153     }
154     // handle hsp
155     for (auto &hspInfo : completeArgs.hspVector) {
156         (void)GetAbcFileInfo(hspInfo.hapPath, hspInfo.moduleArkTSMode, hspInfo.offset, hspInfo.length);
157     }
158     APP_LOGD("PrepareArgs success");
159     return ERR_OK;
160 }
161 
GetSubjectInfo(const AOTArgs & aotArgs) const162 nlohmann::json AOTExecutor::GetSubjectInfo(const AOTArgs &aotArgs) const
163 {
164     /* obtain the uid of current process */
165     int32_t currentProcessUid = static_cast<int32_t>(getuid());
166 
167     std::filesystem::path filePath(aotArgs.arkProfilePath);
168     nlohmann::json subject;
169     subject[BUNDLE_NAME] = aotArgs.bundleName;
170     subject[MODULE_NAME] = aotArgs.moduleName;
171     subject[PKG_PATH] = aotArgs.hapPath;
172     subject[ABC_NAME] = GetAbcRelativePath(aotArgs.moduleArkTSMode);
173     subject[ABC_OFFSET] = DecToHex(aotArgs.offset);
174     subject[ABC_SIZE] = DecToHex(aotArgs.length);
175     subject[PROCESS_UID] = DecToHex(currentProcessUid);
176     subject[BUNDLE_UID] = DecToHex(aotArgs.bundleUid);
177     subject[APP_IDENTIFIER] = aotArgs.appIdentifier;
178     subject[IS_ENCRYPTED_BUNDLE] = DecToHex(aotArgs.isEncryptedBundle);
179     subject[IS_SCREEN_OFF] = DecToHex(aotArgs.isScreenOff);
180     subject[PGO_DIR] = filePath.parent_path().string();
181     return subject;
182 }
183 
MapSysCompArgs(const AOTArgs & aotArgs,std::unordered_map<std::string,std::string> & argsMap)184 void AOTExecutor::MapSysCompArgs(const AOTArgs &aotArgs, std::unordered_map<std::string, std::string> &argsMap)
185 {
186     APP_LOGI_NOFUNC("MapSysCompArgs : %{public}s", aotArgs.ToString().c_str());
187     argsMap.emplace(IS_SYS_COMP, IS_SYS_COMP_TRUE);
188     argsMap.emplace(ABC_PATH, aotArgs.sysCompPath);
189     argsMap.emplace(AN_FILE_NAME, aotArgs.anFileName);
190     uid_t uid = getuid();
191     if (uid > UINT32_MAX) {
192         APP_LOGE_NOFUNC("invalid uid");
193         return;
194     }
195     argsMap.emplace(PROCESS_UID, DecToHex(uid));
196 }
197 
MapHapArgs(const AOTArgs & aotArgs,std::unordered_map<std::string,std::string> & argsMap)198 void AOTExecutor::MapHapArgs(const AOTArgs &aotArgs, std::unordered_map<std::string, std::string> &argsMap)
199 {
200     APP_LOGD("MapHapArgs : %{public}s", aotArgs.ToString().c_str());
201     nlohmann::json subject = GetSubjectInfo(aotArgs);
202 
203     nlohmann::json objectArray = nlohmann::json::array();
204     for (const auto &hspInfo : aotArgs.hspVector) {
205         nlohmann::json object;
206         object[BUNDLE_NAME] = hspInfo.bundleName;
207         object[MODULE_NAME] = hspInfo.moduleName;
208         object[PKG_PATH] = hspInfo.hapPath;
209         object[ABC_NAME] = GetAbcRelativePath(hspInfo.moduleArkTSMode);
210         object[Constants::MODULE_ARKTS_MODE] = hspInfo.moduleArkTSMode;
211         object[ABC_OFFSET] = DecToHex(hspInfo.offset);
212         object[ABC_SIZE] = DecToHex(hspInfo.length);
213         objectArray.push_back(object);
214     }
215     argsMap.emplace("target-compiler-mode", aotArgs.compileMode);
216     argsMap.emplace("aot-file", aotArgs.outputPath + ServiceConstants::PATH_SEPARATOR + aotArgs.moduleName);
217     argsMap.emplace("compiler-pkg-info", subject.dump());
218     argsMap.emplace("compiler-external-pkg-info", objectArray.dump());
219     argsMap.emplace("compiler-opt-bc-range", aotArgs.optBCRangeList);
220     argsMap.emplace("compiler-device-state", std::to_string(aotArgs.isScreenOff));
221     argsMap.emplace("compiler-baseline-pgo", std::to_string(aotArgs.isEnableBaselinePgo));
222     std::string abcPath =
223         aotArgs.hapPath + ServiceConstants::PATH_SEPARATOR + GetAbcRelativePath(aotArgs.moduleArkTSMode);
224     argsMap.emplace(ABC_PATH, abcPath);
225     argsMap.emplace("BundleUid", std::to_string(aotArgs.bundleUid));
226     argsMap.emplace("BundleGid", std::to_string(aotArgs.bundleGid));
227     argsMap.emplace(AN_FILE_NAME, aotArgs.anFileName);
228     argsMap.emplace("appIdentifier", aotArgs.appIdentifier);
229     argsMap.emplace(Constants::MODULE_ARKTS_MODE, aotArgs.moduleArkTSMode);
230     argsMap.emplace(IS_SYS_COMP, IS_SYS_COMP_FALSE);
231 
232     for (const auto &arg : argsMap) {
233         LOG_NOFUNC_I(BMS_TAG_AOT, "%{public}s: %{public}s", arg.first.c_str(), arg.second.c_str());
234     }
235 }
236 
PendSignAOT(const std::string & anFileName,const std::vector<uint8_t> & signData) const237 ErrCode AOTExecutor::PendSignAOT(const std::string &anFileName, const std::vector<uint8_t> &signData) const
238 {
239     return EnforceCodeSign(anFileName, signData);
240 }
241 
EnforceCodeSign(const std::string & anFileName,const std::vector<uint8_t> & signData) const242 ErrCode AOTExecutor::EnforceCodeSign(const std::string &anFileName, const std::vector<uint8_t> &signData) const
243 {
244 #if defined(CODE_SIGNATURE_ENABLE)
245     if (signData.empty()) {
246         APP_LOGI("not enforce code sign if no aot file save");
247         return ERR_OK;
248     }
249     uint32_t dataSize = static_cast<uint32_t>(signData.size());
250     auto retCS =
251         Security::CodeSign::CodeSignUtils::EnforceCodeSignForFile(anFileName, signData.data(), dataSize);
252     if (retCS == VerifyErrCode::CS_ERR_ENABLE) {
253         APP_LOGI("pending enforce code sign as screen not first unlock after reboot");
254         return ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE;
255     }
256     if (retCS != CommonErrCode::CS_SUCCESS) {
257         APP_LOGE("fail to enable code signature for the aot file");
258         return ERR_APPEXECFWK_INSTALLD_SIGN_AOT_FAILED;
259     }
260     APP_LOGI("sign aot file success");
261     return ERR_OK;
262 #else
263     APP_LOGI("code signature disable, ignore");
264     return ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED;
265 #endif
266 }
267 
StartAOTCompiler(const AOTArgs & aotArgs,std::vector<uint8_t> & signData)268 ErrCode AOTExecutor::StartAOTCompiler(const AOTArgs &aotArgs, std::vector<uint8_t> &signData)
269 {
270 #if defined(CODE_SIGNATURE_ENABLE)
271     std::unordered_map<std::string, std::string> argsMap;
272     if (aotArgs.isSysComp) {
273         MapSysCompArgs(aotArgs, argsMap);
274     } else {
275         MapHapArgs(aotArgs, argsMap);
276         std::string aotFilePath = ServiceConstants::ARK_CACHE_PATH + aotArgs.bundleName;
277         if (!InstalldOperator::IsExistDir(ServiceConstants::ARK_CACHE_PATH)) {
278             APP_LOGE("ark cache dir not exist");
279             return ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED;
280         }
281         if (!InstalldOperator::MkOwnerDir(aotFilePath, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH,
282             aotArgs.bundleUid, aotArgs.bundleGid)) {
283             APP_LOGE("mk bundle ark cache dir failed");
284             return ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED;
285         }
286     }
287     APP_LOGI("start to aot compiler");
288     std::vector<int16_t> fileData;
289     ErrCode ret = ArkCompiler::AotCompilerClient::GetInstance().AotCompiler(argsMap, fileData);
290     if (ret == ERR_AOT_COMPILER_SIGN_FAILED) {
291         APP_LOGE("aot compiler local signature fail");
292         return ERR_APPEXECFWK_INSTALLD_SIGN_AOT_FAILED;
293     } else if (ret == ERR_AOT_COMPILER_CALL_CRASH) {
294         APP_LOGE("aot compiler crash");
295         return ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_CRASH;
296     } else if (ret == ERR_AOT_COMPILER_CALL_CANCELLED) {
297         APP_LOGE("aot compiler cancel");
298         return ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_CANCELLED;
299     } else if (ret != ERR_OK) {
300         APP_LOGE("aot compiler fail");
301         return ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED;
302     }
303     uint32_t byteSize = static_cast<uint32_t>(fileData.size());
304     for (uint32_t i = 0; i < byteSize; ++i) {
305         signData.emplace_back(static_cast<uint8_t>(fileData[i]));
306     }
307     APP_LOGI("aot compiler success");
308     return ERR_OK;
309 #else
310     APP_LOGI("code signature disable, ignore");
311     return ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED;
312 #endif
313 }
314 
ExecuteAOT(const AOTArgs & aotArgs,ErrCode & ret,std::vector<uint8_t> & pendSignData)315 void AOTExecutor::ExecuteAOT(const AOTArgs &aotArgs, ErrCode &ret, std::vector<uint8_t> &pendSignData)
316 {
317 #if defined(CODE_SIGNATURE_ENABLE)
318     APP_LOGI("begin to execute AOT");
319     {
320         std::lock_guard<std::mutex> lock(stateMutex_);
321         if (state_.running) {
322             APP_LOGI("AOT is running, ignore");
323             ret = ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED;
324             return;
325         }
326     }
327     AOTArgs completeArgs;
328     ret = PrepareArgs(aotArgs, completeArgs);
329     if (ret != ERR_OK) {
330         APP_LOGE("prepareArgs fail");
331         return;
332     }
333     {
334         std::lock_guard<std::mutex> lock(stateMutex_);
335         InitState(aotArgs);
336     }
337     APP_LOGI("begin to call aot compiler");
338     std::vector<uint8_t> signData;
339     ret = StartAOTCompiler(completeArgs, signData);
340     if (ret == ERR_OK) {
341         ret = EnforceCodeSign(completeArgs.anFileName, signData);
342     }
343     if (ret == ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE) {
344         pendSignData = signData;
345     }
346     APP_LOGI("aot compiler finish");
347     {
348         std::lock_guard<std::mutex> lock(stateMutex_);
349         ResetState();
350     }
351 #else
352     APP_LOGI("code signature disable, ignore");
353     ret = ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED;
354 #endif
355 }
356 
StopAOT()357 ErrCode AOTExecutor::StopAOT()
358 {
359 #if defined(CODE_SIGNATURE_ENABLE)
360     APP_LOGI("begin to stop AOT");
361     std::lock_guard<std::mutex> lock(stateMutex_);
362     if (!state_.running) {
363         APP_LOGI("AOT not running, return directly");
364         return ERR_OK;
365     }
366     int32_t ret = ArkCompiler::AotCompilerClient::GetInstance().StopAotCompiler();
367     if (ret != ERR_OK) {
368         APP_LOGE("stop aot compiler fail");
369         return ERR_APPEXECFWK_INSTALLD_STOP_AOT_FAILED;
370     }
371     (void)InstalldOperator::DeleteDir(state_.outputPath);
372     ResetState();
373     return ERR_OK;
374 #else
375     APP_LOGI("code signature disable, ignore");
376     return ERR_APPEXECFWK_INSTALLD_STOP_AOT_FAILED;
377 #endif
378 }
379 
InitState(const AOTArgs & aotArgs)380 void AOTExecutor::InitState(const AOTArgs &aotArgs)
381 {
382     state_.running = true;
383     state_.outputPath = aotArgs.outputPath;
384 }
385 
ResetState()386 void AOTExecutor::ResetState()
387 {
388     state_.running = false;
389     state_.outputPath.clear();
390 }
391 }  // namespace AppExecFwk
392 }  // namespace OHOS
393