xref: /csrg-svn/sys/kern/kern_exec.c (revision 52539)
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.52 (Berkeley) 02/15/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 		paged = 1;
232 		/* FALLTHROUGH */
233 
234 	case NMAGIC:
235 #ifdef COFF
236 		if (exdata.ex_exec.ex_fhdr.magic != COFF_MAGIC) {
237 			error = ENOEXEC;
238 			goto bad;
239 		}
240 #endif
241 #ifdef sparc
242 		if (exdata.ex_exec.a_mid != MID_SUN_SPARC) {
243 			error = ENOEXEC;
244 			goto bad;
245 		}
246 #endif
247 		if (exdata.ex_exec.a_text == 0) {
248 			error = ENOEXEC;
249 			goto bad;
250 		}
251 		break;
252 
253 	default:
254 		if (exdata.ex_shell[0] != '#' ||
255 		    exdata.ex_shell[1] != '!' ||
256 		    indir) {
257 			error = ENOEXEC;
258 			goto bad;
259 		}
260 		for (cp = &exdata.ex_shell[2];; ++cp) {
261 			if (cp >= &exdata.ex_shell[MAXINTERP]) {
262 				error = ENOEXEC;
263 				goto bad;
264 			}
265 			if (*cp == '\n') {
266 				*cp = '\0';
267 				break;
268 			}
269 			if (*cp == '\t')
270 				*cp = ' ';
271 		}
272 		cp = &exdata.ex_shell[2];
273 		while (*cp == ' ')
274 			cp++;
275 		nd.ni_dirp = cp;
276 		while (*cp && *cp != ' ')
277 			cp++;
278 		cfarg[0] = '\0';
279 		if (*cp) {
280 			*cp++ = '\0';
281 			while (*cp == ' ')
282 				cp++;
283 			if (*cp)
284 				bcopy((caddr_t)cp, (caddr_t)cfarg, MAXINTERP);
285 		}
286 		indir = 1;
287 		vput(vp);
288 		nd.ni_segflg = UIO_SYSSPACE;
289 		if (error = namei(&nd))
290 			return (error);
291 		vp = nd.ni_vp;
292 		if (error = VOP_GETATTR(vp, &vattr, cred, p))
293 			goto bad;
294 		uid = cred->cr_uid;	/* shell scripts can't be setuid */
295 		gid = cred->cr_gid;
296 		goto again;
297 	}
298 
299 	/*
300 	 * Collect arguments on "file" in swap space.
301 	 */
302 	na = 0;
303 	ne = 0;
304 	nc = 0;
305 	cc = NCARGS;
306 	execargs = kmem_alloc_wait(exec_map, NCARGS);
307 #ifdef DIAGNOSTIC
308 	if (execargs == (vm_offset_t)0)
309 		panic("execve: kmem_alloc_wait");
310 #endif
311 	cp = (char *) execargs;
312 	/*
313 	 * Copy arguments into file in argdev area.
314 	 */
315 	if (uap->argp) for (;;) {
316 		ap = NULL;
317 		sharg = NULL;
318 		if (indir && na == 0) {
319 			sharg = nd.ni_cnd.cn_nameptr;
320 			ap = (int)sharg;
321 			uap->argp++;		/* ignore argv[0] */
322 		} else if (indir && (na == 1 && cfarg[0])) {
323 			sharg = cfarg;
324 			ap = (int)sharg;
325 		} else if (indir && (na == 1 || na == 2 && cfarg[0]))
326 			ap = (int)uap->fname;
327 		else if (uap->argp) {
328 			ap = fuword((caddr_t)uap->argp);
329 			uap->argp++;
330 		}
331 		if (ap == NULL && uap->envp) {
332 			uap->argp = NULL;
333 			if ((ap = fuword((caddr_t)uap->envp)) != NULL)
334 				uap->envp++, ne++;
335 		}
336 		if (ap == NULL)
337 			break;
338 		na++;
339 		if (ap == -1) {
340 			error = EFAULT;
341 			goto bad;
342 		}
343 		do {
344 			if (nc >= NCARGS-1) {
345 				error = E2BIG;
346 				break;
347 			}
348 			if (sharg) {
349 				error = copystr(sharg, cp, (unsigned)cc, &len);
350 				sharg += len;
351 			} else {
352 				error = copyinstr((caddr_t)ap, cp, (unsigned)cc,
353 				    &len);
354 				ap += len;
355 			}
356 			cp += len;
357 			nc += len;
358 			cc -= len;
359 		} while (error == ENAMETOOLONG);
360 		if (error)
361 			goto bad;
362 	}
363 
364 	/*
365 	 * XXX the following is excessively bogus
366 	 *
367 	 * Compute initial process stack size and location of argc
368 	 * and character strings.  `nc' is currently just the number
369 	 * of characters of arg and env strings.
370 	 *
371 	 * nc = size of signal code + 4 bytes of NULL pointer + nc,
372 	 *	rounded to nearest integer;
373 	 * ucp = USRSTACK - nc;		[user characters pointer]
374 	 * apsize = padding (if any) +
375 	 *	4 bytes of NULL pointer +
376 	 *	ne 4-byte pointers to env strings +
377 	 *	4 bytes of NULL pointer +
378 	 *	(na-ne) 4-byte pointers to arg strings +
379 	 *	4 bytes of argc;
380 	 * (this is the same as nc + (na+3)*4)
381 	 * ap = ucp - apsize;	[user address of argc]
382 	 * ssize = ssize + nc + machine-dependent space;
383 	 */
384 	nc = (szsigcode + 4 + nc + NBPW-1) & ~(NBPW - 1);
385 #ifdef sparc
386 	ucp = USRSTACK;
387 	ssize = (nc + (na + 3) * NBPW + 7) & ~7;
388 	ap = ucp - ssize;
389 	ucp -= nc;
390 	ssize += sizeof(struct rwindow);
391 #else
392 	ssize = (na + 3) * NBPW;
393 	ucp = USRSTACK - nc;
394 	ap = ucp - ssize;
395 	ssize += nc;
396 #endif
397 	error = getxfile(p, vp, &exdata.ex_exec, paged, ssize, uid, gid);
398 	if (error)
399 		goto bad;
400 	vput(vp);
401 	vp = NULL;
402 
403 #ifdef HPUXCOMPAT
404 	/*
405 	 * We are now committed to the exec so we can save the exec
406 	 * header in the pcb where we can dump it if necessary in core()
407 	 */
408 	if (p->p_addr->u_pcb.pcb_flags & PCB_HPUXBIN)
409 		bcopy((caddr_t)&hhead,
410 		      (caddr_t)p->p_addr->u_pcb.pcb_exec, sizeof hhead);
411 #endif
412 
413 	/*
414 	 * Copy back arglist.
415 	 */
416 	cpu_setstack(p, ap);
417 	(void) suword((caddr_t)ap, na-ne);
418 	nc = 0;
419 	cp = (char *) execargs;
420 	cc = NCARGS;
421 	for (;;) {
422 		ap += NBPW;
423 		if (na == ne) {
424 			(void) suword((caddr_t)ap, 0);
425 			ap += NBPW;
426 		}
427 		if (--na < 0)
428 			break;
429 		(void) suword((caddr_t)ap, ucp);
430 		do {
431 			error = copyoutstr(cp, (caddr_t)ucp, (unsigned)cc,
432 			    &len);
433 			ucp += len;
434 			cp += len;
435 			nc += len;
436 			cc -= len;
437 		} while (error == ENAMETOOLONG);
438 		if (error == EFAULT)
439 			panic("exec: EFAULT");
440 	}
441 	(void) suword((caddr_t)ap, 0);
442 
443 	execsigs(p);
444 
445 	for (nc = fdp->fd_lastfile; nc >= 0; --nc) {
446 		if (fdp->fd_ofileflags[nc] & UF_EXCLOSE) {
447 			(void) closef(fdp->fd_ofiles[nc], p);
448 			fdp->fd_ofiles[nc] = NULL;
449 			fdp->fd_ofileflags[nc] = 0;
450 			if (nc < fdp->fd_freefile)
451 				fdp->fd_freefile = nc;
452 		}
453 		fdp->fd_ofileflags[nc] &= ~UF_MAPPED;
454 	}
455 	/*
456 	 * Adjust fd_lastfile to account for descriptors closed above.
457 	 * Don't decrement fd_lastfile past 0, as it's unsigned.
458 	 */
459 	while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
460 		fdp->fd_lastfile--;
461 	setregs(p, exdata.ex_exec.a_entry, retval);
462 #ifdef COPY_SIGCODE
463 	/*
464 	 * Install sigcode at top of user stack.
465 	 */
466 	copyout((caddr_t)sigcode, (caddr_t)(USRSTACK - szsigcode), szsigcode);
467 #endif
468 	/*
469 	 * Remember file name for accounting.
470 	 */
471 	p->p_acflag &= ~AFORK;
472 	if (nd.ni_cnd.cn_namelen > MAXCOMLEN)
473 		nd.ni_cnd.cn_namelen = MAXCOMLEN;
474 	bcopy((caddr_t)nd.ni_cnd.cn_nameptr, (caddr_t)p->p_comm,
475 	    (unsigned)nd.ni_cnd.cn_namelen);
476 	p->p_comm[nd.ni_cnd.cn_namelen] = '\0';
477 	cpu_exec(p);
478 bad:
479 	FREE(nd.ni_cnd.cn_pnbuf, M_NAMEI);
480 	if (execargs)
481 		kmem_free_wakeup(exec_map, execargs, NCARGS);
482 	if (vp)
483 		vput(vp);
484 	return (error);
485 }
486 
487 /*
488  * Read in and set up memory for executed file.
489  */
490 getxfile(p, vp, ep, paged, ssize, uid, gid)
491 	register struct proc *p;
492 	register struct vnode *vp;
493 	register struct exec *ep;
494 	int paged, ssize, uid, gid;
495 {
496 	register struct ucred *cred = p->p_ucred;
497 	register struct vmspace *vm = p->p_vmspace;
498 	vm_offset_t addr;
499 	vm_size_t xts, size;
500 	segsz_t ds;
501 	off_t toff;
502 	int error = 0;
503 
504 #ifdef HPUXCOMPAT
505 	int hpux = (paged & SHPUX);
506 	paged &= ~SHPUX;
507 	if (ep->a_mid == MID_HPUX) {
508 		if (paged)
509 			toff = CLBYTES;
510 		else
511 			toff = sizeof (struct hpux_exec);
512 	} else
513 #endif
514 #ifdef COFF
515 	toff = N_TXTOFF(*ep);
516 #else
517 #ifdef sparc
518 	if (ep->a_mid == MID_SUN_SPARC)
519 		toff = paged ? 0 : sizeof(struct exec);
520 	else
521 #endif
522 	if (paged)
523 		toff = CLBYTES;
524 	else
525 		toff = sizeof (struct exec);
526 #endif
527 	if (ep->a_text != 0 && (vp->v_flag & VTEXT) == 0 &&
528 	    vp->v_writecount != 0)
529 		return (ETXTBSY);
530 
531 	/*
532 	 * Compute text and data sizes and make sure not too large.
533 	 * Text size is rounded to an ``ld page''; data+bss is left
534 	 * in machine pages.  Check data and bss separately as they
535 	 * may overflow when summed together.  (XXX not done yet)
536 	 */
537 	xts = roundup(ep->a_text, __LDPGSZ);
538 	ds = clrnd(btoc(ep->a_data + ep->a_bss));
539 
540 	/*
541 	 * If we're sharing the address space, allocate a new space
542 	 * and release our reference to the old one.  Otherwise,
543 	 * empty out the existing vmspace.
544 	 */
545 #ifdef sparc
546 	kill_user_windows(p);		/* before addrs go away */
547 #endif
548 	if (vm->vm_refcnt > 1) {
549 		p->p_vmspace = vmspace_alloc(VM_MIN_ADDRESS,
550 		    VM_MAXUSER_ADDRESS, 1);
551 		vmspace_free(vm);
552 		vm = p->p_vmspace;
553 	} else {
554 #ifdef SYSVSHM
555 		if (vm->vm_shm)
556 			shmexit(p);
557 #endif
558 		(void) vm_map_remove(&vm->vm_map, VM_MIN_ADDRESS,
559 		    VM_MAXUSER_ADDRESS);
560 	}
561 	/*
562 	 * If parent is waiting for us to exec or exit,
563 	 * SPPWAIT will be set; clear it and wakeup parent.
564 	 */
565 	if (p->p_flag & SPPWAIT) {
566 		p->p_flag &= ~SPPWAIT;
567 		wakeup((caddr_t) p->p_pptr);
568 	}
569 #ifdef HPUXCOMPAT
570 	p->p_addr->u_pcb.pcb_flags &= ~(PCB_HPUXMMAP|PCB_HPUXBIN);
571 	/* remember that we were loaded from an HPUX format file */
572 	if (ep->a_mid == MID_HPUX)
573 		p->p_addr->u_pcb.pcb_flags |= PCB_HPUXBIN;
574 	if (hpux)
575 		p->p_flag |= SHPUX;
576 	else
577 		p->p_flag &= ~SHPUX;
578 #endif
579 #ifdef ULTRIXCOMPAT
580 	/*
581 	 * Always start out as an ULTRIX process.
582 	 * A system call in crt0.o will change us to BSD system calls later.
583 	 */
584 	p->p_md.md_flags |= MDP_ULTRIX;
585 #endif
586 	p->p_flag |= SEXEC;
587 #ifndef COFF
588 	addr = VM_MIN_ADDRESS;
589 	if (vm_allocate(&vm->vm_map, &addr, xts + ctob(ds), FALSE)) {
590 		uprintf("Cannot allocate text+data space\n");
591 		error = ENOMEM;			/* XXX */
592 		goto badmap;
593 	}
594 	vm->vm_taddr = (caddr_t)VM_MIN_ADDRESS;
595 	vm->vm_daddr = (caddr_t)(VM_MIN_ADDRESS + xts);
596 #else /* COFF */
597 	addr = (vm_offset_t)ep->ex_aout.codeStart;
598 	vm->vm_taddr = (caddr_t)addr;
599 	if (vm_allocate(&vm->vm_map, &addr, xts, FALSE)) {
600 		uprintf("Cannot allocate text space\n");
601 		error = ENOMEM;			/* XXX */
602 		goto badmap;
603 	}
604 	addr = (vm_offset_t)ep->ex_aout.heapStart;
605 	vm->vm_daddr = (caddr_t)addr;
606 	if (vm_allocate(&vm->vm_map, &addr, round_page(ctob(ds)), FALSE)) {
607 		uprintf("Cannot allocate data space\n");
608 		error = ENOMEM;			/* XXX */
609 		goto badmap;
610 	}
611 #endif /* COFF */
612 	size = round_page(MAXSSIZ);		/* XXX */
613 #ifdef	i386
614 	addr = trunc_page(USRSTACK - size) - NBPG;	/* XXX */
615 #else
616 	addr = trunc_page(USRSTACK - size);
617 #endif
618 	if (vm_allocate(&vm->vm_map, &addr, size, FALSE)) {
619 		uprintf("Cannot allocate stack space\n");
620 		error = ENOMEM;			/* XXX */
621 		goto badmap;
622 	}
623 	size -= round_page(p->p_rlimit[RLIMIT_STACK].rlim_cur);
624 	if (vm_map_protect(&vm->vm_map, addr, addr+size, VM_PROT_NONE, FALSE)) {
625 		uprintf("Cannot protect stack space\n");
626 		error = ENOMEM;
627 		goto badmap;
628 	}
629 	vm->vm_maxsaddr = (caddr_t)addr;
630 
631 	if (paged == 0) {
632 		/*
633 		 * Read in data segment.
634 		 */
635 		(void) vn_rdwr(UIO_READ, vp, vm->vm_daddr, (int) ep->a_data,
636 			(off_t)(toff + ep->a_text), UIO_USERSPACE,
637 			(IO_UNIT|IO_NODELOCKED), cred, (int *)0, p);
638 		/*
639 		 * Read in text segment if necessary (0410),
640 		 * and read-protect it.
641 		 */
642 		if (ep->a_text > 0) {
643 			error = vn_rdwr(UIO_READ, vp, vm->vm_taddr,
644 				(int)ep->a_text, toff, UIO_USERSPACE,
645 				(IO_UNIT|IO_NODELOCKED), cred, (int *)0, p);
646 			(void) vm_map_protect(&vm->vm_map, vm->vm_taddr,
647 				vm->vm_taddr + trunc_page(ep->a_text),
648 				VM_PROT_READ|VM_PROT_EXECUTE, FALSE);
649 		}
650 	} else {
651 		/*
652 		 * Allocate a region backed by the exec'ed vnode.
653 		 */
654 #ifndef COFF
655 		addr = VM_MIN_ADDRESS;
656 		size = round_page(xts + ep->a_data);
657 		error = vm_mmap(&vm->vm_map, &addr, size, VM_PROT_ALL,
658 			MAP_FILE|MAP_COPY|MAP_FIXED,
659 			(caddr_t)vp, (vm_offset_t)toff);
660 		(void) vm_map_protect(&vm->vm_map, addr, addr + xts,
661 			VM_PROT_READ|VM_PROT_EXECUTE, FALSE);
662 #else /* COFF */
663 		addr = (vm_offset_t)vm->vm_taddr;
664 		size = xts;
665 		error = vm_mmap(&vm->vm_map, &addr, size,
666 			VM_PROT_READ|VM_PROT_EXECUTE,
667 			MAP_FILE|MAP_COPY|MAP_FIXED,
668 			(caddr_t)vp, (vm_offset_t)toff);
669 		toff += size;
670 		addr = (vm_offset_t)vm->vm_daddr;
671 		size = round_page(ep->a_data);
672 		error = vm_mmap(&vm->vm_map, &addr, size, VM_PROT_ALL,
673 			MAP_FILE|MAP_COPY|MAP_FIXED,
674 			(caddr_t)vp, (vm_offset_t)toff);
675 #endif /* COFF */
676 		vp->v_flag |= VTEXT;
677 	}
678 	if (error) {
679 badmap:
680 		printf("pid %d: VM allocation failure\n", p->p_pid);
681 		uprintf("sorry, pid %d was killed in exec: VM allocation\n",
682 			p->p_pid);
683 		psignal(p, SIGKILL);
684 		p->p_flag |= SKEEP;
685 		return(error);
686 	}
687 
688 	/*
689 	 * set SUID/SGID protections, if no tracing
690 	 */
691 	if ((p->p_flag&STRC)==0) {
692 		if (uid != cred->cr_uid || gid != cred->cr_gid) {
693 			p->p_ucred = cred = crcopy(cred);
694 			/*
695 			 * If process is being ktraced, turn off - unless
696 			 * root set it.
697 			 */
698 			if (p->p_tracep && !(p->p_traceflag & KTRFAC_ROOT)) {
699 				vrele(p->p_tracep);
700 				p->p_tracep = NULL;
701 				p->p_traceflag = 0;
702 			}
703 			cred->cr_uid = uid;
704 			cred->cr_gid = gid;
705 		}
706 	} else
707 		psignal(p, SIGTRAP);
708 	p->p_cred->p_svuid = cred->cr_uid;
709 	p->p_cred->p_svgid = cred->cr_gid;
710 	vm->vm_tsize = btoc(xts);
711 	vm->vm_dsize = ds;
712 	vm->vm_ssize = ssize;
713 	p->p_stats->p_prof.pr_scale = 0;
714 #if defined(tahoe)
715 	/* move this when tahoe cpu_exec is created */
716 	p->p_addr->u_pcb.pcb_savacc.faddr = (float *)NULL;
717 #endif
718 	return (0);
719 }
720