• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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