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#include <fcntl.h>
16#include <grp.h>
17#include <inttypes.h>
18#include <limits.h>
19#include <sys/capability.h>
20#include <stdbool.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <sys/ioctl.h>
25#include <sys/mount.h>
26#include <sys/prctl.h>
27#include <sys/signalfd.h>
28#include <sys/stat.h>
29#include <sys/syscall.h>
30#include <sys/types.h>
31#include <sys/wait.h>
32#include <unistd.h>
33
34#undef _GNU_SOURCE
35#define _GNU_SOURCE
36#include <dlfcn.h>
37#include <malloc.h>
38#include <sched.h>
39
40#include "appspawn_adapter.h"
41#include "appspawn_hook.h"
42#include "appspawn_service.h"
43#include "appspawn_msg.h"
44#include "appspawn_manager.h"
45#include "appspawn_silk.h"
46#include "init_param.h"
47#include "parameter.h"
48#include "securec.h"
49
50#ifdef CODE_SIGNATURE_ENABLE  // for xpm
51#include "code_sign_attr_utils.h"
52#endif
53#ifdef SECURITY_COMPONENT_ENABLE
54#include "sec_comp_enhance_kit_c.h"
55#endif
56#ifdef WITH_SELINUX
57#include "selinux/selinux.h"
58#endif
59
60#define PROVISION_TYPE_DEBUG "debug"
61#define DEVICE_NULL_STR "/dev/null"
62#define BITLEN32 32
63#define PID_NS_INIT_UID 100000  // reserved for pid_ns_init process, avoid app, render proc, etc.
64#define PID_NS_INIT_GID 100000
65
66static int SetProcessName(const AppSpawnMgr *content, const AppSpawningCtx *property)
67{
68    const char *processName = GetProcessName(property);
69    APPSPAWN_CHECK(processName != NULL, return -EINVAL, "Can not get process name");
70    // 解析时已经检查
71    size_t len = strlen(processName);
72    char shortName[MAX_LEN_SHORT_NAME] = {0};
73    // process short name max length 16 bytes.
74    size_t copyLen = len;
75    const char *pos = processName;
76    if (len >= MAX_LEN_SHORT_NAME) {
77        copyLen = MAX_LEN_SHORT_NAME - 1;
78        pos += (len - copyLen);
79    }
80    bool isRet = strncpy_s(shortName, MAX_LEN_SHORT_NAME, pos, copyLen) != EOK;
81    APPSPAWN_CHECK(!isRet, return EINVAL, "strncpy_s short name error: %{public}d", errno);
82
83    // set short name
84    isRet = prctl(PR_SET_NAME, shortName) == -1;
85    APPSPAWN_CHECK(!isRet, return errno, "prctl(PR_SET_NAME) error: %{public}d", errno);
86
87    // reset longProcName
88    isRet = memset_s(content->content.longProcName,
89        (size_t)content->content.longProcNameLen, 0, (size_t)content->content.longProcNameLen) != EOK;
90    APPSPAWN_CHECK(!isRet, return EINVAL, "Failed to memset long process name");
91
92    // set long process name
93    isRet = strncpy_s(content->content.longProcName, content->content.longProcNameLen, processName, len) != EOK;
94    APPSPAWN_CHECK(!isRet, return EINVAL,
95        "strncpy_s long name error: %{public}d longProcNameLen %{public}u", errno, content->content.longProcNameLen);
96    return 0;
97}
98
99static int SetKeepCapabilities(const AppSpawnMgr *content, const AppSpawningCtx *property)
100{
101    AppSpawnMsgDacInfo *dacInfo = (AppSpawnMsgDacInfo *)GetAppProperty(property, TLV_DAC_INFO);
102    APPSPAWN_CHECK(dacInfo != NULL, return APPSPAWN_TLV_NONE,
103        "No tlv %{public}d in msg %{public}s", TLV_DOMAIN_INFO, GetProcessName(property));
104
105    // set keep capabilities when user not root.
106    if (dacInfo->uid != 0) {
107        bool isRet = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1;
108        APPSPAWN_CHECK(!isRet, return errno, "set keepcaps failed: %{public}d", errno);
109    }
110    return 0;
111}
112
113static int SetCapabilities(const AppSpawnMgr *content, const AppSpawningCtx *property)
114{
115    // init cap
116    struct __user_cap_header_struct capHeader;
117
118    bool isRet = memset_s(&capHeader, sizeof(capHeader), 0, sizeof(capHeader)) != EOK;
119    APPSPAWN_CHECK(!isRet, return -EINVAL, "Failed to memset cap header");
120
121    capHeader.version = _LINUX_CAPABILITY_VERSION_3;
122    capHeader.pid = 0;
123
124    struct __user_cap_data_struct capData[2]; // 2 is data number
125    isRet = memset_s(&capData, sizeof(capData), 0, sizeof(capData)) != EOK;
126    APPSPAWN_CHECK(!isRet, return -EINVAL, "Failed to memset cap data");
127
128    // init inheritable permitted effective zero
129#ifdef GRAPHIC_PERMISSION_CHECK
130    const uint64_t inheriTable = 0;
131    const uint64_t permitted = 0;
132    const uint64_t effective = 0;
133#else
134    const uint64_t inheriTable = 0x3fffffffff;
135    const uint64_t permitted = 0x3fffffffff;
136    const uint64_t effective = 0x3fffffffff;
137#endif
138
139    capData[0].inheritable = (__u32)(inheriTable);
140    capData[1].inheritable = (__u32)(inheriTable >> BITLEN32);
141    capData[0].permitted = (__u32)(permitted);
142    capData[1].permitted = (__u32)(permitted >> BITLEN32);
143    capData[0].effective = (__u32)(effective);
144    capData[1].effective = (__u32)(effective >> BITLEN32);
145
146    // set capabilities
147    isRet = capset(&capHeader, &capData[0]) != 0;
148    APPSPAWN_CHECK(!isRet, return -errno, "Failed to capset errno: %{public}d", errno);
149    return 0;
150}
151
152static void InitDebugParams(const AppSpawnMgr *content, const AppSpawningCtx *property)
153{
154#if defined(__aarch64__) || defined(__x86_64__)
155    const char *debugSoPath = "/system/lib64/libhidebug.so";
156#else
157    const char *debugSoPath = "/system/lib/libhidebug.so";
158#endif
159    const char *processName = GetProcessName(property);
160    APPSPAWN_CHECK(processName != NULL, return, "Can not get process name");
161
162    bool isRet = access(debugSoPath, F_OK) != 0;
163    APPSPAWN_CHECK(!isRet, return,
164        "access failed, errno: %{public}d debugSoPath: %{public}s", errno, debugSoPath);
165
166    void *handle = dlopen(debugSoPath, RTLD_LAZY);
167    APPSPAWN_CHECK(handle != NULL, return, "Failed to dlopen libhidebug.so errno: %{public}s", dlerror());
168
169    bool (*initParam)(const char *name);
170    initParam = (bool (*)(const char *name))dlsym(handle, "InitEnvironmentParam");
171    APPSPAWN_CHECK(initParam != NULL, dlclose(handle);
172        return, "Failed to dlsym errno: %{public}s", dlerror());
173    (*initParam)(processName);
174    dlclose(handle);
175}
176
177static void ClearEnvironment(const AppSpawnMgr *content, const AppSpawningCtx *property)
178{
179    sigset_t mask;
180    sigemptyset(&mask);
181    sigaddset(&mask, SIGCHLD);
182    sigaddset(&mask, SIGTERM);
183    sigprocmask(SIG_UNBLOCK, &mask, NULL);
184    // close child fd
185    AppSpawningCtx *ctx = (AppSpawningCtx *)property;
186    close(ctx->forkCtx.fd[0]);
187    ctx->forkCtx.fd[0] = -1;
188    return;
189}
190
191static int SetXpmConfig(const AppSpawnMgr *content, const AppSpawningCtx *property)
192{
193#ifdef CODE_SIGNATURE_ENABLE
194    // nwebspawn no permission set xpm config
195    if (IsNWebSpawnMode(content)) {
196        return 0;
197    }
198
199    uint32_t len = 0;
200    char *provisionType = GetAppPropertyExt(property, MSG_EXT_NAME_PROVISION_TYPE, &len);
201    if (provisionType == NULL || len == 0) {
202        APPSPAWN_LOGE("get provision type failed, defaut is %{public}s", PROVISION_TYPE_DEBUG);
203        provisionType = PROVISION_TYPE_DEBUG;
204    }
205
206    AppSpawnMsgOwnerId *ownerInfo = (AppSpawnMsgOwnerId *)GetAppProperty(property, TLV_OWNER_INFO);
207    int jitfortEnable = IsJitFortModeOn(property) ? 1 : 0;
208    int idType = PROCESS_OWNERID_UNINIT;
209    const char *ownerId = NULL;
210    if (strcmp(provisionType, PROVISION_TYPE_DEBUG) == 0) {
211        idType = PROCESS_OWNERID_DEBUG;
212    } else if (ownerInfo == NULL) {
213        idType = PROCESS_OWNERID_COMPAT;
214    } else if (CheckAppMsgFlagsSet(property, APP_FLAGS_TEMP_JIT)) {
215        idType = PROCESS_OWNERID_APP_TEMP_ALLOW;
216        ownerId = ownerInfo->ownerId;
217    } else {
218        idType = PROCESS_OWNERID_APP;
219        ownerId = ownerInfo->ownerId;
220    }
221    int ret = InitXpm(jitfortEnable, idType, ownerId);
222    APPSPAWN_CHECK(ret == 0, return ret, "set xpm region failed: %{public}d", ret);
223#endif
224    return 0;
225}
226
227static int SetUidGid(const AppSpawnMgr *content, const AppSpawningCtx *property)
228{
229    AppSpawnMsgDacInfo *dacInfo = (AppSpawnMsgDacInfo *)GetAppProperty(property, TLV_DAC_INFO);
230    APPSPAWN_CHECK(dacInfo != NULL, return APPSPAWN_TLV_NONE,
231        "No tlv %{public}d in msg %{public}s", TLV_DAC_INFO, GetProcessName(property));
232
233    // set gids
234    int ret = setgroups(dacInfo->gidCount, (const gid_t *)(&dacInfo->gidTable[0]));
235    APPSPAWN_CHECK(ret == 0, return errno,
236        "setgroups failed: %{public}d, gids.size=%{public}u", errno, dacInfo->gidCount);
237
238    // set gid
239    if (IsNWebSpawnMode(content)) {
240        gid_t gid = dacInfo->gid / UID_BASE;
241        if (gid >= 100) { // 100
242            APPSPAWN_LOGE("SetUidGid invalid uid for nwebspawn %{public}d", dacInfo->gid);
243            return 0;
244        }
245        ret = setresgid(dacInfo->gid, dacInfo->gid, dacInfo->gid);
246    } else {
247        ret = setresgid(dacInfo->gid, dacInfo->gid, dacInfo->gid);
248    }
249    APPSPAWN_CHECK(ret == 0, return errno,
250        "setgid(%{public}u) failed: %{public}d", dacInfo->gid, errno);
251
252    ret = SetSeccompFilter(content, property);
253    APPSPAWN_CHECK(ret == 0, return ret, "Failed to set setSeccompFilter");
254
255    /* If the effective user ID is changed from 0 to nonzero,
256     * then all capabilities are cleared from the effective set
257     */
258    ret = setresuid(dacInfo->uid, dacInfo->uid, dacInfo->uid);
259    APPSPAWN_CHECK(ret == 0, return errno,
260        "setuid(%{public}u) failed: %{public}d", dacInfo->uid, errno);
261
262    if (CheckAppMsgFlagsSet(property, APP_FLAGS_DEBUGGABLE) && IsDeveloperModeOn(property)) {
263        setenv("HAP_DEBUGGABLE", "true", 1);
264        if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) {
265            APPSPAWN_LOGE("Failed to set app dumpable: %{public}s", strerror(errno));
266        }
267    } else {
268        setenv("HAP_DEBUGGABLE", "false", 1);
269    }
270    return 0;
271}
272
273static int32_t SetFileDescriptors(const AppSpawnMgr *content, const AppSpawningCtx *property)
274{
275#ifndef APPSPAWN_TEST
276    // redirect stdin stdout stderr to /dev/null
277    int devNullFd = open(DEVICE_NULL_STR, O_RDWR);
278    if (devNullFd == -1) {
279        APPSPAWN_LOGE("open dev_null error: %{public}d", errno);
280        return (-errno);
281    }
282
283    // stdin
284    if (dup2(devNullFd, STDIN_FILENO) == -1) {
285        APPSPAWN_LOGE("dup2 STDIN error: %{public}d", errno);
286        return (-errno);
287    }
288    // stdout
289    if (dup2(devNullFd, STDOUT_FILENO) == -1) {
290        APPSPAWN_LOGE("dup2 STDOUT error: %{public}d", errno);
291        return (-errno);
292    }
293    // stderr
294    if (dup2(devNullFd, STDERR_FILENO) == -1) {
295        APPSPAWN_LOGE("dup2 STDERR error: %{public}d", errno);
296        return (-errno);
297    }
298
299    if (devNullFd > STDERR_FILENO) {
300        close(devNullFd);
301    }
302#endif
303    return 0;
304}
305
306static int32_t CheckTraceStatus(void)
307{
308    int fd = open("/proc/self/status", O_RDONLY);
309    APPSPAWN_CHECK(fd >= 0, return errno, "Failed to open /proc/self/status error: %{public}d", errno);
310
311    char data[1024] = {0};  // 1024 is data length
312    ssize_t dataNum = read(fd, data, sizeof(data) - 1);
313    (void)close(fd);
314    APPSPAWN_CHECK(dataNum > 0, return -1, "Failed to read file /proc/self/status error: %{public}d", errno);
315
316    const char *tracerPid = "TracerPid:\t";
317    data[dataNum] = '\0';
318    char *traceStr = strstr(data, tracerPid);
319    APPSPAWN_CHECK(traceStr != NULL, return -1, "Not found %{public}s", tracerPid);
320
321    char *separator = strchr(traceStr, '\n');
322    APPSPAWN_CHECK(separator != NULL, return -1, "Not found %{public}s", "\n");
323
324    int len = separator - traceStr - strlen(tracerPid);
325    char pid = *(traceStr + strlen(tracerPid));
326    if (len > 1 || pid != '0') {
327        return 0;
328    }
329    return -1;
330}
331
332static int32_t WaitForDebugger(const AppSpawningCtx *property)
333{
334    // wait for debugger only debugging is required and process is debuggable
335    if (CheckAppMsgFlagsSet(property, APP_FLAGS_NATIVEDEBUG) && CheckAppMsgFlagsSet(property, APP_FLAGS_DEBUGGABLE)) {
336        uint32_t count = 0;
337        while (CheckTraceStatus() != 0) {
338#ifndef APPSPAWN_TEST
339            usleep(1000 * 100);  // sleep 1000 * 100 microsecond
340#else
341            if (count > 0) {
342                break;
343            }
344#endif
345            count++;
346            // remind users to connect to the debugger every 60 * 10 times
347            if (count % (10 * 60) == 0) {
348                count = 0;
349                APPSPAWN_LOGI("wait for debugger, please attach the process");
350            }
351        }
352    }
353    return 0;
354}
355
356static int SpawnInitSpawningEnv(AppSpawnMgr *content, AppSpawningCtx *property)
357{
358    APPSPAWN_LOGV("Spawning: clear env");
359    int ret = SetProcessName(content, property);
360    APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
361    // close socket id and signal for child
362    ClearEnvironment(content, property);
363
364    ResetParamSecurityLabel();
365
366    ret = SetAppAccessToken(content, property);
367    APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
368    return 0;
369}
370
371static int SpawnSetAppEnv(AppSpawnMgr *content, AppSpawningCtx *property)
372{
373    APPSPAWN_LOGV("Spawning: set appEnv");
374    int ret = SetEnvInfo(content, property);
375    APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
376    return 0;
377}
378
379static int SpawnSetIntPermission(AppSpawnMgr *content, AppSpawningCtx *property)
380{
381    APPSPAWN_LOGV("Spawning: set Internet Permission for app process");
382    int ret = SetInternetPermission(property);
383    APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
384    return ret;
385}
386
387static void SpawnLoadSilk(const AppSpawnMgr *content, const AppSpawningCtx *property)
388{
389    const char *processName = GetBundleName(property);
390    APPSPAWN_CHECK(processName != NULL, return, "Can not get bundle name");
391    LoadSilkLibrary(processName);
392}
393
394static int SpawnSetProperties(AppSpawnMgr *content, AppSpawningCtx *property)
395{
396    APPSPAWN_LOGV("Spawning: set child property");
397    SpawnLoadSilk(content, property);
398    (void)umask(DEFAULT_UMASK);
399    int ret = SetKeepCapabilities(content, property);
400    APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
401    ret = SetXpmConfig(content, property);
402    APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
403
404    ret = SetProcessName(content, property);
405    APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
406
407    ret = SetUidGid(content, property);
408    APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
409
410    ret = SetFileDescriptors(content, property);
411    APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
412
413    ret = SetCapabilities(content, property);
414    APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
415
416    ret = SetSelinuxCon(content, property) == -1;
417    APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
418
419    ret = WaitForDebugger(property);
420    APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
421
422    APPSPAWN_ONLY_EXPER(GetAppSpawnMsgType(property) == MSG_SPAWN_NATIVE_PROCESS, return 0);
423#ifdef SECURITY_COMPONENT_ENABLE
424    InitSecCompClientEnhance();
425#endif
426    return 0;
427}
428
429static int PreLoadSetSeccompFilter(AppSpawnMgr *content)
430{
431    // set uid gid filetr
432    int ret = SetUidGidFilter(content);
433    APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
434    return ret;
435}
436
437static int SpawnComplete(AppSpawnMgr *content, AppSpawningCtx *property)
438{
439    InitDebugParams(content, property);
440    return 0;
441}
442
443static int CheckEnabled(const char *param, const char *value)
444{
445    char tmp[32] = {0};  // 32 max
446    int ret = GetParameter(param, "", tmp, sizeof(tmp));
447    APPSPAWN_LOGV("CheckEnabled key %{public}s ret %{public}d result: %{public}s", param, ret, tmp);
448    int enabled = (ret > 0 && strcmp(tmp, value) == 0);
449    return enabled;
450}
451
452static int SpawnGetSpawningFlag(AppSpawnMgr *content, AppSpawningCtx *property)
453{
454    APPSPAWN_LOGV("Spawning: prepare app %{public}s", GetProcessName(property));
455    if (CheckAppMsgFlagsSet(property, APP_FLAGS_COLD_BOOT)) {
456        // check cold start
457        property->client.flags |= CheckEnabled("startup.appspawn.cold.boot", "true") ? APP_COLD_START : 0;
458    }
459    if (CheckAppMsgFlagsSet(property, APP_FLAGS_BEGETCTL_BOOT)) {
460       // Start app from begetctl for debugging.
461        property->client.flags |=  APP_BEGETCTL_BOOT;
462        APPSPAWN_LOGI("Spawning: prepare app %{public}s, start from begetctl", GetProcessName(property));
463    }
464    property->client.flags |= content->flags;
465    return 0;
466}
467
468static int SpawnLoadConfig(AppSpawnMgr *content)
469{
470    LoadSilkConfig();
471    // init flags that will not change until next reboot
472    content->flags |= CheckEnabled("const.security.developermode.state", "true") ? APP_DEVELOPER_MODE : 0;
473    content->flags |= CheckEnabled("persist.security.jitfort.disabled", "true") ? 0 : APP_JITFORT_MODE;
474    return 0;
475}
476
477static int CloseFdArgs(AppSpawnMgr *content, AppSpawningCtx *property)
478{
479    APPSPAWN_CHECK(property != NULL && property->message != NULL
480        && property->message->connection != NULL,
481        return -1, "Get connection info failed");
482    int fdCount = property->message->connection->receiverCtx.fdCount;
483    int *fds = property->message->connection->receiverCtx.fds;
484    if (fds != NULL && fdCount > 0) {
485        for (int i = 0; i < fdCount; i++) {
486            if (fds[i] > 0) {
487                close(fds[i]);
488            }
489        }
490    }
491    property->message->connection->receiverCtx.fdCount = 0;
492    return 0;
493}
494
495APPSPAWN_STATIC int SetFdEnv(AppSpawnMgr *content, AppSpawningCtx *property)
496{
497    APPSPAWN_CHECK_ONLY_EXPER(property != NULL, return -1);
498    APPSPAWN_CHECK_ONLY_EXPER(!property->isPrefork, return 0);
499    AppSpawnMsgNode *message = property->message;
500    APPSPAWN_CHECK_ONLY_EXPER(message != NULL && message->buffer != NULL && message->connection != NULL, return -1);
501    APPSPAWN_CHECK_ONLY_EXPER(message->tlvOffset != NULL, return -1);
502    int findFdIndex = 0;
503    AppSpawnMsgReceiverCtx recvCtx = message->connection->receiverCtx;
504    APPSPAWN_CHECK(recvCtx.fds != NULL && recvCtx.fdCount > 0, return 0,
505        "no need set fd info %{public}d, %{public}d", recvCtx.fds != NULL, recvCtx.fdCount);
506    char keyBuffer[APP_FDNAME_MAXLEN + sizeof(APP_FDENV_PREFIX)];
507    char value[sizeof(int)];
508
509    for (uint32_t index = TLV_MAX; index < (TLV_MAX + message->tlvCount); index++) {
510        if (message->tlvOffset[index] == INVALID_OFFSET) {
511            return -1;
512        }
513        uint8_t *data = message->buffer + message->tlvOffset[index];
514        if (((AppSpawnTlv *)data)->tlvType != TLV_MAX) {
515            continue;
516        }
517        AppSpawnTlvExt *tlv = (AppSpawnTlvExt *)data;
518        if (strcmp(tlv->tlvName, MSG_EXT_NAME_APP_FD) != 0) {
519            continue;
520        }
521        APPSPAWN_CHECK(findFdIndex < recvCtx.fdCount && recvCtx.fds[findFdIndex] > 0, return -1,
522            "check set env args failed %{public}d, %{public}d, %{public}d",
523            findFdIndex, recvCtx.fdCount, recvCtx.fds[findFdIndex]);
524        APPSPAWN_CHECK(snprintf_s(keyBuffer, sizeof(keyBuffer), sizeof(keyBuffer) - 1, APP_FDENV_PREFIX"%s",
525            data + sizeof(AppSpawnTlvExt)) >= 0, return -1, "failed print env key %{public}d", errno);
526        APPSPAWN_CHECK(snprintf_s(value, sizeof(value), sizeof(value) - 1,
527            "%d", recvCtx.fds[findFdIndex++]) >= 0, return -1, "failed print env key %{public}d", errno);
528        int ret = setenv(keyBuffer, value, 1);
529        APPSPAWN_CHECK(ret == 0, return -1, "failed setenv %{public}s, %{public}s", keyBuffer, value);
530        if (findFdIndex >= recvCtx.fdCount) {
531            break;
532        }
533    }
534    return 0;
535}
536
537MODULE_CONSTRUCTOR(void)
538{
539    APPSPAWN_LOGV("Load common module ...");
540    AddPreloadHook(HOOK_PRIO_COMMON, PreLoadSetSeccompFilter);
541    AddPreloadHook(HOOK_PRIO_COMMON, SpawnLoadConfig);
542
543    AddAppSpawnHook(STAGE_PARENT_PRE_FORK, HOOK_PRIO_HIGHEST, SpawnGetSpawningFlag);
544    AddAppSpawnHook(STAGE_CHILD_PRE_COLDBOOT, HOOK_PRIO_HIGHEST, SpawnInitSpawningEnv);
545    AddAppSpawnHook(STAGE_CHILD_PRE_COLDBOOT, HOOK_PRIO_COMMON + 1, SpawnSetAppEnv);
546    AddAppSpawnHook(STAGE_CHILD_EXECUTE, HOOK_PRIO_HIGHEST, SpawnSetIntPermission);
547    AddAppSpawnHook(STAGE_CHILD_EXECUTE, HOOK_PRIO_PROPERTY, SpawnSetProperties);
548    AddAppSpawnHook(STAGE_CHILD_POST_RELY, HOOK_PRIO_HIGHEST, SpawnComplete);
549    AddAppSpawnHook(STAGE_PARENT_POST_FORK, HOOK_PRIO_HIGHEST, CloseFdArgs);
550    AddAppSpawnHook(STAGE_CHILD_PRE_COLDBOOT, HOOK_PRIO_HIGHEST, SetFdEnv);
551}
552