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