10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 /* Copyright (c) 1988 AT&T */
27 /* All Rights Reserved */
28
29 /*
30 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
31 */
32
33 #include <sys/types.h>
34 #include <sys/param.h>
35 #include <sys/sysmacros.h>
36 #include <sys/pcb.h>
37 #include <sys/systm.h>
38 #include <sys/signal.h>
39 #include <sys/cred.h>
40 #include <sys/user.h>
41 #include <sys/vfs.h>
42 #include <sys/vnode.h>
43 #include <sys/proc.h>
44 #include <sys/time.h>
45 #include <sys/file.h>
46 #include <sys/priocntl.h>
47 #include <sys/procset.h>
48 #include <sys/disp.h>
49 #include <sys/callo.h>
50 #include <sys/callb.h>
140
141 /*
142 * Construct a stack for init containing the arguments to it, then
143 * pass control to exec_common.
144 */
145 int
146 exec_init(const char *initpath, const char *args)
147 {
148 caddr32_t ucp;
149 caddr32_t *uap;
150 caddr32_t *argv;
151 caddr32_t exec_fnamep;
152 char *scratchargs;
153 int i, sarg;
154 size_t argvlen, alen;
155 boolean_t in_arg;
156 int argc = 0;
157 int error = 0, count = 0;
158 proc_t *p = ttoproc(curthread);
159 klwp_t *lwp = ttolwp(curthread);
160 int brand_action;
161
162 if (args == NULL)
163 args = "";
164
165 alen = strlen(initpath) + 1 + strlen(args) + 1;
166 scratchargs = kmem_alloc(alen, KM_SLEEP);
167 (void) snprintf(scratchargs, alen, "%s %s", initpath, args);
168
169 /*
170 * We do a quick two state parse of the string to sort out how big
171 * argc should be.
172 */
173 in_arg = B_FALSE;
174 for (i = 0; i < strlen(scratchargs); i++) {
175 if (scratchargs[i] == ' ' || scratchargs[i] == '\0') {
176 if (in_arg) {
177 in_arg = B_FALSE;
178 argc++;
179 }
180 } else {
251 kmem_free(argv, argvlen);
252 kmem_free(scratchargs, alen);
253
254 /*
255 * Point at the arguments.
256 */
257 lwp->lwp_ap = lwp->lwp_arg;
258 lwp->lwp_arg[0] = (uintptr_t)exec_fnamep;
259 lwp->lwp_arg[1] = (uintptr_t)uap;
260 lwp->lwp_arg[2] = NULL;
261 curthread->t_post_sys = 1;
262 curthread->t_sysnum = SYS_execve;
263
264 /*
265 * If we are executing init from zsched, we may have inherited its
266 * parent process's signal mask. Clear it now so that we behave in
267 * the same way as when started from the global zone.
268 */
269 sigemptyset(&curthread->t_hold);
270
271 brand_action = ZONE_IS_BRANDED(p->p_zone) ? EBA_BRAND : EBA_NONE;
272 again:
273 error = exec_common((const char *)(uintptr_t)exec_fnamep,
274 (const char **)(uintptr_t)uap, NULL, brand_action);
275
276 /*
277 * Normally we would just set lwp_argsaved and t_post_sys and
278 * let post_syscall reset lwp_ap for us. Unfortunately,
279 * exec_init isn't always called from a system call. Instead
280 * of making a mess of trap_cleanup, we just reset the args
281 * pointer here.
282 */
283 reset_syscall_args();
284
285 switch (error) {
286 case 0:
287 return (0);
288
289 case ENOENT:
290 zcmn_err(p->p_zone->zone_id, CE_WARN,
291 "exec(%s) failed (file not found).\n", initpath);
|
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 /* Copyright (c) 1988 AT&T */
27 /* All Rights Reserved */
28
29 /*
30 * Copyright 2015, Joyent, Inc.
31 */
32
33 #include <sys/types.h>
34 #include <sys/param.h>
35 #include <sys/sysmacros.h>
36 #include <sys/pcb.h>
37 #include <sys/systm.h>
38 #include <sys/signal.h>
39 #include <sys/cred.h>
40 #include <sys/user.h>
41 #include <sys/vfs.h>
42 #include <sys/vnode.h>
43 #include <sys/proc.h>
44 #include <sys/time.h>
45 #include <sys/file.h>
46 #include <sys/priocntl.h>
47 #include <sys/procset.h>
48 #include <sys/disp.h>
49 #include <sys/callo.h>
50 #include <sys/callb.h>
140
141 /*
142 * Construct a stack for init containing the arguments to it, then
143 * pass control to exec_common.
144 */
145 int
146 exec_init(const char *initpath, const char *args)
147 {
148 caddr32_t ucp;
149 caddr32_t *uap;
150 caddr32_t *argv;
151 caddr32_t exec_fnamep;
152 char *scratchargs;
153 int i, sarg;
154 size_t argvlen, alen;
155 boolean_t in_arg;
156 int argc = 0;
157 int error = 0, count = 0;
158 proc_t *p = ttoproc(curthread);
159 klwp_t *lwp = ttolwp(curthread);
160 int brand_action = EBA_NONE;
161
162 if (args == NULL)
163 args = "";
164
165 alen = strlen(initpath) + 1 + strlen(args) + 1;
166 scratchargs = kmem_alloc(alen, KM_SLEEP);
167 (void) snprintf(scratchargs, alen, "%s %s", initpath, args);
168
169 /*
170 * We do a quick two state parse of the string to sort out how big
171 * argc should be.
172 */
173 in_arg = B_FALSE;
174 for (i = 0; i < strlen(scratchargs); i++) {
175 if (scratchargs[i] == ' ' || scratchargs[i] == '\0') {
176 if (in_arg) {
177 in_arg = B_FALSE;
178 argc++;
179 }
180 } else {
251 kmem_free(argv, argvlen);
252 kmem_free(scratchargs, alen);
253
254 /*
255 * Point at the arguments.
256 */
257 lwp->lwp_ap = lwp->lwp_arg;
258 lwp->lwp_arg[0] = (uintptr_t)exec_fnamep;
259 lwp->lwp_arg[1] = (uintptr_t)uap;
260 lwp->lwp_arg[2] = NULL;
261 curthread->t_post_sys = 1;
262 curthread->t_sysnum = SYS_execve;
263
264 /*
265 * If we are executing init from zsched, we may have inherited its
266 * parent process's signal mask. Clear it now so that we behave in
267 * the same way as when started from the global zone.
268 */
269 sigemptyset(&curthread->t_hold);
270
271 /*
272 * Only instruct exec_common to brand the process if necessary. It is
273 * possible that the init process is already properly branded due to the
274 * proc_exit -> restart_init -> exec_init call chain.
275 */
276 if (ZONE_IS_BRANDED(p->p_zone) &&
277 p->p_brand != p->p_zone->zone_brand) {
278 brand_action = EBA_BRAND;
279 }
280 again:
281 error = exec_common((const char *)(uintptr_t)exec_fnamep,
282 (const char **)(uintptr_t)uap, NULL, brand_action);
283
284 /*
285 * Normally we would just set lwp_argsaved and t_post_sys and
286 * let post_syscall reset lwp_ap for us. Unfortunately,
287 * exec_init isn't always called from a system call. Instead
288 * of making a mess of trap_cleanup, we just reset the args
289 * pointer here.
290 */
291 reset_syscall_args();
292
293 switch (error) {
294 case 0:
295 return (0);
296
297 case ENOENT:
298 zcmn_err(p->p_zone->zone_id, CE_WARN,
299 "exec(%s) failed (file not found).\n", initpath);
|