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