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 
NWebSpawnInit(void)48 void 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 
NWebSpawnLaunch(void)88 pid_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 }