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