169570cc8Sopenharmony_ci/* 269570cc8Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 369570cc8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 469570cc8Sopenharmony_ci * you may not use this file except in compliance with the License. 569570cc8Sopenharmony_ci * You may obtain a copy of the License at 669570cc8Sopenharmony_ci * 769570cc8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 869570cc8Sopenharmony_ci * 969570cc8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1069570cc8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1169570cc8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1269570cc8Sopenharmony_ci * See the License for the specific language governing permissions and 1369570cc8Sopenharmony_ci * limitations under the License. 1469570cc8Sopenharmony_ci */ 1569570cc8Sopenharmony_ci 1669570cc8Sopenharmony_ci#include <algorithm> 1769570cc8Sopenharmony_ci#include <cerrno> 1869570cc8Sopenharmony_ci#include <ctime> 1969570cc8Sopenharmony_ci#include <dlfcn.h> 2069570cc8Sopenharmony_ci#include <map> 2169570cc8Sopenharmony_ci#include <mutex> 2269570cc8Sopenharmony_ci#include <string> 2369570cc8Sopenharmony_ci 2469570cc8Sopenharmony_ci#ifdef __MUSL__ 2569570cc8Sopenharmony_ci#include <cerrno> 2669570cc8Sopenharmony_ci#include <dlfcn_ext.h> 2769570cc8Sopenharmony_ci#include <sys/mman.h> 2869570cc8Sopenharmony_ci#endif 2969570cc8Sopenharmony_ci 3069570cc8Sopenharmony_ci#include "appspawn_hook.h" 3169570cc8Sopenharmony_ci#include "appspawn_manager.h" 3269570cc8Sopenharmony_ci#include "appspawn_utils.h" 3369570cc8Sopenharmony_ci 3469570cc8Sopenharmony_ci#ifdef WITH_SECCOMP 3569570cc8Sopenharmony_ci#include "seccomp_policy.h" 3669570cc8Sopenharmony_ci#endif 3769570cc8Sopenharmony_ci 3869570cc8Sopenharmony_ci#ifndef APPSPAWN_TEST 3969570cc8Sopenharmony_ci#define APPSPAWN_STATIC static 4069570cc8Sopenharmony_ci#else 4169570cc8Sopenharmony_ci#define APPSPAWN_STATIC 4269570cc8Sopenharmony_ci#endif 4369570cc8Sopenharmony_ci 4469570cc8Sopenharmony_cinamespace { 4569570cc8Sopenharmony_ci#if defined(webview_arm64) 4669570cc8Sopenharmony_ci const std::string ARK_WEB_CORE_HAP_LIB_PATH = 4769570cc8Sopenharmony_ci "/data/storage/el1/bundle/arkwebcore/libs/arm64"; 4869570cc8Sopenharmony_ci#elif defined(webview_x86_64) 4969570cc8Sopenharmony_ci const std::string ARK_WEB_CORE_HAP_LIB_PATH = 5069570cc8Sopenharmony_ci "/data/storage/el1/bundle/arkwebcore/libs/x86_64"; 5169570cc8Sopenharmony_ci#else 5269570cc8Sopenharmony_ci const std::string ARK_WEB_CORE_HAP_LIB_PATH = 5369570cc8Sopenharmony_ci "/data/storage/el1/bundle/arkwebcore/libs/arm"; 5469570cc8Sopenharmony_ci#endif 5569570cc8Sopenharmony_ci const std::string ARK_WEB_ENGINE_LIB_NAME = "libarkweb_engine.so"; 5669570cc8Sopenharmony_ci const std::string ARK_WEB_RENDER_LIB_NAME = "libarkweb_render.so"; 5769570cc8Sopenharmony_ci const std::string WEB_ENGINE_LIB_NAME = "libweb_engine.so"; 5869570cc8Sopenharmony_ci const std::string WEB_RENDER_LIB_NAME = "libnweb_render.so"; 5969570cc8Sopenharmony_ci} // namespace 6069570cc8Sopenharmony_ci 6169570cc8Sopenharmony_ciAPPSPAWN_STATIC bool SetSeccompPolicyForRenderer(void *nwebRenderHandle) 6269570cc8Sopenharmony_ci{ 6369570cc8Sopenharmony_ci#ifdef WITH_SECCOMP 6469570cc8Sopenharmony_ci if (IsEnableSeccomp()) { 6569570cc8Sopenharmony_ci using SeccompFuncType = bool (*)(void); 6669570cc8Sopenharmony_ci SeccompFuncType funcSetRendererSeccompPolicy = 6769570cc8Sopenharmony_ci reinterpret_cast<SeccompFuncType>(dlsym(nwebRenderHandle, "SetRendererSeccompPolicy")); 6869570cc8Sopenharmony_ci if (funcSetRendererSeccompPolicy != nullptr && funcSetRendererSeccompPolicy()) { 6969570cc8Sopenharmony_ci return true; 7069570cc8Sopenharmony_ci } 7169570cc8Sopenharmony_ci APPSPAWN_LOGE("SetRendererSeccompPolicy dlsym errno: %{public}d", errno); 7269570cc8Sopenharmony_ci return false; 7369570cc8Sopenharmony_ci } 7469570cc8Sopenharmony_ci#endif 7569570cc8Sopenharmony_ci return true; 7669570cc8Sopenharmony_ci} 7769570cc8Sopenharmony_ci 7869570cc8Sopenharmony_ciAPPSPAWN_STATIC std::string GetArkWebEngineLibName() 7969570cc8Sopenharmony_ci{ 8069570cc8Sopenharmony_ci std::string arkWebEngineLibPath = ARK_WEB_CORE_HAP_LIB_PATH + "/" 8169570cc8Sopenharmony_ci + ARK_WEB_ENGINE_LIB_NAME; 8269570cc8Sopenharmony_ci bool isArkWebEngineLibPathExist = access(arkWebEngineLibPath.c_str(), F_OK) == 0; 8369570cc8Sopenharmony_ci return isArkWebEngineLibPathExist ? 8469570cc8Sopenharmony_ci ARK_WEB_ENGINE_LIB_NAME : WEB_ENGINE_LIB_NAME; 8569570cc8Sopenharmony_ci} 8669570cc8Sopenharmony_ci 8769570cc8Sopenharmony_ciAPPSPAWN_STATIC std::string GetArkWebRenderLibName() 8869570cc8Sopenharmony_ci{ 8969570cc8Sopenharmony_ci std::string arkWebRenderLibPath = ARK_WEB_CORE_HAP_LIB_PATH + "/" 9069570cc8Sopenharmony_ci + ARK_WEB_RENDER_LIB_NAME; 9169570cc8Sopenharmony_ci bool isArkWebRenderLibPathExist = access(arkWebRenderLibPath.c_str(), F_OK) == 0; 9269570cc8Sopenharmony_ci return isArkWebRenderLibPathExist ? 9369570cc8Sopenharmony_ci ARK_WEB_RENDER_LIB_NAME : WEB_RENDER_LIB_NAME; 9469570cc8Sopenharmony_ci} 9569570cc8Sopenharmony_ci 9669570cc8Sopenharmony_ciAPPSPAWN_STATIC int RunChildProcessor(AppSpawnContent *content, AppSpawnClient *client) 9769570cc8Sopenharmony_ci{ 9869570cc8Sopenharmony_ci EnableCache(); 9969570cc8Sopenharmony_ci uint32_t len = 0; 10069570cc8Sopenharmony_ci char *renderCmd = reinterpret_cast<char *>(GetAppPropertyExt( 10169570cc8Sopenharmony_ci reinterpret_cast<AppSpawningCtx *>(client), MSG_EXT_NAME_RENDER_CMD, &len)); 10269570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(renderCmd != nullptr, return -1); 10369570cc8Sopenharmony_ci std::string renderStr(renderCmd); 10469570cc8Sopenharmony_ci void *webEngineHandle = nullptr; 10569570cc8Sopenharmony_ci void *nwebRenderHandle = nullptr; 10669570cc8Sopenharmony_ci 10769570cc8Sopenharmony_ci const std::string& libPath = ARK_WEB_CORE_HAP_LIB_PATH; 10869570cc8Sopenharmony_ci const std::string engineLibName = GetArkWebEngineLibName(); 10969570cc8Sopenharmony_ci const std::string renderLibName = GetArkWebRenderLibName(); 11069570cc8Sopenharmony_ci 11169570cc8Sopenharmony_ci#ifdef __MUSL__ 11269570cc8Sopenharmony_ci Dl_namespace dlns; 11369570cc8Sopenharmony_ci dlns_init(&dlns, "nweb_ns"); 11469570cc8Sopenharmony_ci dlns_create(&dlns, libPath.c_str()); 11569570cc8Sopenharmony_ci // preload libweb_engine 11669570cc8Sopenharmony_ci webEngineHandle = 11769570cc8Sopenharmony_ci dlopen_ns(&dlns, engineLibName.c_str(), RTLD_NOW | RTLD_GLOBAL); 11869570cc8Sopenharmony_ci // load libnweb_render 11969570cc8Sopenharmony_ci nwebRenderHandle = 12069570cc8Sopenharmony_ci dlopen_ns(&dlns, renderLibName.c_str(), RTLD_NOW | RTLD_GLOBAL); 12169570cc8Sopenharmony_ci#else 12269570cc8Sopenharmony_ci // preload libweb_engine 12369570cc8Sopenharmony_ci const std::string engineLibPath = libPath + "/" + engineLibName; 12469570cc8Sopenharmony_ci webEngineHandle = dlopen(engineLibPath.c_str(), RTLD_NOW | RTLD_GLOBAL); 12569570cc8Sopenharmony_ci 12669570cc8Sopenharmony_ci // load libnweb_render 12769570cc8Sopenharmony_ci const std::string renderLibPath = libPath + "/" + renderLibName; 12869570cc8Sopenharmony_ci nwebRenderHandle = dlopen(renderLibPath.c_str(), RTLD_NOW | RTLD_GLOBAL); 12969570cc8Sopenharmony_ci#endif 13069570cc8Sopenharmony_ci if (webEngineHandle == nullptr) { 13169570cc8Sopenharmony_ci APPSPAWN_LOGE("Fail to dlopen libweb_engine.so, errno: %{public}d", errno); 13269570cc8Sopenharmony_ci } 13369570cc8Sopenharmony_ci if (nwebRenderHandle == nullptr) { 13469570cc8Sopenharmony_ci APPSPAWN_LOGE("Fail to dlopen libnweb_render.so, errno: %{public}d", errno); 13569570cc8Sopenharmony_ci return -1; 13669570cc8Sopenharmony_ci } 13769570cc8Sopenharmony_ci 13869570cc8Sopenharmony_ci std::string processType = reinterpret_cast<char *>(GetAppPropertyExt( 13969570cc8Sopenharmony_ci reinterpret_cast<AppSpawningCtx *>(client), MSG_EXT_NAME_PROCESS_TYPE, &len)); 14069570cc8Sopenharmony_ci if (processType == "render" && !SetSeccompPolicyForRenderer(nwebRenderHandle)) { 14169570cc8Sopenharmony_ci return -1; 14269570cc8Sopenharmony_ci } 14369570cc8Sopenharmony_ci using FuncType = void (*)(const char *cmd); 14469570cc8Sopenharmony_ci 14569570cc8Sopenharmony_ci FuncType funcNWebRenderMain = reinterpret_cast<FuncType>(dlsym(nwebRenderHandle, "NWebRenderMain")); 14669570cc8Sopenharmony_ci if (funcNWebRenderMain == nullptr) { 14769570cc8Sopenharmony_ci APPSPAWN_LOGE("webviewspawn dlsym errno: %{public}d", errno); 14869570cc8Sopenharmony_ci return -1; 14969570cc8Sopenharmony_ci } 15069570cc8Sopenharmony_ci AppSpawnEnvClear(content, client); 15169570cc8Sopenharmony_ci APPSPAWN_LOGI("RunChildProcessorNweb %{public}s", renderStr.c_str()); 15269570cc8Sopenharmony_ci funcNWebRenderMain(renderStr.c_str()); 15369570cc8Sopenharmony_ci return 0; 15469570cc8Sopenharmony_ci} 15569570cc8Sopenharmony_ci 15669570cc8Sopenharmony_cistatic int PreLoadNwebSpawn(AppSpawnMgr *content) 15769570cc8Sopenharmony_ci{ 15869570cc8Sopenharmony_ci APPSPAWN_LOGI("PreLoadNwebSpawn %{public}d", IsNWebSpawnMode(content)); 15969570cc8Sopenharmony_ci if (!IsNWebSpawnMode(content)) { 16069570cc8Sopenharmony_ci return 0; 16169570cc8Sopenharmony_ci } 16269570cc8Sopenharmony_ci // register 16369570cc8Sopenharmony_ci RegChildLooper(&content->content, RunChildProcessor); 16469570cc8Sopenharmony_ci return 0; 16569570cc8Sopenharmony_ci} 16669570cc8Sopenharmony_ci 16769570cc8Sopenharmony_ciMODULE_CONSTRUCTOR(void) 16869570cc8Sopenharmony_ci{ 16969570cc8Sopenharmony_ci APPSPAWN_LOGI("Load nweb module ..."); 17069570cc8Sopenharmony_ci AddPreloadHook(HOOK_PRIO_HIGHEST, PreLoadNwebSpawn); 17169570cc8Sopenharmony_ci} 172