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