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