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