kern_exec.c revision 1.170 1 1.170 dsl /* $NetBSD: kern_exec.c,v 1.170 2003/07/16 22:42:48 dsl Exp $ */
2 1.55 cgd
3 1.55 cgd /*-
4 1.77 cgd * Copyright (C) 1993, 1994, 1996 Christopher G. Demetriou
5 1.55 cgd * Copyright (C) 1992 Wolfgang Solfrank.
6 1.55 cgd * Copyright (C) 1992 TooLs GmbH.
7 1.55 cgd * All rights reserved.
8 1.55 cgd *
9 1.55 cgd * Redistribution and use in source and binary forms, with or without
10 1.55 cgd * modification, are permitted provided that the following conditions
11 1.55 cgd * are met:
12 1.55 cgd * 1. Redistributions of source code must retain the above copyright
13 1.55 cgd * notice, this list of conditions and the following disclaimer.
14 1.55 cgd * 2. Redistributions in binary form must reproduce the above copyright
15 1.55 cgd * notice, this list of conditions and the following disclaimer in the
16 1.55 cgd * documentation and/or other materials provided with the distribution.
17 1.55 cgd * 3. All advertising materials mentioning features or use of this software
18 1.55 cgd * must display the following acknowledgement:
19 1.55 cgd * This product includes software developed by TooLs GmbH.
20 1.55 cgd * 4. The name of TooLs GmbH may not be used to endorse or promote products
21 1.55 cgd * derived from this software without specific prior written permission.
22 1.55 cgd *
23 1.55 cgd * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
24 1.55 cgd * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 1.55 cgd * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 1.55 cgd * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 1.55 cgd * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 1.55 cgd * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29 1.55 cgd * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 1.55 cgd * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31 1.55 cgd * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32 1.55 cgd * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 1.55 cgd */
34 1.146 lukem
35 1.146 lukem #include <sys/cdefs.h>
36 1.170 dsl __KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.170 2003/07/16 22:42:48 dsl Exp $");
37 1.89 mrg
38 1.92 thorpej #include "opt_ktrace.h"
39 1.124 jdolecek #include "opt_syscall_debug.h"
40 1.55 cgd
41 1.55 cgd #include <sys/param.h>
42 1.55 cgd #include <sys/systm.h>
43 1.55 cgd #include <sys/filedesc.h>
44 1.55 cgd #include <sys/kernel.h>
45 1.55 cgd #include <sys/proc.h>
46 1.55 cgd #include <sys/mount.h>
47 1.55 cgd #include <sys/malloc.h>
48 1.55 cgd #include <sys/namei.h>
49 1.55 cgd #include <sys/vnode.h>
50 1.55 cgd #include <sys/file.h>
51 1.55 cgd #include <sys/acct.h>
52 1.55 cgd #include <sys/exec.h>
53 1.55 cgd #include <sys/ktrace.h>
54 1.55 cgd #include <sys/resourcevar.h>
55 1.55 cgd #include <sys/wait.h>
56 1.55 cgd #include <sys/mman.h>
57 1.155 gmcgarry #include <sys/ras.h>
58 1.55 cgd #include <sys/signalvar.h>
59 1.55 cgd #include <sys/stat.h>
60 1.124 jdolecek #include <sys/syscall.h>
61 1.55 cgd
62 1.164 thorpej #include <sys/sa.h>
63 1.164 thorpej #include <sys/savar.h>
64 1.56 cgd #include <sys/syscallargs.h>
65 1.55 cgd
66 1.88 mrg #include <uvm/uvm_extern.h>
67 1.88 mrg
68 1.55 cgd #include <machine/cpu.h>
69 1.55 cgd #include <machine/reg.h>
70 1.55 cgd
71 1.143 christos #ifdef DEBUG_EXEC
72 1.143 christos #define DPRINTF(a) uprintf a
73 1.143 christos #else
74 1.143 christos #define DPRINTF(a)
75 1.143 christos #endif /* DEBUG_EXEC */
76 1.165 thorpej
77 1.165 thorpej MALLOC_DEFINE(M_EXEC, "exec", "argument lists & other mem used by exec");
78 1.143 christos
79 1.130 jdolecek /*
80 1.130 jdolecek * Exec function switch:
81 1.130 jdolecek *
82 1.130 jdolecek * Note that each makecmds function is responsible for loading the
83 1.130 jdolecek * exec package with the necessary functions for any exec-type-specific
84 1.130 jdolecek * handling.
85 1.130 jdolecek *
86 1.130 jdolecek * Functions for specific exec types should be defined in their own
87 1.130 jdolecek * header file.
88 1.130 jdolecek */
89 1.138 lukem extern const struct execsw execsw_builtin[];
90 1.138 lukem extern int nexecs_builtin;
91 1.138 lukem static const struct execsw **execsw = NULL;
92 1.138 lukem static int nexecs;
93 1.138 lukem
94 1.153 thorpej u_int exec_maxhdrsz; /* must not be static - netbsd32 needs it */
95 1.130 jdolecek
96 1.130 jdolecek #ifdef LKM
97 1.130 jdolecek /* list of supported emulations */
98 1.130 jdolecek static
99 1.130 jdolecek LIST_HEAD(emlist_head, emul_entry) el_head = LIST_HEAD_INITIALIZER(el_head);
100 1.130 jdolecek struct emul_entry {
101 1.138 lukem LIST_ENTRY(emul_entry) el_list;
102 1.138 lukem const struct emul *el_emul;
103 1.138 lukem int ro_entry;
104 1.130 jdolecek };
105 1.130 jdolecek
106 1.130 jdolecek /* list of dynamically loaded execsw entries */
107 1.130 jdolecek static
108 1.130 jdolecek LIST_HEAD(execlist_head, exec_entry) ex_head = LIST_HEAD_INITIALIZER(ex_head);
109 1.130 jdolecek struct exec_entry {
110 1.138 lukem LIST_ENTRY(exec_entry) ex_list;
111 1.138 lukem const struct execsw *es;
112 1.130 jdolecek };
113 1.130 jdolecek
114 1.130 jdolecek /* structure used for building execw[] */
115 1.130 jdolecek struct execsw_entry {
116 1.138 lukem struct execsw_entry *next;
117 1.138 lukem const struct execsw *es;
118 1.130 jdolecek };
119 1.130 jdolecek #endif /* LKM */
120 1.130 jdolecek
121 1.130 jdolecek /* NetBSD emul struct */
122 1.138 lukem extern char sigcode[], esigcode[];
123 1.124 jdolecek #ifdef SYSCALL_DEBUG
124 1.124 jdolecek extern const char * const syscallnames[];
125 1.124 jdolecek #endif
126 1.133 mycroft #ifdef __HAVE_SYSCALL_INTERN
127 1.138 lukem void syscall_intern(struct proc *);
128 1.133 mycroft #else
129 1.138 lukem void syscall(void);
130 1.133 mycroft #endif
131 1.124 jdolecek
132 1.124 jdolecek const struct emul emul_netbsd = {
133 1.124 jdolecek "netbsd",
134 1.127 jdolecek NULL, /* emulation path */
135 1.133 mycroft #ifndef __HAVE_MINIMAL_EMUL
136 1.140 manu EMUL_HAS_SYS___syscall,
137 1.124 jdolecek NULL,
138 1.124 jdolecek SYS_syscall,
139 1.161 jdolecek SYS_NSYSENT,
140 1.133 mycroft #endif
141 1.124 jdolecek sysent,
142 1.124 jdolecek #ifdef SYSCALL_DEBUG
143 1.124 jdolecek syscallnames,
144 1.124 jdolecek #else
145 1.124 jdolecek NULL,
146 1.124 jdolecek #endif
147 1.133 mycroft sendsig,
148 1.142 christos trapsignal,
149 1.124 jdolecek sigcode,
150 1.124 jdolecek esigcode,
151 1.145 jdolecek setregs,
152 1.128 jdolecek NULL,
153 1.128 jdolecek NULL,
154 1.128 jdolecek NULL,
155 1.133 mycroft #ifdef __HAVE_SYSCALL_INTERN
156 1.133 mycroft syscall_intern,
157 1.133 mycroft #else
158 1.133 mycroft syscall,
159 1.133 mycroft #endif
160 1.156 manu NULL,
161 1.156 manu NULL,
162 1.124 jdolecek };
163 1.124 jdolecek
164 1.147 jdolecek #ifdef LKM
165 1.55 cgd /*
166 1.130 jdolecek * Exec lock. Used to control access to execsw[] structures.
167 1.130 jdolecek * This must not be static so that netbsd32 can access it, too.
168 1.130 jdolecek */
169 1.130 jdolecek struct lock exec_lock;
170 1.130 jdolecek
171 1.138 lukem static void link_es(struct execsw_entry **, const struct execsw *);
172 1.130 jdolecek #endif /* LKM */
173 1.130 jdolecek
174 1.130 jdolecek /*
175 1.55 cgd * check exec:
176 1.55 cgd * given an "executable" described in the exec package's namei info,
177 1.55 cgd * see what we can do with it.
178 1.55 cgd *
179 1.55 cgd * ON ENTRY:
180 1.55 cgd * exec package with appropriate namei info
181 1.55 cgd * proc pointer of exec'ing proc
182 1.160 blymn * iff verified exec enabled then flag indicating a direct exec or
183 1.160 blymn * an indirect exec (i.e. for a shell script interpreter)
184 1.55 cgd * NO SELF-LOCKED VNODES
185 1.55 cgd *
186 1.55 cgd * ON EXIT:
187 1.55 cgd * error: nothing held, etc. exec header still allocated.
188 1.77 cgd * ok: filled exec package, executable's vnode (unlocked).
189 1.55 cgd *
190 1.55 cgd * EXEC SWITCH ENTRY:
191 1.55 cgd * Locked vnode to check, exec package, proc.
192 1.55 cgd *
193 1.55 cgd * EXEC SWITCH EXIT:
194 1.77 cgd * ok: return 0, filled exec package, executable's vnode (unlocked).
195 1.55 cgd * error: destructive:
196 1.55 cgd * everything deallocated execept exec header.
197 1.76 cgd * non-destructive:
198 1.77 cgd * error code, executable's vnode (unlocked),
199 1.76 cgd * exec header unmodified.
200 1.55 cgd */
201 1.55 cgd int
202 1.160 blymn #ifdef VERIFIED_EXEC
203 1.169 fvdl check_exec(struct proc *p, struct exec_package *epp, int direct_exec)
204 1.160 blymn #else
205 1.169 fvdl check_exec(struct proc *p, struct exec_package *epp)
206 1.160 blymn #endif
207 1.55 cgd {
208 1.138 lukem int error, i;
209 1.138 lukem struct vnode *vp;
210 1.55 cgd struct nameidata *ndp;
211 1.138 lukem size_t resid;
212 1.55 cgd
213 1.55 cgd ndp = epp->ep_ndp;
214 1.55 cgd ndp->ni_cnd.cn_nameiop = LOOKUP;
215 1.55 cgd ndp->ni_cnd.cn_flags = FOLLOW | LOCKLEAF | SAVENAME;
216 1.55 cgd /* first get the vnode */
217 1.74 christos if ((error = namei(ndp)) != 0)
218 1.55 cgd return error;
219 1.55 cgd epp->ep_vp = vp = ndp->ni_vp;
220 1.55 cgd
221 1.84 mycroft /* check access and type */
222 1.55 cgd if (vp->v_type != VREG) {
223 1.81 kleink error = EACCES;
224 1.55 cgd goto bad1;
225 1.55 cgd }
226 1.169 fvdl if ((error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p)) != 0)
227 1.84 mycroft goto bad1;
228 1.55 cgd
229 1.55 cgd /* get attributes */
230 1.169 fvdl if ((error = VOP_GETATTR(vp, epp->ep_vap, p->p_ucred, p)) != 0)
231 1.55 cgd goto bad1;
232 1.55 cgd
233 1.55 cgd /* Check mount point */
234 1.55 cgd if (vp->v_mount->mnt_flag & MNT_NOEXEC) {
235 1.55 cgd error = EACCES;
236 1.55 cgd goto bad1;
237 1.55 cgd }
238 1.141 thorpej if (vp->v_mount->mnt_flag & MNT_NOSUID)
239 1.83 mycroft epp->ep_vap->va_mode &= ~(S_ISUID | S_ISGID);
240 1.55 cgd
241 1.55 cgd /* try to open it */
242 1.169 fvdl if ((error = VOP_OPEN(vp, FREAD, p->p_ucred, p)) != 0)
243 1.55 cgd goto bad1;
244 1.55 cgd
245 1.99 wrstuden /* unlock vp, since we need it unlocked from here on out. */
246 1.90 fvdl VOP_UNLOCK(vp, 0);
247 1.77 cgd
248 1.160 blymn
249 1.160 blymn #ifdef VERIFIED_EXEC
250 1.160 blymn /* Evaluate signature for file... */
251 1.160 blymn if ((error = check_veriexec(p, vp, epp, direct_exec)) != 0)
252 1.160 blymn goto bad2;
253 1.160 blymn #endif
254 1.160 blymn
255 1.55 cgd /* now we have the file, get the exec header */
256 1.125 chs uvn_attach(vp, VM_PROT_READ);
257 1.74 christos error = vn_rdwr(UIO_READ, vp, epp->ep_hdr, epp->ep_hdrlen, 0,
258 1.169 fvdl UIO_SYSSPACE, 0, p->p_ucred, &resid, p);
259 1.74 christos if (error)
260 1.55 cgd goto bad2;
261 1.55 cgd epp->ep_hdrvalid = epp->ep_hdrlen - resid;
262 1.55 cgd
263 1.55 cgd /*
264 1.136 eeh * Set up default address space limits. Can be overridden
265 1.136 eeh * by individual exec packages.
266 1.136 eeh *
267 1.167 manu * XXX probably should be all done in the exec pakages.
268 1.136 eeh */
269 1.136 eeh epp->ep_vm_minaddr = VM_MIN_ADDRESS;
270 1.136 eeh epp->ep_vm_maxaddr = VM_MAXUSER_ADDRESS;
271 1.136 eeh /*
272 1.55 cgd * set up the vmcmds for creation of the process
273 1.55 cgd * address space
274 1.55 cgd */
275 1.55 cgd error = ENOEXEC;
276 1.55 cgd for (i = 0; i < nexecs && error != 0; i++) {
277 1.68 cgd int newerror;
278 1.68 cgd
279 1.130 jdolecek epp->ep_esch = execsw[i];
280 1.169 fvdl newerror = (*execsw[i]->es_check)(p, epp);
281 1.68 cgd /* make sure the first "interesting" error code is saved. */
282 1.68 cgd if (!newerror || error == ENOEXEC)
283 1.68 cgd error = newerror;
284 1.124 jdolecek
285 1.124 jdolecek /* if es_check call was successful, update epp->ep_es */
286 1.124 jdolecek if (!newerror && (epp->ep_flags & EXEC_HASES) == 0)
287 1.130 jdolecek epp->ep_es = execsw[i];
288 1.124 jdolecek
289 1.55 cgd if (epp->ep_flags & EXEC_DESTR && error != 0)
290 1.55 cgd return error;
291 1.55 cgd }
292 1.55 cgd if (!error) {
293 1.55 cgd /* check that entry point is sane */
294 1.55 cgd if (epp->ep_entry > VM_MAXUSER_ADDRESS)
295 1.55 cgd error = ENOEXEC;
296 1.55 cgd
297 1.55 cgd /* check limits */
298 1.55 cgd if ((epp->ep_tsize > MAXTSIZ) ||
299 1.153 thorpej (epp->ep_dsize >
300 1.153 thorpej (u_quad_t)p->p_rlimit[RLIMIT_DATA].rlim_cur))
301 1.55 cgd error = ENOMEM;
302 1.55 cgd
303 1.55 cgd if (!error)
304 1.55 cgd return (0);
305 1.55 cgd }
306 1.55 cgd
307 1.55 cgd /*
308 1.55 cgd * free any vmspace-creation commands,
309 1.55 cgd * and release their references
310 1.55 cgd */
311 1.55 cgd kill_vmcmds(&epp->ep_vmcmds);
312 1.55 cgd
313 1.55 cgd bad2:
314 1.55 cgd /*
315 1.99 wrstuden * close and release the vnode, restore the old one, free the
316 1.55 cgd * pathname buf, and punt.
317 1.55 cgd */
318 1.99 wrstuden vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
319 1.169 fvdl VOP_CLOSE(vp, FREAD, p->p_ucred, p);
320 1.99 wrstuden vput(vp);
321 1.120 thorpej PNBUF_PUT(ndp->ni_cnd.cn_pnbuf);
322 1.55 cgd return error;
323 1.55 cgd
324 1.55 cgd bad1:
325 1.55 cgd /*
326 1.55 cgd * free the namei pathname buffer, and put the vnode
327 1.55 cgd * (which we don't yet have open).
328 1.55 cgd */
329 1.77 cgd vput(vp); /* was still locked */
330 1.120 thorpej PNBUF_PUT(ndp->ni_cnd.cn_pnbuf);
331 1.55 cgd return error;
332 1.55 cgd }
333 1.55 cgd
334 1.55 cgd /*
335 1.55 cgd * exec system call
336 1.55 cgd */
337 1.55 cgd /* ARGSUSED */
338 1.75 christos int
339 1.164 thorpej sys_execve(struct lwp *l, void *v, register_t *retval)
340 1.71 thorpej {
341 1.108 augustss struct sys_execve_args /* {
342 1.138 lukem syscallarg(const char *) path;
343 1.138 lukem syscallarg(char * const *) argp;
344 1.138 lukem syscallarg(char * const *) envp;
345 1.71 thorpej } */ *uap = v;
346 1.153 thorpej int error;
347 1.153 thorpej u_int i;
348 1.138 lukem struct exec_package pack;
349 1.138 lukem struct nameidata nid;
350 1.138 lukem struct vattr attr;
351 1.164 thorpej struct proc *p;
352 1.138 lukem struct ucred *cred;
353 1.138 lukem char *argp;
354 1.138 lukem char * const *cpp;
355 1.138 lukem char *dp, *sp;
356 1.138 lukem long argc, envc;
357 1.138 lukem size_t len;
358 1.138 lukem char *stack;
359 1.138 lukem struct ps_strings arginfo;
360 1.138 lukem struct vmspace *vm;
361 1.138 lukem char **tmpfap;
362 1.138 lukem int szsigcode;
363 1.138 lukem struct exec_vmcmd *base_vcp;
364 1.164 thorpej int oldlwpflags;
365 1.55 cgd
366 1.164 thorpej /* Disable scheduler activation upcalls. */
367 1.164 thorpej oldlwpflags = l->l_flag & (L_SA | L_SA_UPCALL);
368 1.164 thorpej if (l->l_flag & L_SA)
369 1.164 thorpej l->l_flag &= ~(L_SA | L_SA_UPCALL);
370 1.164 thorpej
371 1.164 thorpej p = l->l_proc;
372 1.149 christos /*
373 1.149 christos * Lock the process and set the P_INEXEC flag to indicate that
374 1.149 christos * it should be left alone until we're done here. This is
375 1.149 christos * necessary to avoid race conditions - e.g. in ptrace() -
376 1.149 christos * that might allow a local user to illicitly obtain elevated
377 1.149 christos * privileges.
378 1.149 christos */
379 1.149 christos p->p_flag |= P_INEXEC;
380 1.149 christos
381 1.138 lukem cred = p->p_ucred;
382 1.138 lukem base_vcp = NULL;
383 1.55 cgd /*
384 1.129 jdolecek * Init the namei data to point the file user's program name.
385 1.129 jdolecek * This is done here rather than in check_exec(), so that it's
386 1.129 jdolecek * possible to override this settings if any of makecmd/probe
387 1.129 jdolecek * functions call check_exec() recursively - for example,
388 1.129 jdolecek * see exec_script_makecmds().
389 1.129 jdolecek */
390 1.169 fvdl NDINIT(&nid, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
391 1.55 cgd
392 1.55 cgd /*
393 1.55 cgd * initialize the fields of the exec package.
394 1.55 cgd */
395 1.56 cgd pack.ep_name = SCARG(uap, path);
396 1.119 thorpej pack.ep_hdr = malloc(exec_maxhdrsz, M_EXEC, M_WAITOK);
397 1.55 cgd pack.ep_hdrlen = exec_maxhdrsz;
398 1.55 cgd pack.ep_hdrvalid = 0;
399 1.55 cgd pack.ep_ndp = &nid;
400 1.67 christos pack.ep_emul_arg = NULL;
401 1.55 cgd pack.ep_vmcmds.evs_cnt = 0;
402 1.55 cgd pack.ep_vmcmds.evs_used = 0;
403 1.55 cgd pack.ep_vap = &attr;
404 1.55 cgd pack.ep_flags = 0;
405 1.55 cgd
406 1.147 jdolecek #ifdef LKM
407 1.130 jdolecek lockmgr(&exec_lock, LK_SHARED, NULL);
408 1.147 jdolecek #endif
409 1.130 jdolecek
410 1.55 cgd /* see if we can run it. */
411 1.160 blymn #ifdef VERIFIED_EXEC
412 1.169 fvdl if ((error = check_exec(p, &pack, 1)) != 0)
413 1.169 fvdl /* if ((error = check_exec(p, &pack, 0)) != 0) */
414 1.160 blymn #else
415 1.169 fvdl if ((error = check_exec(p, &pack)) != 0)
416 1.160 blymn #endif
417 1.55 cgd goto freehdr;
418 1.55 cgd
419 1.55 cgd /* XXX -- THE FOLLOWING SECTION NEEDS MAJOR CLEANUP */
420 1.55 cgd
421 1.55 cgd /* allocate an argument buffer */
422 1.88 mrg argp = (char *) uvm_km_valloc_wait(exec_map, NCARGS);
423 1.55 cgd #ifdef DIAGNOSTIC
424 1.95 eeh if (argp == (vaddr_t) 0)
425 1.55 cgd panic("execve: argp == NULL");
426 1.55 cgd #endif
427 1.55 cgd dp = argp;
428 1.55 cgd argc = 0;
429 1.55 cgd
430 1.55 cgd /* copy the fake args list, if there's one, freeing it as we go */
431 1.55 cgd if (pack.ep_flags & EXEC_HASARGL) {
432 1.55 cgd tmpfap = pack.ep_fa;
433 1.55 cgd while (*tmpfap != NULL) {
434 1.55 cgd char *cp;
435 1.55 cgd
436 1.55 cgd cp = *tmpfap;
437 1.55 cgd while (*cp)
438 1.55 cgd *dp++ = *cp++;
439 1.74 christos dp++;
440 1.55 cgd
441 1.55 cgd FREE(*tmpfap, M_EXEC);
442 1.55 cgd tmpfap++; argc++;
443 1.55 cgd }
444 1.55 cgd FREE(pack.ep_fa, M_EXEC);
445 1.55 cgd pack.ep_flags &= ~EXEC_HASARGL;
446 1.55 cgd }
447 1.55 cgd
448 1.55 cgd /* Now get argv & environment */
449 1.56 cgd if (!(cpp = SCARG(uap, argp))) {
450 1.55 cgd error = EINVAL;
451 1.55 cgd goto bad;
452 1.55 cgd }
453 1.55 cgd
454 1.55 cgd if (pack.ep_flags & EXEC_SKIPARG)
455 1.55 cgd cpp++;
456 1.55 cgd
457 1.55 cgd while (1) {
458 1.55 cgd len = argp + ARG_MAX - dp;
459 1.74 christos if ((error = copyin(cpp, &sp, sizeof(sp))) != 0)
460 1.55 cgd goto bad;
461 1.55 cgd if (!sp)
462 1.55 cgd break;
463 1.74 christos if ((error = copyinstr(sp, dp, len, &len)) != 0) {
464 1.55 cgd if (error == ENAMETOOLONG)
465 1.55 cgd error = E2BIG;
466 1.55 cgd goto bad;
467 1.55 cgd }
468 1.170 dsl #ifdef KTRACE
469 1.170 dsl if (KTRPOINT(p, KTR_EXEC_ARG))
470 1.170 dsl ktrkmem(p, KTR_EXEC_ARG, dp, len - 1);
471 1.170 dsl #endif
472 1.55 cgd dp += len;
473 1.55 cgd cpp++;
474 1.55 cgd argc++;
475 1.55 cgd }
476 1.55 cgd
477 1.55 cgd envc = 0;
478 1.74 christos /* environment need not be there */
479 1.74 christos if ((cpp = SCARG(uap, envp)) != NULL ) {
480 1.55 cgd while (1) {
481 1.55 cgd len = argp + ARG_MAX - dp;
482 1.74 christos if ((error = copyin(cpp, &sp, sizeof(sp))) != 0)
483 1.55 cgd goto bad;
484 1.55 cgd if (!sp)
485 1.55 cgd break;
486 1.74 christos if ((error = copyinstr(sp, dp, len, &len)) != 0) {
487 1.55 cgd if (error == ENAMETOOLONG)
488 1.55 cgd error = E2BIG;
489 1.55 cgd goto bad;
490 1.55 cgd }
491 1.170 dsl #ifdef KTRACE
492 1.170 dsl if (KTRPOINT(p, KTR_EXEC_ENV))
493 1.170 dsl ktrkmem(p, KTR_EXEC_ENV, dp, len - 1);
494 1.170 dsl #endif
495 1.55 cgd dp += len;
496 1.55 cgd cpp++;
497 1.55 cgd envc++;
498 1.55 cgd }
499 1.55 cgd }
500 1.61 mycroft
501 1.61 mycroft dp = (char *) ALIGN(dp);
502 1.55 cgd
503 1.126 mrg szsigcode = pack.ep_es->es_emul->e_esigcode -
504 1.126 mrg pack.ep_es->es_emul->e_sigcode;
505 1.65 fvdl
506 1.55 cgd /* Now check if args & environ fit into new stack */
507 1.105 eeh if (pack.ep_flags & EXEC_32)
508 1.126 mrg len = ((argc + envc + 2 + pack.ep_es->es_arglen) *
509 1.126 mrg sizeof(int) + sizeof(int) + dp + STACKGAPLEN +
510 1.126 mrg szsigcode + sizeof(struct ps_strings)) - argp;
511 1.105 eeh else
512 1.126 mrg len = ((argc + envc + 2 + pack.ep_es->es_arglen) *
513 1.126 mrg sizeof(char *) + sizeof(int) + dp + STACKGAPLEN +
514 1.126 mrg szsigcode + sizeof(struct ps_strings)) - argp;
515 1.67 christos
516 1.55 cgd len = ALIGN(len); /* make the stack "safely" aligned */
517 1.55 cgd
518 1.55 cgd if (len > pack.ep_ssize) { /* in effect, compare to initial limit */
519 1.55 cgd error = ENOMEM;
520 1.55 cgd goto bad;
521 1.55 cgd }
522 1.55 cgd
523 1.164 thorpej /* Get rid of other LWPs/ */
524 1.164 thorpej p->p_flag |= P_WEXIT; /* XXX hack. lwp-exit stuff wants to see it. */
525 1.164 thorpej exit_lwps(l);
526 1.164 thorpej p->p_flag &= ~P_WEXIT;
527 1.164 thorpej KDASSERT(p->p_nlwps == 1);
528 1.164 thorpej
529 1.164 thorpej /* This is now LWP 1 */
530 1.164 thorpej l->l_lid = 1;
531 1.164 thorpej p->p_nlwpid = 1;
532 1.164 thorpej
533 1.164 thorpej /* Release any SA state. */
534 1.164 thorpej if (p->p_sa) {
535 1.164 thorpej p->p_flag &= ~P_SA;
536 1.164 thorpej free(p->p_sa->sa_stacks, M_SA);
537 1.164 thorpej pool_put(&sadata_pool, p->p_sa);
538 1.164 thorpej p->p_sa = NULL;
539 1.164 thorpej }
540 1.164 thorpej
541 1.164 thorpej /* Remove POSIX timers */
542 1.164 thorpej timers_free(p, TIMERS_POSIX);
543 1.164 thorpej
544 1.55 cgd /* adjust "active stack depth" for process VSZ */
545 1.55 cgd pack.ep_ssize = len; /* maybe should go elsewhere, but... */
546 1.55 cgd
547 1.86 thorpej /*
548 1.86 thorpej * Do whatever is necessary to prepare the address space
549 1.86 thorpej * for remapping. Note that this might replace the current
550 1.86 thorpej * vmspace with another!
551 1.86 thorpej */
552 1.164 thorpej uvmspace_exec(l, pack.ep_vm_minaddr, pack.ep_vm_maxaddr);
553 1.55 cgd
554 1.55 cgd /* Now map address space */
555 1.86 thorpej vm = p->p_vmspace;
556 1.158 junyoung vm->vm_taddr = (caddr_t) pack.ep_taddr;
557 1.55 cgd vm->vm_tsize = btoc(pack.ep_tsize);
558 1.158 junyoung vm->vm_daddr = (caddr_t) pack.ep_daddr;
559 1.55 cgd vm->vm_dsize = btoc(pack.ep_dsize);
560 1.55 cgd vm->vm_ssize = btoc(pack.ep_ssize);
561 1.158 junyoung vm->vm_maxsaddr = (caddr_t) pack.ep_maxsaddr;
562 1.158 junyoung vm->vm_minsaddr = (caddr_t) pack.ep_minsaddr;
563 1.55 cgd
564 1.55 cgd /* create the new process's VM space by running the vmcmds */
565 1.55 cgd #ifdef DIAGNOSTIC
566 1.55 cgd if (pack.ep_vmcmds.evs_used == 0)
567 1.55 cgd panic("execve: no vmcmds");
568 1.55 cgd #endif
569 1.55 cgd for (i = 0; i < pack.ep_vmcmds.evs_used && !error; i++) {
570 1.55 cgd struct exec_vmcmd *vcp;
571 1.55 cgd
572 1.55 cgd vcp = &pack.ep_vmcmds.evs_cmds[i];
573 1.114 matt if (vcp->ev_flags & VMCMD_RELATIVE) {
574 1.114 matt #ifdef DIAGNOSTIC
575 1.114 matt if (base_vcp == NULL)
576 1.114 matt panic("execve: relative vmcmd with no base");
577 1.114 matt if (vcp->ev_flags & VMCMD_BASE)
578 1.114 matt panic("execve: illegal base & relative vmcmd");
579 1.114 matt #endif
580 1.114 matt vcp->ev_addr += base_vcp->ev_addr;
581 1.114 matt }
582 1.169 fvdl error = (*vcp->ev_proc)(p, vcp);
583 1.143 christos #ifdef DEBUG_EXEC
584 1.111 matt if (error) {
585 1.143 christos int j;
586 1.143 christos struct exec_vmcmd *vp = &pack.ep_vmcmds.evs_cmds[0];
587 1.143 christos for (j = 0; j <= i; j++)
588 1.143 christos uprintf(
589 1.143 christos "vmcmd[%d] = %#lx/%#lx fd@%#lx prot=0%o flags=%d\n",
590 1.143 christos j, vp[j].ev_addr, vp[j].ev_len,
591 1.143 christos vp[j].ev_offset, vp[j].ev_prot,
592 1.143 christos vp[j].ev_flags);
593 1.111 matt }
594 1.143 christos #endif /* DEBUG_EXEC */
595 1.114 matt if (vcp->ev_flags & VMCMD_BASE)
596 1.114 matt base_vcp = vcp;
597 1.55 cgd }
598 1.55 cgd
599 1.55 cgd /* free the vmspace-creation commands, and release their references */
600 1.55 cgd kill_vmcmds(&pack.ep_vmcmds);
601 1.55 cgd
602 1.55 cgd /* if an error happened, deallocate and punt */
603 1.111 matt if (error) {
604 1.143 christos DPRINTF(("execve: vmcmd %i failed: %d\n", i - 1, error));
605 1.55 cgd goto exec_abort;
606 1.111 matt }
607 1.55 cgd
608 1.55 cgd /* remember information about the process */
609 1.55 cgd arginfo.ps_nargvstr = argc;
610 1.55 cgd arginfo.ps_nenvstr = envc;
611 1.55 cgd
612 1.163 chs stack = (char *)STACK_ALLOC(STACK_GROW(vm->vm_minsaddr,
613 1.163 chs sizeof(struct ps_strings) + szsigcode),
614 1.163 chs len - (sizeof(struct ps_strings) + szsigcode));
615 1.163 chs #ifdef __MACHINE_STACK_GROWS_UP
616 1.163 chs /*
617 1.163 chs * The copyargs call always copies into lower addresses
618 1.163 chs * first, moving towards higher addresses, starting with
619 1.163 chs * the stack pointer that we give. When the stack grows
620 1.163 chs * down, this puts argc/argv/envp very shallow on the
621 1.163 chs * stack, right at the first user stack pointer, and puts
622 1.163 chs * STACKGAPLEN very deep in the stack. When the stack
623 1.163 chs * grows up, the situation is reversed.
624 1.163 chs *
625 1.163 chs * Normally, this is no big deal. But the ld_elf.so _rtld()
626 1.163 chs * function expects to be called with a single pointer to
627 1.163 chs * a region that has a few words it can stash values into,
628 1.163 chs * followed by argc/argv/envp. When the stack grows down,
629 1.163 chs * it's easy to decrement the stack pointer a little bit to
630 1.163 chs * allocate the space for these few words and pass the new
631 1.163 chs * stack pointer to _rtld. When the stack grows up, however,
632 1.163 chs * a few words before argc is part of the signal trampoline,
633 1.163 chs * so we have a problem.
634 1.163 chs *
635 1.163 chs * Instead of changing how _rtld works, we take the easy way
636 1.163 chs * out and steal 32 bytes before we call copyargs. This
637 1.163 chs * space is effectively stolen from STACKGAPLEN.
638 1.163 chs */
639 1.163 chs stack += 32;
640 1.163 chs #endif /* __MACHINE_STACK_GROWS_UP */
641 1.163 chs
642 1.55 cgd /* Now copy argc, args & environ to new stack */
643 1.169 fvdl error = (*pack.ep_es->es_copyargs)(p, &pack, &arginfo, &stack, argp);
644 1.144 christos if (error) {
645 1.144 christos DPRINTF(("execve: copyargs failed %d\n", error));
646 1.55 cgd goto exec_abort;
647 1.111 matt }
648 1.144 christos /* Move the stack back to original point */
649 1.163 chs stack = (char *)STACK_GROW(vm->vm_minsaddr, len);
650 1.55 cgd
651 1.121 eeh /* fill process ps_strings info */
652 1.163 chs p->p_psstr = (struct ps_strings *)STACK_ALLOC(vm->vm_minsaddr,
653 1.163 chs sizeof(struct ps_strings));
654 1.121 eeh p->p_psargv = offsetof(struct ps_strings, ps_argvstr);
655 1.121 eeh p->p_psnargv = offsetof(struct ps_strings, ps_nargvstr);
656 1.121 eeh p->p_psenv = offsetof(struct ps_strings, ps_envstr);
657 1.121 eeh p->p_psnenv = offsetof(struct ps_strings, ps_nenvstr);
658 1.121 eeh
659 1.55 cgd /* copy out the process's ps_strings structure */
660 1.144 christos if ((error = copyout(&arginfo, (char *)p->p_psstr,
661 1.144 christos sizeof(arginfo))) != 0) {
662 1.143 christos DPRINTF(("execve: ps_strings copyout %p->%p size %ld failed\n",
663 1.143 christos &arginfo, (char *)p->p_psstr, (long)sizeof(arginfo)));
664 1.55 cgd goto exec_abort;
665 1.111 matt }
666 1.109 simonb
667 1.158 junyoung /* copy out the process's signal trampoline code */
668 1.96 mycroft if (szsigcode) {
669 1.163 chs p->p_sigctx.ps_sigcode = STACK_ALLOC(STACK_MAX(p->p_psstr,
670 1.163 chs sizeof(struct ps_strings)), szsigcode);
671 1.144 christos if ((error = copyout((char *)pack.ep_es->es_emul->e_sigcode,
672 1.163 chs p->p_sigctx.ps_sigcode, szsigcode)) != 0) {
673 1.143 christos DPRINTF(("execve: sig trampoline copyout failed\n"));
674 1.97 kleink goto exec_abort;
675 1.111 matt }
676 1.104 is #ifdef PMAP_NEED_PROCWR
677 1.104 is /* This is code. Let the pmap do what is needed. */
678 1.134 jdolecek pmap_procwr(p, (vaddr_t)p->p_sigctx.ps_sigcode, szsigcode);
679 1.104 is #endif
680 1.96 mycroft }
681 1.55 cgd
682 1.102 ross stopprofclock(p); /* stop profiling */
683 1.169 fvdl fdcloseexec(p); /* handle close on exec */
684 1.55 cgd execsigs(p); /* reset catched signals */
685 1.164 thorpej
686 1.164 thorpej l->l_ctxlink = NULL; /* reset ucontext link */
687 1.55 cgd
688 1.55 cgd /* set command name & other accounting info */
689 1.55 cgd len = min(nid.ni_cnd.cn_namelen, MAXCOMLEN);
690 1.94 perry memcpy(p->p_comm, nid.ni_cnd.cn_nameptr, len);
691 1.55 cgd p->p_comm[len] = 0;
692 1.55 cgd p->p_acflag &= ~AFORK;
693 1.55 cgd
694 1.55 cgd /* record proc's vnode, for use by procfs and others */
695 1.55 cgd if (p->p_textvp)
696 1.55 cgd vrele(p->p_textvp);
697 1.55 cgd VREF(pack.ep_vp);
698 1.55 cgd p->p_textvp = pack.ep_vp;
699 1.55 cgd
700 1.55 cgd p->p_flag |= P_EXEC;
701 1.55 cgd if (p->p_flag & P_PPWAIT) {
702 1.55 cgd p->p_flag &= ~P_PPWAIT;
703 1.55 cgd wakeup((caddr_t) p->p_pptr);
704 1.55 cgd }
705 1.55 cgd
706 1.55 cgd /*
707 1.55 cgd * deal with set[ug]id.
708 1.141 thorpej * MNT_NOSUID has already been used to disable s[ug]id.
709 1.55 cgd */
710 1.141 thorpej if ((p->p_flag & P_TRACED) == 0 &&
711 1.141 thorpej
712 1.141 thorpej (((attr.va_mode & S_ISUID) != 0 &&
713 1.141 thorpej p->p_ucred->cr_uid != attr.va_uid) ||
714 1.141 thorpej
715 1.141 thorpej ((attr.va_mode & S_ISGID) != 0 &&
716 1.141 thorpej p->p_ucred->cr_gid != attr.va_gid))) {
717 1.141 thorpej /*
718 1.141 thorpej * Mark the process as SUGID before we do
719 1.141 thorpej * anything that might block.
720 1.141 thorpej */
721 1.141 thorpej p_sugid(p);
722 1.152 christos
723 1.152 christos /* Make sure file descriptors 0..2 are in use. */
724 1.169 fvdl if ((error = fdcheckstd(p)) != 0)
725 1.152 christos goto exec_abort;
726 1.141 thorpej
727 1.55 cgd p->p_ucred = crcopy(cred);
728 1.55 cgd #ifdef KTRACE
729 1.55 cgd /*
730 1.55 cgd * If process is being ktraced, turn off - unless
731 1.55 cgd * root set it.
732 1.55 cgd */
733 1.91 christos if (p->p_tracep && !(p->p_traceflag & KTRFAC_ROOT))
734 1.91 christos ktrderef(p);
735 1.55 cgd #endif
736 1.83 mycroft if (attr.va_mode & S_ISUID)
737 1.55 cgd p->p_ucred->cr_uid = attr.va_uid;
738 1.83 mycroft if (attr.va_mode & S_ISGID)
739 1.55 cgd p->p_ucred->cr_gid = attr.va_gid;
740 1.79 mrg } else
741 1.79 mrg p->p_flag &= ~P_SUGID;
742 1.55 cgd p->p_cred->p_svuid = p->p_ucred->cr_uid;
743 1.55 cgd p->p_cred->p_svgid = p->p_ucred->cr_gid;
744 1.155 gmcgarry
745 1.155 gmcgarry #if defined(__HAVE_RAS)
746 1.155 gmcgarry /*
747 1.155 gmcgarry * Remove all RASs from the address space.
748 1.155 gmcgarry */
749 1.155 gmcgarry ras_purgeall(p);
750 1.155 gmcgarry #endif
751 1.107 fvdl
752 1.107 fvdl doexechooks(p);
753 1.55 cgd
754 1.95 eeh uvm_km_free_wakeup(exec_map, (vaddr_t) argp, NCARGS);
755 1.55 cgd
756 1.120 thorpej PNBUF_PUT(nid.ni_cnd.cn_pnbuf);
757 1.99 wrstuden vn_lock(pack.ep_vp, LK_EXCLUSIVE | LK_RETRY);
758 1.169 fvdl VOP_CLOSE(pack.ep_vp, FREAD, cred, p);
759 1.99 wrstuden vput(pack.ep_vp);
760 1.159 jdolecek
761 1.159 jdolecek /* notify others that we exec'd */
762 1.159 jdolecek KNOTE(&p->p_klist, NOTE_EXEC);
763 1.55 cgd
764 1.55 cgd /* setup new registers and do misc. setup. */
765 1.164 thorpej (*pack.ep_es->es_emul->e_setregs)(l, &pack, (u_long) stack);
766 1.145 jdolecek if (pack.ep_es->es_setregs)
767 1.164 thorpej (*pack.ep_es->es_setregs)(l, &pack, (u_long) stack);
768 1.55 cgd
769 1.55 cgd if (p->p_flag & P_TRACED)
770 1.55 cgd psignal(p, SIGTRAP);
771 1.55 cgd
772 1.122 jdolecek free(pack.ep_hdr, M_EXEC);
773 1.122 jdolecek
774 1.122 jdolecek /*
775 1.122 jdolecek * Call emulation specific exec hook. This can setup setup per-process
776 1.122 jdolecek * p->p_emuldata or do any other per-process stuff an emulation needs.
777 1.122 jdolecek *
778 1.122 jdolecek * If we are executing process of different emulation than the
779 1.122 jdolecek * original forked process, call e_proc_exit() of the old emulation
780 1.122 jdolecek * first, then e_proc_exec() of new emulation. If the emulation is
781 1.122 jdolecek * same, the exec hook code should deallocate any old emulation
782 1.122 jdolecek * resources held previously by this process.
783 1.122 jdolecek */
784 1.124 jdolecek if (p->p_emul && p->p_emul->e_proc_exit
785 1.124 jdolecek && p->p_emul != pack.ep_es->es_emul)
786 1.122 jdolecek (*p->p_emul->e_proc_exit)(p);
787 1.122 jdolecek
788 1.123 jdolecek /*
789 1.123 jdolecek * Call exec hook. Emulation code may NOT store reference to anything
790 1.123 jdolecek * from &pack.
791 1.123 jdolecek */
792 1.124 jdolecek if (pack.ep_es->es_emul->e_proc_exec)
793 1.124 jdolecek (*pack.ep_es->es_emul->e_proc_exec)(p, &pack);
794 1.122 jdolecek
795 1.122 jdolecek /* update p_emul, the old value is no longer needed */
796 1.124 jdolecek p->p_emul = pack.ep_es->es_emul;
797 1.148 thorpej
798 1.148 thorpej /* ...and the same for p_execsw */
799 1.148 thorpej p->p_execsw = pack.ep_es;
800 1.148 thorpej
801 1.133 mycroft #ifdef __HAVE_SYSCALL_INTERN
802 1.133 mycroft (*p->p_emul->e_syscall_intern)(p);
803 1.133 mycroft #endif
804 1.70 christos #ifdef KTRACE
805 1.70 christos if (KTRPOINT(p, KTR_EMUL))
806 1.169 fvdl ktremul(p);
807 1.70 christos #endif
808 1.85 mycroft
809 1.147 jdolecek #ifdef LKM
810 1.130 jdolecek lockmgr(&exec_lock, LK_RELEASE, NULL);
811 1.147 jdolecek #endif
812 1.149 christos p->p_flag &= ~P_INEXEC;
813 1.162 manu
814 1.162 manu if (p->p_flag & P_STOPEXEC) {
815 1.162 manu int s;
816 1.162 manu
817 1.162 manu sigminusset(&contsigmask, &p->p_sigctx.ps_siglist);
818 1.162 manu SCHED_LOCK(s);
819 1.162 manu p->p_stat = SSTOP;
820 1.164 thorpej l->l_stat = LSSTOP;
821 1.164 thorpej p->p_nrlwps--;
822 1.164 thorpej mi_switch(l, NULL);
823 1.162 manu SCHED_ASSERT_UNLOCKED();
824 1.162 manu splx(s);
825 1.162 manu }
826 1.162 manu
827 1.85 mycroft return (EJUSTRETURN);
828 1.55 cgd
829 1.138 lukem bad:
830 1.149 christos p->p_flag &= ~P_INEXEC;
831 1.55 cgd /* free the vmspace-creation commands, and release their references */
832 1.55 cgd kill_vmcmds(&pack.ep_vmcmds);
833 1.55 cgd /* kill any opened file descriptor, if necessary */
834 1.55 cgd if (pack.ep_flags & EXEC_HASFD) {
835 1.55 cgd pack.ep_flags &= ~EXEC_HASFD;
836 1.169 fvdl (void) fdrelease(p, pack.ep_fd);
837 1.55 cgd }
838 1.55 cgd /* close and put the exec'd file */
839 1.99 wrstuden vn_lock(pack.ep_vp, LK_EXCLUSIVE | LK_RETRY);
840 1.169 fvdl VOP_CLOSE(pack.ep_vp, FREAD, cred, p);
841 1.99 wrstuden vput(pack.ep_vp);
842 1.120 thorpej PNBUF_PUT(nid.ni_cnd.cn_pnbuf);
843 1.95 eeh uvm_km_free_wakeup(exec_map, (vaddr_t) argp, NCARGS);
844 1.55 cgd
845 1.138 lukem freehdr:
846 1.164 thorpej l->l_flag |= oldlwpflags;
847 1.150 christos p->p_flag &= ~P_INEXEC;
848 1.147 jdolecek #ifdef LKM
849 1.130 jdolecek lockmgr(&exec_lock, LK_RELEASE, NULL);
850 1.147 jdolecek #endif
851 1.130 jdolecek
852 1.119 thorpej free(pack.ep_hdr, M_EXEC);
853 1.55 cgd return error;
854 1.55 cgd
855 1.138 lukem exec_abort:
856 1.150 christos p->p_flag &= ~P_INEXEC;
857 1.147 jdolecek #ifdef LKM
858 1.130 jdolecek lockmgr(&exec_lock, LK_RELEASE, NULL);
859 1.147 jdolecek #endif
860 1.130 jdolecek
861 1.55 cgd /*
862 1.55 cgd * the old process doesn't exist anymore. exit gracefully.
863 1.55 cgd * get rid of the (new) address space we have created, if any, get rid
864 1.55 cgd * of our namei data and vnode, and exit noting failure
865 1.55 cgd */
866 1.88 mrg uvm_deallocate(&vm->vm_map, VM_MIN_ADDRESS,
867 1.88 mrg VM_MAXUSER_ADDRESS - VM_MIN_ADDRESS);
868 1.73 mycroft if (pack.ep_emul_arg)
869 1.124 jdolecek FREE(pack.ep_emul_arg, M_TEMP);
870 1.120 thorpej PNBUF_PUT(nid.ni_cnd.cn_pnbuf);
871 1.99 wrstuden vn_lock(pack.ep_vp, LK_EXCLUSIVE | LK_RETRY);
872 1.169 fvdl VOP_CLOSE(pack.ep_vp, FREAD, cred, p);
873 1.99 wrstuden vput(pack.ep_vp);
874 1.95 eeh uvm_km_free_wakeup(exec_map, (vaddr_t) argp, NCARGS);
875 1.119 thorpej free(pack.ep_hdr, M_EXEC);
876 1.164 thorpej exit1(l, W_EXITCODE(error, SIGABRT));
877 1.55 cgd
878 1.55 cgd /* NOTREACHED */
879 1.55 cgd return 0;
880 1.67 christos }
881 1.67 christos
882 1.67 christos
883 1.144 christos int
884 1.169 fvdl copyargs(struct proc *p, struct exec_package *pack, struct ps_strings *arginfo,
885 1.144 christos char **stackp, void *argp)
886 1.67 christos {
887 1.138 lukem char **cpp, *dp, *sp;
888 1.138 lukem size_t len;
889 1.138 lukem void *nullp;
890 1.138 lukem long argc, envc;
891 1.144 christos int error;
892 1.138 lukem
893 1.144 christos cpp = (char **)*stackp;
894 1.138 lukem nullp = NULL;
895 1.138 lukem argc = arginfo->ps_nargvstr;
896 1.138 lukem envc = arginfo->ps_nenvstr;
897 1.144 christos if ((error = copyout(&argc, cpp++, sizeof(argc))) != 0)
898 1.144 christos return error;
899 1.67 christos
900 1.124 jdolecek dp = (char *) (cpp + argc + envc + 2 + pack->ep_es->es_arglen);
901 1.67 christos sp = argp;
902 1.67 christos
903 1.67 christos /* XXX don't copy them out, remap them! */
904 1.69 mycroft arginfo->ps_argvstr = cpp; /* remember location of argv for later */
905 1.67 christos
906 1.67 christos for (; --argc >= 0; sp += len, dp += len)
907 1.144 christos if ((error = copyout(&dp, cpp++, sizeof(dp))) != 0 ||
908 1.144 christos (error = copyoutstr(sp, dp, ARG_MAX, &len)) != 0)
909 1.144 christos return error;
910 1.67 christos
911 1.144 christos if ((error = copyout(&nullp, cpp++, sizeof(nullp))) != 0)
912 1.144 christos return error;
913 1.67 christos
914 1.69 mycroft arginfo->ps_envstr = cpp; /* remember location of envp for later */
915 1.67 christos
916 1.67 christos for (; --envc >= 0; sp += len, dp += len)
917 1.144 christos if ((error = copyout(&dp, cpp++, sizeof(dp))) != 0 ||
918 1.144 christos (error = copyoutstr(sp, dp, ARG_MAX, &len)) != 0)
919 1.144 christos return error;
920 1.67 christos
921 1.144 christos if ((error = copyout(&nullp, cpp++, sizeof(nullp))) != 0)
922 1.144 christos return error;
923 1.67 christos
924 1.144 christos *stackp = (char *)cpp;
925 1.144 christos return 0;
926 1.55 cgd }
927 1.130 jdolecek
928 1.130 jdolecek #ifdef LKM
929 1.130 jdolecek /*
930 1.130 jdolecek * Find an emulation of given name in list of emulations.
931 1.151 jdolecek * Needs to be called with the exec_lock held.
932 1.130 jdolecek */
933 1.151 jdolecek const struct emul *
934 1.138 lukem emul_search(const char *name)
935 1.130 jdolecek {
936 1.130 jdolecek struct emul_entry *it;
937 1.130 jdolecek
938 1.130 jdolecek LIST_FOREACH(it, &el_head, el_list) {
939 1.130 jdolecek if (strcmp(name, it->el_emul->e_name) == 0)
940 1.130 jdolecek return it->el_emul;
941 1.130 jdolecek }
942 1.130 jdolecek
943 1.130 jdolecek return NULL;
944 1.130 jdolecek }
945 1.130 jdolecek
946 1.130 jdolecek /*
947 1.130 jdolecek * Add an emulation to list, if it's not there already.
948 1.130 jdolecek */
949 1.130 jdolecek int
950 1.138 lukem emul_register(const struct emul *emul, int ro_entry)
951 1.130 jdolecek {
952 1.138 lukem struct emul_entry *ee;
953 1.138 lukem int error;
954 1.130 jdolecek
955 1.138 lukem error = 0;
956 1.130 jdolecek lockmgr(&exec_lock, LK_SHARED, NULL);
957 1.130 jdolecek
958 1.130 jdolecek if (emul_search(emul->e_name)) {
959 1.130 jdolecek error = EEXIST;
960 1.130 jdolecek goto out;
961 1.130 jdolecek }
962 1.130 jdolecek
963 1.130 jdolecek MALLOC(ee, struct emul_entry *, sizeof(struct emul_entry),
964 1.130 jdolecek M_EXEC, M_WAITOK);
965 1.130 jdolecek ee->el_emul = emul;
966 1.130 jdolecek ee->ro_entry = ro_entry;
967 1.130 jdolecek LIST_INSERT_HEAD(&el_head, ee, el_list);
968 1.130 jdolecek
969 1.138 lukem out:
970 1.130 jdolecek lockmgr(&exec_lock, LK_RELEASE, NULL);
971 1.130 jdolecek return error;
972 1.130 jdolecek }
973 1.130 jdolecek
974 1.130 jdolecek /*
975 1.130 jdolecek * Remove emulation with name 'name' from list of supported emulations.
976 1.130 jdolecek */
977 1.130 jdolecek int
978 1.138 lukem emul_unregister(const char *name)
979 1.130 jdolecek {
980 1.130 jdolecek const struct proclist_desc *pd;
981 1.138 lukem struct emul_entry *it;
982 1.138 lukem int i, error;
983 1.138 lukem struct proc *ptmp;
984 1.130 jdolecek
985 1.138 lukem error = 0;
986 1.130 jdolecek lockmgr(&exec_lock, LK_SHARED, NULL);
987 1.130 jdolecek
988 1.130 jdolecek LIST_FOREACH(it, &el_head, el_list) {
989 1.130 jdolecek if (strcmp(it->el_emul->e_name, name) == 0)
990 1.130 jdolecek break;
991 1.130 jdolecek }
992 1.130 jdolecek
993 1.130 jdolecek if (!it) {
994 1.130 jdolecek error = ENOENT;
995 1.130 jdolecek goto out;
996 1.130 jdolecek }
997 1.130 jdolecek
998 1.130 jdolecek if (it->ro_entry) {
999 1.130 jdolecek error = EBUSY;
1000 1.130 jdolecek goto out;
1001 1.130 jdolecek }
1002 1.130 jdolecek
1003 1.130 jdolecek /* test if any execw[] entry is still using this */
1004 1.132 jdolecek for(i=0; i < nexecs; i++) {
1005 1.130 jdolecek if (execsw[i]->es_emul == it->el_emul) {
1006 1.130 jdolecek error = EBUSY;
1007 1.130 jdolecek goto out;
1008 1.130 jdolecek }
1009 1.130 jdolecek }
1010 1.130 jdolecek
1011 1.130 jdolecek /*
1012 1.130 jdolecek * Test if any process is running under this emulation - since
1013 1.130 jdolecek * emul_unregister() is running quite sendomly, it's better
1014 1.130 jdolecek * to do expensive check here than to use any locking.
1015 1.130 jdolecek */
1016 1.130 jdolecek proclist_lock_read();
1017 1.130 jdolecek for (pd = proclists; pd->pd_list != NULL && !error; pd++) {
1018 1.130 jdolecek LIST_FOREACH(ptmp, pd->pd_list, p_list) {
1019 1.130 jdolecek if (ptmp->p_emul == it->el_emul) {
1020 1.130 jdolecek error = EBUSY;
1021 1.130 jdolecek break;
1022 1.130 jdolecek }
1023 1.130 jdolecek }
1024 1.130 jdolecek }
1025 1.130 jdolecek proclist_unlock_read();
1026 1.130 jdolecek
1027 1.130 jdolecek if (error)
1028 1.130 jdolecek goto out;
1029 1.130 jdolecek
1030 1.130 jdolecek
1031 1.130 jdolecek /* entry is not used, remove it */
1032 1.130 jdolecek LIST_REMOVE(it, el_list);
1033 1.130 jdolecek FREE(it, M_EXEC);
1034 1.130 jdolecek
1035 1.138 lukem out:
1036 1.130 jdolecek lockmgr(&exec_lock, LK_RELEASE, NULL);
1037 1.130 jdolecek return error;
1038 1.130 jdolecek }
1039 1.130 jdolecek
1040 1.130 jdolecek /*
1041 1.130 jdolecek * Add execsw[] entry.
1042 1.130 jdolecek */
1043 1.130 jdolecek int
1044 1.138 lukem exec_add(struct execsw *esp, const char *e_name)
1045 1.130 jdolecek {
1046 1.138 lukem struct exec_entry *it;
1047 1.138 lukem int error;
1048 1.130 jdolecek
1049 1.138 lukem error = 0;
1050 1.130 jdolecek lockmgr(&exec_lock, LK_EXCLUSIVE, NULL);
1051 1.130 jdolecek
1052 1.130 jdolecek if (!esp->es_emul) {
1053 1.130 jdolecek esp->es_emul = emul_search(e_name);
1054 1.130 jdolecek if (!esp->es_emul) {
1055 1.130 jdolecek error = ENOENT;
1056 1.130 jdolecek goto out;
1057 1.130 jdolecek }
1058 1.130 jdolecek }
1059 1.130 jdolecek
1060 1.130 jdolecek LIST_FOREACH(it, &ex_head, ex_list) {
1061 1.130 jdolecek /* assume tuple (makecmds, probe_func, emulation) is unique */
1062 1.130 jdolecek if (it->es->es_check == esp->es_check
1063 1.130 jdolecek && it->es->u.elf_probe_func == esp->u.elf_probe_func
1064 1.130 jdolecek && it->es->es_emul == esp->es_emul) {
1065 1.130 jdolecek error = EEXIST;
1066 1.130 jdolecek goto out;
1067 1.130 jdolecek }
1068 1.130 jdolecek }
1069 1.130 jdolecek
1070 1.130 jdolecek /* if we got here, the entry doesn't exist yet */
1071 1.130 jdolecek MALLOC(it, struct exec_entry *, sizeof(struct exec_entry),
1072 1.130 jdolecek M_EXEC, M_WAITOK);
1073 1.130 jdolecek it->es = esp;
1074 1.130 jdolecek LIST_INSERT_HEAD(&ex_head, it, ex_list);
1075 1.130 jdolecek
1076 1.130 jdolecek /* update execsw[] */
1077 1.130 jdolecek exec_init(0);
1078 1.130 jdolecek
1079 1.138 lukem out:
1080 1.130 jdolecek lockmgr(&exec_lock, LK_RELEASE, NULL);
1081 1.130 jdolecek return error;
1082 1.130 jdolecek }
1083 1.130 jdolecek
1084 1.130 jdolecek /*
1085 1.130 jdolecek * Remove execsw[] entry.
1086 1.130 jdolecek */
1087 1.130 jdolecek int
1088 1.138 lukem exec_remove(const struct execsw *esp)
1089 1.130 jdolecek {
1090 1.138 lukem struct exec_entry *it;
1091 1.138 lukem int error;
1092 1.130 jdolecek
1093 1.138 lukem error = 0;
1094 1.130 jdolecek lockmgr(&exec_lock, LK_EXCLUSIVE, NULL);
1095 1.130 jdolecek
1096 1.130 jdolecek LIST_FOREACH(it, &ex_head, ex_list) {
1097 1.130 jdolecek /* assume tuple (makecmds, probe_func, emulation) is unique */
1098 1.130 jdolecek if (it->es->es_check == esp->es_check
1099 1.130 jdolecek && it->es->u.elf_probe_func == esp->u.elf_probe_func
1100 1.130 jdolecek && it->es->es_emul == esp->es_emul)
1101 1.130 jdolecek break;
1102 1.130 jdolecek }
1103 1.130 jdolecek if (!it) {
1104 1.130 jdolecek error = ENOENT;
1105 1.130 jdolecek goto out;
1106 1.130 jdolecek }
1107 1.130 jdolecek
1108 1.130 jdolecek /* remove item from list and free resources */
1109 1.130 jdolecek LIST_REMOVE(it, ex_list);
1110 1.130 jdolecek FREE(it, M_EXEC);
1111 1.130 jdolecek
1112 1.130 jdolecek /* update execsw[] */
1113 1.130 jdolecek exec_init(0);
1114 1.130 jdolecek
1115 1.138 lukem out:
1116 1.130 jdolecek lockmgr(&exec_lock, LK_RELEASE, NULL);
1117 1.130 jdolecek return error;
1118 1.130 jdolecek }
1119 1.130 jdolecek
1120 1.130 jdolecek static void
1121 1.138 lukem link_es(struct execsw_entry **listp, const struct execsw *esp)
1122 1.130 jdolecek {
1123 1.130 jdolecek struct execsw_entry *et, *e1;
1124 1.130 jdolecek
1125 1.130 jdolecek MALLOC(et, struct execsw_entry *, sizeof(struct execsw_entry),
1126 1.130 jdolecek M_TEMP, M_WAITOK);
1127 1.130 jdolecek et->next = NULL;
1128 1.130 jdolecek et->es = esp;
1129 1.130 jdolecek if (*listp == NULL) {
1130 1.130 jdolecek *listp = et;
1131 1.130 jdolecek return;
1132 1.130 jdolecek }
1133 1.130 jdolecek
1134 1.130 jdolecek switch(et->es->es_prio) {
1135 1.130 jdolecek case EXECSW_PRIO_FIRST:
1136 1.130 jdolecek /* put new entry as the first */
1137 1.130 jdolecek et->next = *listp;
1138 1.130 jdolecek *listp = et;
1139 1.130 jdolecek break;
1140 1.130 jdolecek case EXECSW_PRIO_ANY:
1141 1.130 jdolecek /* put new entry after all *_FIRST and *_ANY entries */
1142 1.130 jdolecek for(e1 = *listp; e1->next
1143 1.130 jdolecek && e1->next->es->es_prio != EXECSW_PRIO_LAST;
1144 1.130 jdolecek e1 = e1->next);
1145 1.130 jdolecek et->next = e1->next;
1146 1.130 jdolecek e1->next = et;
1147 1.130 jdolecek break;
1148 1.130 jdolecek case EXECSW_PRIO_LAST:
1149 1.130 jdolecek /* put new entry as the last one */
1150 1.130 jdolecek for(e1 = *listp; e1->next; e1 = e1->next);
1151 1.130 jdolecek e1->next = et;
1152 1.130 jdolecek break;
1153 1.130 jdolecek default:
1154 1.130 jdolecek #ifdef DIAGNOSTIC
1155 1.157 provos panic("execw[] entry with unknown priority %d found",
1156 1.130 jdolecek et->es->es_prio);
1157 1.130 jdolecek #endif
1158 1.130 jdolecek break;
1159 1.130 jdolecek }
1160 1.130 jdolecek }
1161 1.130 jdolecek
1162 1.130 jdolecek /*
1163 1.130 jdolecek * Initialize exec structures. If init_boot is true, also does necessary
1164 1.130 jdolecek * one-time initialization (it's called from main() that way).
1165 1.147 jdolecek * Once system is multiuser, this should be called with exec_lock held,
1166 1.130 jdolecek * i.e. via exec_{add|remove}().
1167 1.130 jdolecek */
1168 1.130 jdolecek int
1169 1.138 lukem exec_init(int init_boot)
1170 1.130 jdolecek {
1171 1.138 lukem const struct execsw **new_es, * const *old_es;
1172 1.138 lukem struct execsw_entry *list, *e1;
1173 1.138 lukem struct exec_entry *e2;
1174 1.138 lukem int i, es_sz;
1175 1.130 jdolecek
1176 1.130 jdolecek if (init_boot) {
1177 1.130 jdolecek /* do one-time initializations */
1178 1.130 jdolecek lockinit(&exec_lock, PWAIT, "execlck", 0, 0);
1179 1.130 jdolecek
1180 1.130 jdolecek /* register compiled-in emulations */
1181 1.130 jdolecek for(i=0; i < nexecs_builtin; i++) {
1182 1.130 jdolecek if (execsw_builtin[i].es_emul)
1183 1.130 jdolecek emul_register(execsw_builtin[i].es_emul, 1);
1184 1.130 jdolecek }
1185 1.130 jdolecek #ifdef DIAGNOSTIC
1186 1.130 jdolecek if (i == 0)
1187 1.157 provos panic("no emulations found in execsw_builtin[]");
1188 1.130 jdolecek #endif
1189 1.130 jdolecek }
1190 1.130 jdolecek
1191 1.130 jdolecek /*
1192 1.130 jdolecek * Build execsw[] array from builtin entries and entries added
1193 1.130 jdolecek * at runtime.
1194 1.130 jdolecek */
1195 1.130 jdolecek list = NULL;
1196 1.130 jdolecek for(i=0; i < nexecs_builtin; i++)
1197 1.130 jdolecek link_es(&list, &execsw_builtin[i]);
1198 1.130 jdolecek
1199 1.130 jdolecek /* Add dynamically loaded entries */
1200 1.130 jdolecek es_sz = nexecs_builtin;
1201 1.130 jdolecek LIST_FOREACH(e2, &ex_head, ex_list) {
1202 1.130 jdolecek link_es(&list, e2->es);
1203 1.130 jdolecek es_sz++;
1204 1.130 jdolecek }
1205 1.130 jdolecek
1206 1.130 jdolecek /*
1207 1.130 jdolecek * Now that we have sorted all execw entries, create new execsw[]
1208 1.130 jdolecek * and free no longer needed memory in the process.
1209 1.130 jdolecek */
1210 1.130 jdolecek new_es = malloc(es_sz * sizeof(struct execsw *), M_EXEC, M_WAITOK);
1211 1.130 jdolecek for(i=0; list; i++) {
1212 1.130 jdolecek new_es[i] = list->es;
1213 1.130 jdolecek e1 = list->next;
1214 1.130 jdolecek FREE(list, M_TEMP);
1215 1.130 jdolecek list = e1;
1216 1.130 jdolecek }
1217 1.130 jdolecek
1218 1.130 jdolecek /*
1219 1.130 jdolecek * New execsw[] array built, now replace old execsw[] and free
1220 1.130 jdolecek * used memory.
1221 1.130 jdolecek */
1222 1.130 jdolecek old_es = execsw;
1223 1.130 jdolecek execsw = new_es;
1224 1.130 jdolecek nexecs = es_sz;
1225 1.130 jdolecek if (old_es)
1226 1.130 jdolecek free((void *)old_es, M_EXEC);
1227 1.130 jdolecek
1228 1.130 jdolecek /*
1229 1.130 jdolecek * Figure out the maximum size of an exec header.
1230 1.130 jdolecek */
1231 1.130 jdolecek exec_maxhdrsz = 0;
1232 1.130 jdolecek for (i = 0; i < nexecs; i++) {
1233 1.130 jdolecek if (execsw[i]->es_hdrsz > exec_maxhdrsz)
1234 1.130 jdolecek exec_maxhdrsz = execsw[i]->es_hdrsz;
1235 1.130 jdolecek }
1236 1.130 jdolecek
1237 1.130 jdolecek return 0;
1238 1.130 jdolecek }
1239 1.130 jdolecek #endif
1240 1.130 jdolecek
1241 1.130 jdolecek #ifndef LKM
1242 1.130 jdolecek /*
1243 1.130 jdolecek * Simplified exec_init() for kernels without LKMs. Only initialize
1244 1.130 jdolecek * exec_maxhdrsz and execsw[].
1245 1.130 jdolecek */
1246 1.130 jdolecek int
1247 1.138 lukem exec_init(int init_boot)
1248 1.130 jdolecek {
1249 1.130 jdolecek int i;
1250 1.130 jdolecek
1251 1.130 jdolecek #ifdef DIAGNOSTIC
1252 1.130 jdolecek if (!init_boot)
1253 1.130 jdolecek panic("exec_init(): called with init_boot == 0");
1254 1.130 jdolecek #endif
1255 1.130 jdolecek
1256 1.130 jdolecek /* do one-time initializations */
1257 1.130 jdolecek nexecs = nexecs_builtin;
1258 1.130 jdolecek execsw = malloc(nexecs*sizeof(struct execsw *), M_EXEC, M_WAITOK);
1259 1.130 jdolecek
1260 1.130 jdolecek /*
1261 1.130 jdolecek * Fill in execsw[] and figure out the maximum size of an exec header.
1262 1.130 jdolecek */
1263 1.130 jdolecek exec_maxhdrsz = 0;
1264 1.130 jdolecek for(i=0; i < nexecs; i++) {
1265 1.130 jdolecek execsw[i] = &execsw_builtin[i];
1266 1.130 jdolecek if (execsw_builtin[i].es_hdrsz > exec_maxhdrsz)
1267 1.130 jdolecek exec_maxhdrsz = execsw_builtin[i].es_hdrsz;
1268 1.130 jdolecek }
1269 1.130 jdolecek
1270 1.130 jdolecek return 0;
1271 1.130 jdolecek
1272 1.130 jdolecek }
1273 1.130 jdolecek #endif /* !LKM */
1274