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 <sched.h>
16#include <signal.h>
17#include <stdbool.h>
18#include <stdlib.h>
19#include <unistd.h>
20
21#include <sys/capability.h>
22#include <sys/prctl.h>
23#include <sys/resource.h>
24
25#include "appspawn.h"
26#include "appspawn_modulemgr.h"
27#include "appspawn_msg.h"
28#include "appspawn_server.h"
29#include "appspawn_service.h"
30#include "appspawn_utils.h"
31#include "parameter.h"
32#include "securec.h"
33
34#ifdef CODE_SIGNATURE_ENABLE
35#include "code_sign_attr_utils.h"
36#endif
37#ifdef WITH_SELINUX
38#include "selinux/selinux.h"
39#endif
40
41#define NWEB_UID 3081
42#define NWEB_GID 3081
43#define NWEB_NAME "nwebspawn"
44#define NATIVE_NAME "nativespawn"
45#define CAP_NUM 2
46#define BITLEN32 32
47
48void NWebSpawnInit(void)
49{
50    APPSPAWN_LOGI("NWebSpawnInit");
51#ifdef CODE_SIGNATURE_ENABLE
52    // ownerId must been set before setcon & setuid
53    (void)SetXpmOwnerId(PROCESS_OWNERID_NWEB, NULL);
54#endif
55#ifdef WITH_SELINUX
56    setcon("u:r:nwebspawn:s0");
57#endif
58    pid_t pid = getpid();
59    setpriority(PRIO_PROCESS, pid, 0);
60    struct  __user_cap_header_struct capHeader;
61    capHeader.version = _LINUX_CAPABILITY_VERSION_3;
62    capHeader.pid = 0;
63    // old CAP_SYS_ADMIN | CAP_SETGID | CAP_SETUID
64    const uint64_t inheriTable = CAP_TO_MASK(CAP_SYS_ADMIN) | CAP_TO_MASK(CAP_SETGID) |
65        CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_KILL);
66    const uint64_t permitted = inheriTable;
67    const uint64_t effective = inheriTable;
68    struct __user_cap_data_struct capData[CAP_NUM] = {};
69    for (int j = 0; j < CAP_NUM; ++j) {
70        capData[0].inheritable = (__u32)(inheriTable);
71        capData[1].inheritable = (__u32)(inheriTable >> BITLEN32);
72        capData[0].permitted = (__u32)(permitted);
73        capData[1].permitted = (__u32)(permitted >> BITLEN32);
74        capData[0].effective = (__u32)(effective);
75        capData[1].effective = (__u32)(effective >> BITLEN32);
76    }
77    capset(&capHeader, capData);
78    for (int i = 0; i <= CAP_LAST_CAP; ++i) {
79        prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, i, 0, 0);
80    }
81#ifndef APPSPAWN_TEST
82    (void)prctl(PR_SET_NAME, NWEB_NAME);
83#endif
84    setuid(NWEB_UID);
85    setgid(NWEB_GID);
86}
87
88pid_t NWebSpawnLaunch(void)
89{
90    pid_t ret = fork();
91    if (ret == 0) {
92        NWebSpawnInit();
93    }
94    APPSPAWN_LOGI("nwebspawn fork success pid: %{public}d", ret);
95    return ret;
96}