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