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