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