1 /*
2 * Copyright (c) 2023 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
3 * Licensed under the Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9 * PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 */
12
13 #include <dirent.h>
14 #include <errno.h>
15 #include <fcntl.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <sys/stat.h>
20 #include <unistd.h>
21
22 #include <chcore/bug.h>
23 #include <chcore/defs.h>
24 #include <chcore-internal/procmgr_defs.h>
25 #include <chcore/proc.h>
26 #include <chcore/ipc.h>
27 #include <chcore/syscall.h>
28 #include <chcore/launcher.h>
29 #include <chcore/memory.h>
30
31 #ifdef CHCORE_OH_TEE
chcore_new_process_spawn(int argc,char * __argv[],char ** envp,const posix_spawnattr_t * attr,int * tid,const char * path)32 pid_t chcore_new_process_spawn(int argc, char *__argv[], char **envp,
33 const posix_spawnattr_t *attr, int *tid,
34 const char *path)
35 {
36 int ret;
37 const int MAX_ARGC = 128;
38 char *argv[MAX_ARGC];
39 int i;
40 int envp_argc;
41 struct proc_request *pr;
42 ipc_msg_t *ipc_msg;
43 int text_i;
44
45 if (argc + 1 >= MAX_ARGC) {
46 ret = -EINVAL;
47 goto out_fail;
48 }
49
50 if (strlen(path) >= PROC_REQ_NAME_LEN) {
51 ret = -ENAMETOOLONG;
52 goto out_fail;
53 }
54
55 ipc_msg = ipc_create_msg(procmgr_ipc_struct, sizeof(struct proc_request));
56 pr = (struct proc_request *)ipc_get_msg_data(ipc_msg);
57
58 pr->req = PROC_REQ_SPAWN;
59 pr->spawn.argc = argc;
60 if (attr == NULL) {
61 pr->spawn.attr_valid = 0;
62 } else {
63 pr->spawn.attr_valid = 1;
64 memcpy(&pr->spawn.attr, attr, sizeof(*attr));
65 }
66
67 memcpy(&pr->spawn.path, path, strlen(path));
68 pr->spawn.path[strlen(path)] = 0;
69
70 for (i = 0, text_i = 0; i < argc; ++i) {
71 /* Plus 1 for the trailing \0. */
72 int len = strlen(__argv[i]) + 1;
73 if (text_i + len > PROC_REQ_TEXT_SIZE) {
74 ret = -EINVAL;
75 goto out_destroy_msg;
76 }
77
78 memcpy(&pr->spawn.argv_text[text_i], __argv[i], len);
79
80 pr->spawn.argv_off[i] = text_i;
81 text_i += len;
82 }
83
84 i = 0;
85 if (envp != NULL) {
86 for (text_i = 0; envp[i] != NULL; ++i) {
87 int len = strlen(envp[i]) + 1;
88 if (text_i + len > PROC_REQ_ENV_TEXT_SIZE) {
89 ret = -EINVAL;
90 goto out_destroy_msg;
91 }
92
93 memcpy(&pr->spawn.envp_text[text_i], envp[i], len);
94
95 pr->spawn.envp_off[i] = text_i;
96 text_i += len;
97 }
98 }
99
100 pr->spawn.envc = i;
101
102 ret = ipc_call(procmgr_ipc_struct, ipc_msg);
103 if (ret >= 0 && tid != NULL) {
104 *tid = pr->spawn.main_thread_id;
105 }
106
107 out_destroy_msg:
108 ipc_destroy_msg(ipc_msg);
109
110 out_fail:
111 return ret;
112 }
113 #endif /* CHCORE_OH_TEE */
114
chcore_new_process(int argc,char * __argv[],int is_bbapplet)115 pid_t chcore_new_process(int argc, char *__argv[], int is_bbapplet)
116 {
117 int ret;
118 cap_t caps[3];
119 const int MAX_ARGC = 128;
120 char *argv[MAX_ARGC];
121 int i;
122 int argv_start;
123 struct proc_request *pr;
124 ipc_msg_t *ipc_msg;
125 int text_i;
126
127 if (argc + 1 >= MAX_ARGC) {
128 ret = -EINVAL;
129 goto out_fail;
130 }
131 /*
132 * Reserve argv[0] for busybox applets.
133 * Dynamic loaders are handled by procmgr.
134 */
135 argv_start = 1;
136 for (i = 0; i < argc; ++i)
137 argv[i + argv_start] = __argv[i];
138
139 if (is_bbapplet) {
140 /* This is a busybox applet. Invoke busybox. */
141 argv[0] = "/busybox";
142 argv_start = 0;
143 argc += 1;
144 }
145
146 ipc_msg = ipc_create_msg(procmgr_ipc_struct, sizeof(struct proc_request));
147 pr = (struct proc_request *)ipc_get_msg_data(ipc_msg);
148
149 pr->req = PROC_REQ_NEWPROC;
150 pr->newproc.argc = argc;
151
152 /* Dump argv[] to the text area of the pr. */
153 for (i = 0, text_i = 0; i < argc; ++i) {
154 /* Plus 1 for the trailing \0. */
155 int len = strlen(argv[argv_start + i]) + 1;
156 if (text_i + len > PROC_REQ_TEXT_SIZE) {
157 ret = -EINVAL;
158 goto out_destroy_msg;
159 }
160
161 memcpy(&pr->newproc.argv_text[text_i], argv[argv_start + i], len);
162
163 pr->newproc.argv_off[i] = text_i;
164 text_i += len;
165 }
166
167 ret = ipc_call(procmgr_ipc_struct, ipc_msg);
168
169 out_destroy_msg:
170 ipc_destroy_msg(ipc_msg);
171
172 out_fail:
173 return ret;
174 }
175
get_new_process_mt_cap(int pid)176 int get_new_process_mt_cap(int pid)
177 {
178 ipc_msg_t *ipc_msg;
179 struct proc_request *pr;
180 cap_t mt_cap;
181
182 ipc_msg = ipc_create_msg(procmgr_ipc_struct, sizeof(struct proc_request));
183
184 pr = (struct proc_request *)ipc_get_msg_data(ipc_msg);
185 pr->req = PROC_REQ_GET_MT_CAP;
186 pr->get_mt_cap.pid = pid;
187
188 ipc_call(procmgr_ipc_struct, ipc_msg);
189 mt_cap = ipc_get_msg_cap(ipc_msg, 0);
190 ipc_destroy_msg(ipc_msg);
191
192 return mt_cap;
193 }
194
create_process(int argc,char * __argv[],struct new_process_caps * caps)195 int create_process(int argc, char *__argv[], struct new_process_caps *caps)
196 {
197 pid_t pid;
198 pid = chcore_new_process(argc, __argv, 0);
199 if (caps != NULL)
200 caps->mt_cap = get_new_process_mt_cap(pid);
201 return pid;
202 }
203