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