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