xref: /original-bsd/sys/kern/kern_exec.c (revision deff14a8)
1 /*-
2  * Copyright (c) 1982, 1986, 1991, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  * (c) UNIX System Laboratories, Inc.
5  * All or some portions of this file are derived from material licensed
6  * to the University of California by American Telephone and Telegraph
7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8  * the permission of UNIX System Laboratories, Inc.
9  *
10  * %sccs.include.proprietary.c%
11  *
12  *	@(#)kern_exec.c	8.7 (Berkeley) 08/11/94
13  */
14 
15 #include <sys/param.h>
16 #include <sys/systm.h>
17 #include <sys/filedesc.h>
18 #include <sys/kernel.h>
19 #include <sys/proc.h>
20 #include <sys/mount.h>
21 #include <sys/malloc.h>
22 #include <sys/namei.h>
23 #include <sys/vnode.h>
24 #include <sys/file.h>
25 #include <sys/acct.h>
26 #include <sys/exec.h>
27 #include <sys/ktrace.h>
28 #include <sys/resourcevar.h>
29 
30 #include <machine/cpu.h>
31 #include <machine/reg.h>
32 
33 #include <sys/mman.h>
34 #include <vm/vm.h>
35 #include <vm/vm_param.h>
36 #include <vm/vm_map.h>
37 #include <vm/vm_kern.h>
38 #include <vm/vm_pager.h>
39 
40 #include <sys/signalvar.h>
41 
42 #ifdef HPUXCOMPAT
43 #include <sys/user.h>			/* for pcb */
44 #include <hp/hpux/hpux_exec.h>
45 #endif
46 
47 #ifdef COPY_SIGCODE
48 extern char sigcode[], esigcode[];
49 #define	szsigcode	(esigcode - sigcode)
50 #else
51 #define	szsigcode	0
52 #endif
53 
54 /*
55  * exec system call
56  */
57 execve(p, uap, retval)
58 	register struct proc *p;
59 	register struct execve_args *uap;
60 	int *retval;
61 {
62 	register struct ucred *cred = p->p_ucred;
63 	register struct filedesc *fdp = p->p_fd;
64 	int na, ne, ucp, ap, cc, ssize;
65 	register char *cp;
66 	register int nc;
67 	unsigned len;
68 	int indir, uid, gid;
69 	char *sharg;
70 	struct vnode *vp;
71 	int resid, error, paged = 0;
72 	vm_offset_t execargs = 0;
73 	struct vattr vattr;
74 	char cfarg[MAXINTERP];
75 	union {
76 		char	ex_shell[MAXINTERP];	/* #! and interpreter name */
77 		struct	exec ex_exec;
78 #ifdef HPUXCOMPAT
79 		struct	hpux_exec ex_hexec;
80 #endif
81 	} exdata;
82 #ifdef HPUXCOMPAT
83 	struct hpux_exec hhead;
84 #endif
85 	struct nameidata nd;
86 	struct ps_strings ps;
87 
88 	NDINIT(&nd, LOOKUP, FOLLOW | SAVENAME, UIO_USERSPACE,
89 		uap->fname, p);
90 	if (error = namei(&nd))
91 		return (error);
92 	vp = nd.ni_vp;
93 	VOP_LEASE(vp, p, cred, LEASE_READ);
94 	VOP_LOCK(vp);
95 	indir = 0;
96 	uid = cred->cr_uid;
97 	gid = cred->cr_gid;
98 	if (error = VOP_GETATTR(vp, &vattr, cred, p))
99 		goto bad;
100 	if (vp->v_mount->mnt_flag & MNT_NOEXEC) {
101 		error = EACCES;
102 		goto bad;
103 	}
104 	if ((vp->v_mount->mnt_flag & MNT_NOSUID) == 0) {
105 		if (vattr.va_mode & VSUID)
106 			uid = vattr.va_uid;
107 		if (vattr.va_mode & VSGID)
108 			gid = vattr.va_gid;
109 	}
110 
111   again:
112 	if (error = VOP_ACCESS(vp, VEXEC, cred, p))
113 		goto bad;
114 	if ((p->p_flag & P_TRACED) && (error = VOP_ACCESS(vp, VREAD, cred, p)))
115 		goto bad;
116 	if (vp->v_type != VREG ||
117 	    (vattr.va_mode & (VEXEC|(VEXEC>>3)|(VEXEC>>6))) == 0) {
118 		error = EACCES;
119 		goto bad;
120 	}
121 
122 	/*
123 	 * Read in first few bytes of file for segment sizes, magic number:
124 	 *	OMAGIC = plain executable
125 	 *	NMAGIC = RO text
126 	 *	ZMAGIC = demand paged RO text
127 	 * Also an ASCII line beginning with #! is
128 	 * the file name of a ``shell'' and arguments may be prepended
129 	 * to the argument list if given here.
130 	 *
131 	 * SHELL NAMES ARE LIMITED IN LENGTH.
132 	 *
133 	 * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM
134 	 * THE ASCII LINE.
135 	 */
136 	exdata.ex_shell[0] = '\0';	/* for zero length files */
137 	error = vn_rdwr(UIO_READ, vp, (caddr_t)&exdata, sizeof (exdata),
138 	    (off_t)0, UIO_SYSSPACE, (IO_UNIT|IO_NODELOCKED), cred, &resid,
139 	    (struct proc *)0);
140 	if (error)
141 		goto bad;
142 #ifndef lint
143 	if (resid > sizeof(exdata) - sizeof(exdata.ex_exec) &&
144 	    exdata.ex_shell[0] != '#') {
145 		error = ENOEXEC;
146 		goto bad;
147 	}
148 #endif
149 #if defined(hp300) || defined(luna68k)
150 	switch ((int)exdata.ex_exec.a_mid) {
151 
152 	/*
153 	 * An ancient hp200 or hp300 binary, shouldn't happen anymore.
154 	 * Mark as invalid.
155 	 */
156 	case MID_ZERO:
157 		exdata.ex_exec.a_magic = 0;
158 		break;
159 
160 	/*
161 	 * HP200 series has a smaller page size so we cannot
162 	 * demand-load or even write protect text, so we just
163 	 * treat as OMAGIC.
164 	 */
165 	case MID_HP200:
166 		exdata.ex_exec.a_magic = OMAGIC;
167 		break;
168 
169 	case MID_HP300:
170 		break;
171 
172 #ifdef HPUXCOMPAT
173 	case MID_HPUX:
174 		/*
175 		 * Save a.out header.  This is eventually saved in the pcb,
176 		 * but we cannot do that yet in case the exec fails before
177 		 * the image is overlayed.
178 		 */
179 		bcopy((caddr_t)&exdata.ex_hexec,
180 		      (caddr_t)&hhead, sizeof hhead);
181 		/*
182 		 * Shuffle important fields to their BSD locations.
183 		 * Note that the order in which this is done is important.
184 		 */
185 		exdata.ex_exec.a_text = exdata.ex_hexec.ha_text;
186 		exdata.ex_exec.a_data = exdata.ex_hexec.ha_data;
187 		exdata.ex_exec.a_bss = exdata.ex_hexec.ha_bss;
188 		exdata.ex_exec.a_entry = exdata.ex_hexec.ha_entry;
189 		/*
190 		 * For ZMAGIC files, make sizes consistant with those
191 		 * generated by BSD ld.
192 		 */
193 		if (exdata.ex_exec.a_magic == ZMAGIC) {
194 			exdata.ex_exec.a_text =
195 				ctob(btoc(exdata.ex_exec.a_text));
196 			nc = exdata.ex_exec.a_data + exdata.ex_exec.a_bss;
197 			exdata.ex_exec.a_data =
198 				ctob(btoc(exdata.ex_exec.a_data));
199 			nc -= (int)exdata.ex_exec.a_data;
200 			exdata.ex_exec.a_bss = (nc < 0) ? 0 : nc;
201 		}
202 		break;
203 #endif
204 	}
205 #endif
206 	switch ((int)exdata.ex_exec.a_magic) {
207 
208 	case OMAGIC:
209 #ifdef COFF
210 		if (exdata.ex_exec.ex_fhdr.magic != COFF_MAGIC) {
211 			error = ENOEXEC;
212 			goto bad;
213 		}
214 #endif
215 #ifdef sparc
216 		if (exdata.ex_exec.a_mid != MID_SUN_SPARC) {
217 			error = ENOEXEC;
218 			goto bad;
219 		}
220 #endif
221 		exdata.ex_exec.a_data += exdata.ex_exec.a_text;
222 		exdata.ex_exec.a_text = 0;
223 		break;
224 
225 	case ZMAGIC:
226 		paged = 1;
227 		/* FALLTHROUGH */
228 
229 	case NMAGIC:
230 #ifdef COFF
231 		if (exdata.ex_exec.ex_fhdr.magic != COFF_MAGIC) {
232 			error = ENOEXEC;
233 			goto bad;
234 		}
235 #endif
236 #ifdef sparc
237 		if (exdata.ex_exec.a_mid != MID_SUN_SPARC) {
238 			error = ENOEXEC;
239 			goto bad;
240 		}
241 #endif
242 		if (exdata.ex_exec.a_text == 0) {
243 			error = ENOEXEC;
244 			goto bad;
245 		}
246 		break;
247 
248 	default:
249 		if (exdata.ex_shell[0] != '#' ||
250 		    exdata.ex_shell[1] != '!' ||
251 		    indir) {
252 			error = ENOEXEC;
253 			goto bad;
254 		}
255 		for (cp = &exdata.ex_shell[2];; ++cp) {
256 			if (cp >= &exdata.ex_shell[MAXINTERP]) {
257 				error = ENOEXEC;
258 				goto bad;
259 			}
260 			if (*cp == '\n') {
261 				*cp = '\0';
262 				break;
263 			}
264 			if (*cp == '\t')
265 				*cp = ' ';
266 		}
267 		cp = &exdata.ex_shell[2];
268 		while (*cp == ' ')
269 			cp++;
270 		nd.ni_dirp = cp;
271 		while (*cp && *cp != ' ')
272 			cp++;
273 		cfarg[0] = '\0';
274 		if (*cp) {
275 			*cp++ = '\0';
276 			while (*cp == ' ')
277 				cp++;
278 			if (*cp)
279 				bcopy((caddr_t)cp, (caddr_t)cfarg, MAXINTERP);
280 		}
281 		indir = 1;
282 		vput(vp);
283 		nd.ni_segflg = UIO_SYSSPACE;
284 		if (error = namei(&nd))
285 			return (error);
286 		vp = nd.ni_vp;
287 		VOP_LEASE(vp, p, cred, LEASE_READ);
288 		VOP_LOCK(vp);
289 		if (error = VOP_GETATTR(vp, &vattr, cred, p))
290 			goto bad;
291 		uid = cred->cr_uid;	/* shell scripts can't be setuid */
292 		gid = cred->cr_gid;
293 		goto again;
294 	}
295 
296 	/*
297 	 * Collect arguments on "file" in swap space.
298 	 */
299 	na = 0;
300 	ne = 0;
301 	nc = 0;
302 	cc = NCARGS;
303 	execargs = kmem_alloc_wait(exec_map, NCARGS);
304 #ifdef DIAGNOSTIC
305 	if (execargs == (vm_offset_t)0)
306 		panic("execve: kmem_alloc_wait");
307 #endif
308 	cp = (char *) execargs;
309 	/*
310 	 * Copy arguments into file in argdev area.
311 	 */
312 	if (uap->argp) for (;;) {
313 		ap = NULL;
314 		sharg = NULL;
315 		if (indir && na == 0) {
316 			sharg = nd.ni_cnd.cn_nameptr;
317 			ap = (int)sharg;
318 			uap->argp++;		/* ignore argv[0] */
319 		} else if (indir && (na == 1 && cfarg[0])) {
320 			sharg = cfarg;
321 			ap = (int)sharg;
322 		} else if (indir && (na == 1 || na == 2 && cfarg[0]))
323 			ap = (int)uap->fname;
324 		else if (uap->argp) {
325 			ap = fuword((caddr_t)uap->argp);
326 			uap->argp++;
327 		}
328 		if (ap == NULL && uap->envp) {
329 			uap->argp = NULL;
330 			if ((ap = fuword((caddr_t)uap->envp)) != NULL)
331 				uap->envp++, ne++;
332 		}
333 		if (ap == NULL)
334 			break;
335 		na++;
336 		if (ap == -1) {
337 			error = EFAULT;
338 			goto bad;
339 		}
340 		do {
341 			if (nc >= NCARGS-1) {
342 				error = E2BIG;
343 				break;
344 			}
345 			if (sharg) {
346 				error = copystr(sharg, cp, (unsigned)cc, &len);
347 				sharg += len;
348 			} else {
349 				error = copyinstr((caddr_t)ap, cp, (unsigned)cc,
350 				    &len);
351 				ap += len;
352 			}
353 			cp += len;
354 			nc += len;
355 			cc -= len;
356 		} while (error == ENAMETOOLONG);
357 		if (error)
358 			goto bad;
359 	}
360 
361 	/*
362 	 * XXX the following is excessively bogus
363 	 *
364 	 * Compute initial process stack size and location of argc
365 	 * and character strings.  `nc' is currently just the number
366 	 * of characters of arg and env strings.
367 	 *
368 	 * nc = size of ps_strings structure +
369 	 *	size of signal code +
370 	 *	4 bytes of NULL pointer +
371 	 *	nc,
372 	 * rounded to nearest integer;
373 	 * ucp = USRSTACK - nc;		[user characters pointer]
374 	 * apsize = padding (if any) +
375 	 *	4 bytes of NULL pointer +
376 	 *	ne 4-byte pointers to env strings +
377 	 *	4 bytes of NULL pointer +
378 	 *	(na-ne) 4-byte pointers to arg strings +
379 	 *	4 bytes of argc;
380 	 * (this is the same as nc + (na+3)*4)
381 	 * ap = ucp - apsize;	[user address of argc]
382 	 * ssize = ssize + nc + machine-dependent space;
383 	 */
384 	nc = (sizeof(ps) + szsigcode + 4 + nc + NBPW-1) & ~(NBPW - 1);
385 #if defined(sparc) || defined(mips)
386 	ucp = USRSTACK;
387 	ssize = ALIGN(nc + (na + 3) * NBPW);
388 	ap = ucp - ssize;
389 	ucp -= nc;
390 #ifdef sparc
391 	ssize += sizeof(struct rwindow);
392 #endif
393 #else
394 	ssize = (na + 3) * NBPW;
395 	ucp = USRSTACK - nc;
396 	ap = ucp - ssize;
397 	ssize += nc;
398 #endif
399 	error = getxfile(p, vp, &exdata.ex_exec, paged, ssize, uid, gid);
400 	if (error)
401 		goto bad;
402 
403 	/* take a reference to the new text vnode (for procfs) */
404 	if (p->p_textvp)
405 		vrele(p->p_textvp);
406 	VREF(vp);
407 	p->p_textvp = vp;
408 
409 	vput(vp);
410 	vp = NULL;
411 
412 #ifdef HPUXCOMPAT
413 	/*
414 	 * We are now committed to the exec so we can save the exec
415 	 * header in the pcb where we can dump it if necessary in core()
416 	 */
417 	if (p->p_md.md_flags & MDP_HPUX)
418 		bcopy((caddr_t)&hhead,
419 		      (caddr_t)p->p_addr->u_md.md_exec, sizeof hhead);
420 #endif
421 
422 	/*
423 	 * Copy back arglist.
424 	 */
425 	cpu_setstack(p, ap);
426 	(void) suword((caddr_t)ap, na-ne);
427 	nc = 0;
428 	cp = (char *) execargs;
429 	cc = NCARGS;
430 	ps.ps_argvstr = (char *)ucp;	/* first argv string */
431 	ps.ps_nargvstr = na - ne;	/* argc */
432 	for (;;) {
433 		ap += NBPW;
434 		if (na == ne) {
435 			(void) suword((caddr_t)ap, 0);
436 			ap += NBPW;
437 			ps.ps_envstr = (char *)ucp;
438 			ps.ps_nenvstr = ne;
439 		}
440 		if (--na < 0)
441 			break;
442 		(void) suword((caddr_t)ap, ucp);
443 		do {
444 			error = copyoutstr(cp, (caddr_t)ucp, (unsigned)cc,
445 			    &len);
446 			ucp += len;
447 			cp += len;
448 			nc += len;
449 			cc -= len;
450 		} while (error == ENAMETOOLONG);
451 		if (error == EFAULT)
452 			panic("exec: EFAULT");
453 	}
454 	(void) suword((caddr_t)ap, 0);
455 	(void) copyout((caddr_t)&ps, (caddr_t)PS_STRINGS, sizeof(ps));
456 
457 	execsigs(p);
458 
459 	for (nc = fdp->fd_lastfile; nc >= 0; --nc) {
460 		if (fdp->fd_ofileflags[nc] & UF_EXCLOSE) {
461 			(void) closef(fdp->fd_ofiles[nc], p);
462 			fdp->fd_ofiles[nc] = NULL;
463 			fdp->fd_ofileflags[nc] = 0;
464 			if (nc < fdp->fd_freefile)
465 				fdp->fd_freefile = nc;
466 		}
467 		fdp->fd_ofileflags[nc] &= ~UF_MAPPED;
468 	}
469 	/*
470 	 * Adjust fd_lastfile to account for descriptors closed above.
471 	 * Don't decrement fd_lastfile past 0, as it's unsigned.
472 	 */
473 	while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
474 		fdp->fd_lastfile--;
475 	setregs(p, exdata.ex_exec.a_entry, retval);
476 #ifdef COPY_SIGCODE
477 	/*
478 	 * Install sigcode at top of user stack.
479 	 */
480 	copyout((caddr_t)sigcode, (caddr_t)PS_STRINGS - szsigcode, szsigcode);
481 #endif
482 	/*
483 	 * Remember file name for accounting.
484 	 */
485 	p->p_acflag &= ~AFORK;
486 	if (nd.ni_cnd.cn_namelen > MAXCOMLEN)
487 		nd.ni_cnd.cn_namelen = MAXCOMLEN;
488 	bcopy((caddr_t)nd.ni_cnd.cn_nameptr, (caddr_t)p->p_comm,
489 	    (unsigned)nd.ni_cnd.cn_namelen);
490 	p->p_comm[nd.ni_cnd.cn_namelen] = '\0';
491 	cpu_exec(p);
492 bad:
493 	FREE(nd.ni_cnd.cn_pnbuf, M_NAMEI);
494 	if (execargs)
495 		kmem_free_wakeup(exec_map, execargs, NCARGS);
496 	if (vp)
497 		vput(vp);
498 	return (error);
499 }
500 
501 /*
502  * Read in and set up memory for executed file.
503  */
504 getxfile(p, vp, ep, paged, ssize, uid, gid)
505 	register struct proc *p;
506 	register struct vnode *vp;
507 	register struct exec *ep;
508 	int paged, ssize, uid, gid;
509 {
510 	register struct ucred *cred = p->p_ucred;
511 	register struct vmspace *vm = p->p_vmspace;
512 	vm_offset_t addr;
513 	vm_size_t xts, size;
514 	segsz_t ds;
515 	off_t toff;
516 	int error = 0;
517 
518 #ifdef HPUXCOMPAT
519 	if (ep->a_mid == MID_HPUX)
520 		toff = paged ? CLBYTES : sizeof(struct hpux_exec);
521 	else
522 #endif
523 #ifdef COFF
524 	toff = N_TXTOFF(*ep);
525 #else
526 #ifdef sparc
527 	if (ep->a_mid == MID_SUN_SPARC)
528 		toff = paged ? 0 : sizeof(struct exec);
529 	else
530 #endif
531 	if (paged)
532 #ifdef mips
533 		toff = 0;
534 #else
535 		toff = CLBYTES;
536 #endif
537 	else
538 		toff = sizeof (struct exec);
539 #endif
540 	if (ep->a_text != 0 && (vp->v_flag & VTEXT) == 0 &&
541 	    vp->v_writecount != 0)
542 		return (ETXTBSY);
543 
544 	/*
545 	 * Compute text and data sizes and make sure not too large.
546 	 * Text size is rounded to an ``ld page''; data+bss is left
547 	 * in machine pages.  Check data and bss separately as they
548 	 * may overflow when summed together.  (XXX not done yet)
549 	 */
550 	xts = roundup(ep->a_text, __LDPGSZ);
551 	ds = clrnd(btoc(ep->a_data + ep->a_bss));
552 
553 	/*
554 	 * If we're sharing the address space, allocate a new space
555 	 * and release our reference to the old one.  Otherwise,
556 	 * empty out the existing vmspace.
557 	 */
558 #ifdef sparc
559 	kill_user_windows(p);		/* before addrs go away */
560 #endif
561 	if (vm->vm_refcnt > 1) {
562 		p->p_vmspace = vmspace_alloc(VM_MIN_ADDRESS,
563 		    VM_MAXUSER_ADDRESS, 1);
564 		vmspace_free(vm);
565 		vm = p->p_vmspace;
566 	} else {
567 #ifdef SYSVSHM
568 		if (vm->vm_shm)
569 			shmexit(p);
570 #endif
571 		(void) vm_map_remove(&vm->vm_map, VM_MIN_ADDRESS,
572 		    VM_MAXUSER_ADDRESS);
573 	}
574 	/*
575 	 * If parent is waiting for us to exec or exit,
576 	 * P_PPWAIT will be set; clear it and wakeup parent.
577 	 */
578 	if (p->p_flag & P_PPWAIT) {
579 		p->p_flag &= ~P_PPWAIT;
580 		wakeup((caddr_t) p->p_pptr);
581 	}
582 #if defined(HP380) || defined(LUNA2)
583 	/* default to copyback caching on 68040 */
584 	if (mmutype == MMU_68040)
585 		p->p_md.md_flags |= (MDP_CCBDATA|MDP_CCBSTACK);
586 #endif
587 #ifdef HPUXCOMPAT
588 	p->p_md.md_flags &= ~(MDP_HPUX|MDP_HPUXMMAP);
589 	/* note that we are an HP-UX binary */
590 	if (ep->a_mid == MID_HPUX)
591 		p->p_md.md_flags |= MDP_HPUX;
592 	/* deal with miscellaneous attributes */
593 	if (ep->a_trsize & HPUXM_VALID) {
594 		if (ep->a_trsize & HPUXM_DATAWT)
595 			p->p_md.md_flags &= ~MDP_CCBDATA;
596 		if (ep->a_trsize & HPUXM_STKWT)
597 			p->p_md.md_flags &= ~MDP_CCBSTACK;
598 	}
599 #endif
600 #ifdef ULTRIXCOMPAT
601 	/*
602 	 * Always start out as an ULTRIX process.
603 	 * A system call in crt0.o will change us to BSD system calls later.
604 	 */
605 	p->p_md.md_flags |= MDP_ULTRIX;
606 #endif
607 	p->p_flag |= P_EXEC;
608 #ifndef COFF
609 	addr = VM_MIN_ADDRESS;
610 	if (vm_allocate(&vm->vm_map, &addr, xts + ctob(ds), FALSE)) {
611 		uprintf("Cannot allocate text+data space\n");
612 		error = ENOMEM;			/* XXX */
613 		goto badmap;
614 	}
615 	vm->vm_taddr = (caddr_t)VM_MIN_ADDRESS;
616 	vm->vm_daddr = (caddr_t)(VM_MIN_ADDRESS + xts);
617 #else /* COFF */
618 	addr = (vm_offset_t)ep->ex_aout.codeStart;
619 	vm->vm_taddr = (caddr_t)addr;
620 	if (vm_allocate(&vm->vm_map, &addr, xts, FALSE)) {
621 		uprintf("Cannot allocate text space\n");
622 		error = ENOMEM;			/* XXX */
623 		goto badmap;
624 	}
625 	addr = (vm_offset_t)ep->ex_aout.heapStart;
626 	vm->vm_daddr = (caddr_t)addr;
627 	if (vm_allocate(&vm->vm_map, &addr, round_page(ctob(ds)), FALSE)) {
628 		uprintf("Cannot allocate data space\n");
629 		error = ENOMEM;			/* XXX */
630 		goto badmap;
631 	}
632 #endif /* COFF */
633 	size = round_page(MAXSSIZ);		/* XXX */
634 #ifdef	i386
635 	addr = trunc_page(USRSTACK - size) - NBPG;	/* XXX */
636 #else
637 	addr = trunc_page(USRSTACK - size);
638 #endif
639 	if (vm_allocate(&vm->vm_map, &addr, size, FALSE)) {
640 		uprintf("Cannot allocate stack space\n");
641 		error = ENOMEM;			/* XXX */
642 		goto badmap;
643 	}
644 	size -= round_page(p->p_rlimit[RLIMIT_STACK].rlim_cur);
645 	if (vm_map_protect(&vm->vm_map, addr, addr+size, VM_PROT_NONE, FALSE)) {
646 		uprintf("Cannot protect stack space\n");
647 		error = ENOMEM;
648 		goto badmap;
649 	}
650 	vm->vm_maxsaddr = (caddr_t)addr;
651 
652 	if (paged == 0) {
653 		/*
654 		 * Read in data segment.
655 		 */
656 		(void) vn_rdwr(UIO_READ, vp, vm->vm_daddr, (int) ep->a_data,
657 			(off_t)(toff + ep->a_text), UIO_USERSPACE,
658 			(IO_UNIT|IO_NODELOCKED), cred, (int *)0, p);
659 		/*
660 		 * Read in text segment if necessary (0410),
661 		 * and read-protect it.
662 		 */
663 		if (ep->a_text > 0) {
664 			error = vn_rdwr(UIO_READ, vp, vm->vm_taddr,
665 			    (int)ep->a_text, toff, UIO_USERSPACE,
666 			    (IO_UNIT|IO_NODELOCKED), cred, (int *)0, p);
667 			(void) vm_map_protect(&vm->vm_map,
668 			    (vm_offset_t)vm->vm_taddr,
669 			    (vm_offset_t)vm->vm_taddr + trunc_page(ep->a_text),
670 			    VM_PROT_READ|VM_PROT_EXECUTE, FALSE);
671 		}
672 	} else {
673 		/*
674 		 * Allocate a region backed by the exec'ed vnode.
675 		 */
676 #ifndef COFF
677 		addr = VM_MIN_ADDRESS;
678 		size = round_page(xts + ep->a_data);
679 		error = vm_mmap(&vm->vm_map, &addr, size,
680 			VM_PROT_ALL, VM_PROT_ALL,
681 			MAP_COPY|MAP_FIXED,
682 			(caddr_t)vp, (vm_offset_t)toff);
683 		(void) vm_map_protect(&vm->vm_map, addr, addr + xts,
684 			VM_PROT_READ|VM_PROT_EXECUTE, FALSE);
685 #else /* COFF */
686 		addr = (vm_offset_t)vm->vm_taddr;
687 		size = xts;
688 		error = vm_mmap(&vm->vm_map, &addr, size,
689 			VM_PROT_READ|VM_PROT_EXECUTE, VM_PROT_ALL,
690 			MAP_COPY|MAP_FIXED,
691 			(caddr_t)vp, (vm_offset_t)toff);
692 		toff += size;
693 		addr = (vm_offset_t)vm->vm_daddr;
694 		size = round_page(ep->a_data);
695 		error = vm_mmap(&vm->vm_map, &addr, size,
696 			VM_PROT_ALL, VM_PROT_ALL,
697 			MAP_COPY|MAP_FIXED,
698 			(caddr_t)vp, (vm_offset_t)toff);
699 #endif /* COFF */
700 		vp->v_flag |= VTEXT;
701 	}
702 	if (error) {
703 badmap:
704 		killproc(p, "VM allocation in exec");
705 		p->p_flag |= P_NOSWAP;
706 		return(error);
707 	}
708 
709 	/*
710 	 * set SUID/SGID protections, if no tracing
711 	 */
712 	p->p_flag &= ~P_SUGID;
713 	if ((p->p_flag & P_TRACED) == 0) {
714 		if (uid != cred->cr_uid || gid != cred->cr_gid) {
715 			p->p_ucred = cred = crcopy(cred);
716 #ifdef KTRACE
717 			/*
718 			 * If process is being ktraced, turn off - unless
719 			 * root set it.
720 			 */
721 			if (p->p_tracep && !(p->p_traceflag & KTRFAC_ROOT)) {
722 				vrele(p->p_tracep);
723 				p->p_tracep = NULL;
724 				p->p_traceflag = 0;
725 			}
726 #endif
727 			cred->cr_uid = uid;
728 			cred->cr_gid = gid;
729 			p->p_flag |= P_SUGID;
730 		}
731 	} else
732 		psignal(p, SIGTRAP);
733 	p->p_cred->p_svuid = cred->cr_uid;
734 	p->p_cred->p_svgid = cred->cr_gid;
735 	vm->vm_tsize = btoc(xts);
736 	vm->vm_dsize = ds;
737 	vm->vm_ssize = btoc(ssize);
738 	if (p->p_flag & P_PROFIL)
739 		stopprofclock(p);
740 #if defined(tahoe)
741 	/* move this when tahoe cpu_exec is created */
742 	p->p_addr->u_pcb.pcb_savacc.faddr = (float *)NULL;
743 #endif
744 	return (0);
745 }
746