• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <algorithm>
17 #include <cerrno>
18 #include <ctime>
19 #include <dlfcn.h>
20 #include <map>
21 #include <mutex>
22 #include <string>
23 
24 #ifdef __MUSL__
25 #include <cerrno>
26 #include <dlfcn_ext.h>
27 #include <sys/mman.h>
28 #endif
29 
30 #include "appspawn_hook.h"
31 #include "appspawn_manager.h"
32 
33 #ifdef WITH_SECCOMP
34 #include "seccomp_policy.h"
35 #endif
36 
37 namespace {
38 #if defined(webview_arm64)
39     const std::string NWEB_HAP_LIB_PATH = "/data/storage/el1/bundle/nweb/libs/arm64";
40 #elif defined(webview_x86_64)
41     const std::string NWEB_HAP_LIB_PATH = "/data/storage/el1/bundle/nweb/libs/x86_64";
42 #else
43     const std::string NWEB_HAP_LIB_PATH = "/data/storage/el1/bundle/nweb/libs/arm";
44 #endif
45 }  // namespace
46 
SetSeccompPolicyForRenderer(void * nwebRenderHandle)47 static bool SetSeccompPolicyForRenderer(void *nwebRenderHandle)
48 {
49 #ifdef WITH_SECCOMP
50     if (IsEnableSeccomp()) {
51         using SeccompFuncType = bool (*)(void);
52         SeccompFuncType funcSetRendererSeccompPolicy =
53                 reinterpret_cast<SeccompFuncType>(dlsym(nwebRenderHandle, "SetRendererSeccompPolicy"));
54         if (funcSetRendererSeccompPolicy != nullptr && funcSetRendererSeccompPolicy()) {
55             return true;
56         }
57         APPSPAWN_LOGE("SetRendererSeccompPolicy dlsym errno: %{public}d", errno);
58         return false;
59     }
60 #endif
61     return true;
62 }
63 
RunChildProcessor(AppSpawnContent * content,AppSpawnClient * client)64 static int RunChildProcessor(AppSpawnContent *content, AppSpawnClient *client)
65 {
66     uint32_t len = 0;
67     char *renderCmd = reinterpret_cast<char *>(GetAppPropertyExt(
68         reinterpret_cast<AppSpawningCtx *>(client), MSG_EXT_NAME_RENDER_CMD, &len));
69     if (renderCmd == nullptr) {
70         return -1;
71     }
72     std::string renderStr(renderCmd);
73     void *webEngineHandle = nullptr;
74     void *nwebRenderHandle = nullptr;
75 #ifdef __MUSL__
76     Dl_namespace dlns;
77     dlns_init(&dlns, "nweb_ns");
78     dlns_create(&dlns, NWEB_HAP_LIB_PATH.c_str());
79 
80     // preload libweb_engine
81     webEngineHandle = dlopen_ns(&dlns, "libweb_engine.so", RTLD_NOW | RTLD_GLOBAL);
82 
83     // load libnweb_render
84     nwebRenderHandle = dlopen_ns(&dlns, "libnweb_render.so", RTLD_NOW | RTLD_GLOBAL);
85 #else
86     // preload libweb_engine
87     const std::string engineLibDir = NWEB_HAP_LIB_PATH + "/libweb_engine.so";
88     webEngineHandle = dlopen(engineLibDir.c_str(), RTLD_NOW | RTLD_GLOBAL);
89 
90     // load libnweb_render
91     const std::string renderLibDir = NWEB_HAP_LIB_PATH + "/libnweb_render.so";
92     nwebRenderHandle = dlopen(renderLibDir.c_str(), RTLD_NOW | RTLD_GLOBAL);
93 #endif
94     if (webEngineHandle == nullptr) {
95         APPSPAWN_LOGE("Fail to dlopen libweb_engine.so, errno: %{public}d", errno);
96     }
97 
98     if (nwebRenderHandle == nullptr) {
99         APPSPAWN_LOGE("Fail to dlopen libnweb_render.so, errno: %{public}d", errno);
100         return -1;
101     }
102 
103     if (!SetSeccompPolicyForRenderer(nwebRenderHandle)) {
104         return -1;
105     }
106     using FuncType = void (*)(const char *cmd);
107 
108     FuncType funcNWebRenderMain = reinterpret_cast<FuncType>(dlsym(nwebRenderHandle, "NWebRenderMain"));
109     if (funcNWebRenderMain == nullptr) {
110         APPSPAWN_LOGE("webviewspawn dlsym errno: %{public}d", errno);
111         return -1;
112     }
113     AppSpawnEnvClear(content, client);
114     funcNWebRenderMain(renderStr.c_str());
115     APPSPAWN_LOGI("RunChildProcessorNweb %{public}s", renderStr.c_str());
116     return 0;
117 }
118 
PreLoadNwebSpawn(AppSpawnMgr * content)119 static int PreLoadNwebSpawn(AppSpawnMgr *content)
120 {
121     APPSPAWN_LOGI("PreLoadNwebSpawn %{public}d", IsNWebSpawnMode(content));
122     if (!IsNWebSpawnMode(content)) {
123         return 0;
124     }
125     // register
126     RegChildLooper(&content->content, RunChildProcessor);
127     return 0;
128 }
129 
MODULE_CONSTRUCTOR(void)130 MODULE_CONSTRUCTOR(void)
131 {
132     APPSPAWN_LOGI("Load nweb module ...");
133     AddPreloadHook(HOOK_PRIO_HIGHEST, PreLoadNwebSpawn);
134 }
135