1 /* 2 * Copyright (c) 1993, David Greenman 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: src/sys/kern/kern_exec.c,v 1.107.2.15 2002/07/30 15:40:46 nectar Exp $ 27 */ 28 29 #include <sys/param.h> 30 #include <sys/systm.h> 31 #include <sys/sysproto.h> 32 #include <sys/kernel.h> 33 #include <sys/mount.h> 34 #include <sys/filedesc.h> 35 #include <sys/fcntl.h> 36 #include <sys/acct.h> 37 #include <sys/exec.h> 38 #include <sys/imgact.h> 39 #include <sys/imgact_elf.h> 40 #include <sys/wait.h> 41 #include <sys/malloc.h> 42 #include <sys/proc.h> 43 #include <sys/signalvar.h> 44 #include <sys/pioctl.h> 45 #include <sys/namei.h> 46 #include <sys/sysent.h> 47 #include <sys/shm.h> 48 #include <sys/sysctl.h> 49 #include <sys/vnode.h> 50 #include <sys/aio.h> 51 52 #include <vm/vm.h> 53 #include <vm/vm_param.h> 54 #include <sys/lock.h> 55 #include <vm/pmap.h> 56 #include <vm/vm_page.h> 57 #include <vm/vm_map.h> 58 #include <vm/vm_kern.h> 59 #include <vm/vm_extern.h> 60 #include <vm/vm_object.h> 61 #include <vm/vm_pager.h> 62 63 #include <sys/user.h> 64 #include <machine/reg.h> 65 66 MALLOC_DEFINE(M_PARGS, "proc-args", "Process arguments"); 67 68 static register_t *exec_copyout_strings __P((struct image_params *)); 69 70 /* XXX This should be vm_size_t. */ 71 static u_long ps_strings = PS_STRINGS; 72 SYSCTL_ULONG(_kern, KERN_PS_STRINGS, ps_strings, CTLFLAG_RD, &ps_strings, 0, ""); 73 74 /* XXX This should be vm_size_t. */ 75 static u_long usrstack = USRSTACK; 76 SYSCTL_ULONG(_kern, KERN_USRSTACK, usrstack, CTLFLAG_RD, &usrstack, 0, ""); 77 78 u_long ps_arg_cache_limit = PAGE_SIZE / 16; 79 SYSCTL_LONG(_kern, OID_AUTO, ps_arg_cache_limit, CTLFLAG_RW, 80 &ps_arg_cache_limit, 0, ""); 81 82 int ps_argsopen = 1; 83 SYSCTL_INT(_kern, OID_AUTO, ps_argsopen, CTLFLAG_RW, &ps_argsopen, 0, ""); 84 85 /* 86 * Each of the items is a pointer to a `const struct execsw', hence the 87 * double pointer here. 88 */ 89 static const struct execsw **execsw; 90 91 #ifndef _SYS_SYSPROTO_H_ 92 struct execve_args { 93 char *fname; 94 char **argv; 95 char **envv; 96 }; 97 #endif 98 99 /* 100 * execve() system call. 101 */ 102 int 103 execve(p, uap) 104 struct proc *p; 105 register struct execve_args *uap; 106 { 107 struct nameidata nd, *ndp; 108 register_t *stack_base; 109 int error, len, i; 110 struct image_params image_params, *imgp; 111 struct vattr attr; 112 int (*img_first) __P((struct image_params *)); 113 114 imgp = &image_params; 115 116 /* 117 * Lock the process and set the P_INEXEC flag to indicate that 118 * it should be left alone until we're done here. This is 119 * necessary to avoid race conditions - e.g. in ptrace() - 120 * that might allow a local user to illicitly obtain elevated 121 * privileges. 122 */ 123 p->p_flag |= P_INEXEC; 124 125 /* 126 * Initialize part of the common data 127 */ 128 imgp->proc = p; 129 imgp->uap = uap; 130 imgp->attr = &attr; 131 imgp->argc = imgp->envc = 0; 132 imgp->argv0 = NULL; 133 imgp->entry_addr = 0; 134 imgp->vmspace_destroyed = 0; 135 imgp->interpreted = 0; 136 imgp->interpreter_name[0] = '\0'; 137 imgp->auxargs = NULL; 138 imgp->vp = NULL; 139 imgp->firstpage = NULL; 140 imgp->ps_strings = 0; 141 142 /* 143 * Allocate temporary demand zeroed space for argument and 144 * environment strings 145 */ 146 imgp->stringbase = (char *)kmem_alloc_wait(exec_map, ARG_MAX + PAGE_SIZE); 147 if (imgp->stringbase == NULL) { 148 error = ENOMEM; 149 goto exec_fail; 150 } 151 imgp->stringp = imgp->stringbase; 152 imgp->stringspace = ARG_MAX; 153 imgp->image_header = imgp->stringbase + ARG_MAX; 154 155 /* 156 * Translate the file name. namei() returns a vnode pointer 157 * in ni_vp amoung other things. 158 */ 159 ndp = &nd; 160 NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME, 161 UIO_USERSPACE, uap->fname, p); 162 163 interpret: 164 165 error = namei(ndp); 166 if (error) { 167 kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase, 168 ARG_MAX + PAGE_SIZE); 169 goto exec_fail; 170 } 171 172 imgp->vp = ndp->ni_vp; 173 imgp->fname = uap->fname; 174 175 /* 176 * Check file permissions (also 'opens' file) 177 */ 178 error = exec_check_permissions(imgp); 179 if (error) { 180 VOP_UNLOCK(imgp->vp, 0, p); 181 goto exec_fail_dealloc; 182 } 183 184 error = exec_map_first_page(imgp); 185 VOP_UNLOCK(imgp->vp, 0, p); 186 if (error) 187 goto exec_fail_dealloc; 188 189 /* 190 * If the current process has a special image activator it 191 * wants to try first, call it. For example, emulating shell 192 * scripts differently. 193 */ 194 error = -1; 195 if ((img_first = imgp->proc->p_sysent->sv_imgact_try) != NULL) 196 error = img_first(imgp); 197 198 /* 199 * Loop through the list of image activators, calling each one. 200 * An activator returns -1 if there is no match, 0 on success, 201 * and an error otherwise. 202 */ 203 for (i = 0; error == -1 && execsw[i]; ++i) { 204 if (execsw[i]->ex_imgact == NULL || 205 execsw[i]->ex_imgact == img_first) { 206 continue; 207 } 208 error = (*execsw[i]->ex_imgact)(imgp); 209 } 210 211 if (error) { 212 if (error == -1) 213 error = ENOEXEC; 214 goto exec_fail_dealloc; 215 } 216 217 /* 218 * Special interpreter operation, cleanup and loop up to try to 219 * activate the interpreter. 220 */ 221 if (imgp->interpreted) { 222 exec_unmap_first_page(imgp); 223 /* free name buffer and old vnode */ 224 NDFREE(ndp, NDF_ONLY_PNBUF); 225 vrele(ndp->ni_vp); 226 /* set new name to that of the interpreter */ 227 NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME, 228 UIO_SYSSPACE, imgp->interpreter_name, p); 229 goto interpret; 230 } 231 232 /* 233 * Copy out strings (args and env) and initialize stack base 234 */ 235 stack_base = exec_copyout_strings(imgp); 236 p->p_vmspace->vm_minsaddr = (char *)stack_base; 237 238 /* 239 * If custom stack fixup routine present for this process 240 * let it do the stack setup. 241 * Else stuff argument count as first item on stack 242 */ 243 if (p->p_sysent->sv_fixup) 244 (*p->p_sysent->sv_fixup)(&stack_base, imgp); 245 else 246 suword(--stack_base, imgp->argc); 247 248 /* 249 * For security and other reasons, the file descriptor table cannot 250 * be shared after an exec. 251 */ 252 if (p->p_fd->fd_refcnt > 1) { 253 struct filedesc *tmp; 254 255 tmp = fdcopy(p); 256 fdfree(p); 257 p->p_fd = tmp; 258 } 259 260 /* 261 * For security and other reasons, signal handlers cannot 262 * be shared after an exec. The new proces gets a copy of the old 263 * handlers. In execsigs(), the new process will have its signals 264 * reset. 265 */ 266 if (p->p_procsig->ps_refcnt > 1) { 267 struct procsig *newprocsig; 268 269 MALLOC(newprocsig, struct procsig *, sizeof(struct procsig), 270 M_SUBPROC, M_WAITOK); 271 bcopy(p->p_procsig, newprocsig, sizeof(*newprocsig)); 272 p->p_procsig->ps_refcnt--; 273 p->p_procsig = newprocsig; 274 p->p_procsig->ps_refcnt = 1; 275 if (p->p_sigacts == &p->p_addr->u_sigacts) 276 panic("shared procsig but private sigacts?"); 277 278 p->p_addr->u_sigacts = *p->p_sigacts; 279 p->p_sigacts = &p->p_addr->u_sigacts; 280 } 281 282 /* Stop profiling */ 283 stopprofclock(p); 284 285 /* close files on exec */ 286 fdcloseexec(p); 287 288 /* reset caught signals */ 289 execsigs(p); 290 291 /* name this process - nameiexec(p, ndp) */ 292 len = min(ndp->ni_cnd.cn_namelen,MAXCOMLEN); 293 bcopy(ndp->ni_cnd.cn_nameptr, p->p_comm, len); 294 p->p_comm[len] = 0; 295 296 /* 297 * mark as execed, wakeup the process that vforked (if any) and tell 298 * it that it now has its own resources back 299 */ 300 p->p_flag |= P_EXEC; 301 if (p->p_pptr && (p->p_flag & P_PPWAIT)) { 302 p->p_flag &= ~P_PPWAIT; 303 wakeup((caddr_t)p->p_pptr); 304 } 305 306 /* 307 * Implement image setuid/setgid. 308 * 309 * Don't honor setuid/setgid if the filesystem prohibits it or if 310 * the process is being traced. 311 */ 312 if ((((attr.va_mode & VSUID) && p->p_ucred->cr_uid != attr.va_uid) || 313 ((attr.va_mode & VSGID) && p->p_ucred->cr_gid != attr.va_gid)) && 314 (imgp->vp->v_mount->mnt_flag & MNT_NOSUID) == 0 && 315 (p->p_flag & P_TRACED) == 0) { 316 /* 317 * Turn off syscall tracing for set-id programs, except for 318 * root. Record any set-id flags first to make sure that 319 * we do not regain any tracing during a possible block. 320 */ 321 setsugid(p); 322 if (p->p_tracep && suser(p)) { 323 struct vnode *vtmp; 324 325 if ((vtmp = p->p_tracep) != NULL) { 326 p->p_tracep = NULL; 327 p->p_traceflag = 0; 328 vrele(vtmp); 329 } 330 } 331 /* Close any file descriptors 0..2 that reference procfs */ 332 setugidsafety(p); 333 /* Make sure file descriptors 0..2 are in use. */ 334 error = fdcheckstd(p); 335 if (error != 0) 336 goto exec_fail_dealloc; 337 /* 338 * Set the new credentials. 339 */ 340 p->p_ucred = crcopy(p->p_ucred); 341 if (attr.va_mode & VSUID) 342 change_euid(p, attr.va_uid); 343 if (attr.va_mode & VSGID) 344 p->p_ucred->cr_gid = attr.va_gid; 345 } else { 346 if (p->p_ucred->cr_uid == p->p_cred->p_ruid && 347 p->p_ucred->cr_gid == p->p_cred->p_rgid) 348 p->p_flag &= ~P_SUGID; 349 } 350 351 /* 352 * Implement correct POSIX saved-id behavior. 353 */ 354 p->p_cred->p_svuid = p->p_ucred->cr_uid; 355 p->p_cred->p_svgid = p->p_ucred->cr_gid; 356 357 /* 358 * Store the vp for use in procfs 359 */ 360 if (p->p_textvp) /* release old reference */ 361 vrele(p->p_textvp); 362 VREF(ndp->ni_vp); 363 p->p_textvp = ndp->ni_vp; 364 365 /* 366 * Notify others that we exec'd, and clear the P_INEXEC flag 367 * as we're now a bona fide freshly-execed process. 368 */ 369 KNOTE(&p->p_klist, NOTE_EXEC); 370 p->p_flag &= ~P_INEXEC; 371 372 /* 373 * If tracing the process, trap to debugger so breakpoints 374 * can be set before the program executes. 375 */ 376 STOPEVENT(p, S_EXEC, 0); 377 378 if (p->p_flag & P_TRACED) 379 psignal(p, SIGTRAP); 380 381 /* clear "fork but no exec" flag, as we _are_ execing */ 382 p->p_acflag &= ~AFORK; 383 384 /* Set values passed into the program in registers. */ 385 setregs(p, imgp->entry_addr, (u_long)(uintptr_t)stack_base, 386 imgp->ps_strings); 387 388 /* Free any previous argument cache */ 389 if (p->p_args && --p->p_args->ar_ref == 0) 390 FREE(p->p_args, M_PARGS); 391 p->p_args = NULL; 392 393 /* Cache arguments if they fit inside our allowance */ 394 i = imgp->endargs - imgp->stringbase; 395 if (ps_arg_cache_limit >= i + sizeof(struct pargs)) { 396 MALLOC(p->p_args, struct pargs *, sizeof(struct pargs) + i, 397 M_PARGS, M_WAITOK); 398 p->p_args->ar_ref = 1; 399 p->p_args->ar_length = i; 400 bcopy(imgp->stringbase, p->p_args->ar_args, i); 401 } 402 403 exec_fail_dealloc: 404 405 /* 406 * free various allocated resources 407 */ 408 if (imgp->firstpage) 409 exec_unmap_first_page(imgp); 410 411 if (imgp->stringbase != NULL) 412 kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase, 413 ARG_MAX + PAGE_SIZE); 414 415 if (imgp->vp) { 416 NDFREE(ndp, NDF_ONLY_PNBUF); 417 vrele(imgp->vp); 418 } 419 420 if (error == 0) 421 return (0); 422 423 exec_fail: 424 /* we're done here, clear P_INEXEC */ 425 p->p_flag &= ~P_INEXEC; 426 if (imgp->vmspace_destroyed) { 427 /* sorry, no more process anymore. exit gracefully */ 428 exit1(p, W_EXITCODE(0, SIGABRT)); 429 /* NOT REACHED */ 430 return(0); 431 } else { 432 return(error); 433 } 434 } 435 436 int 437 exec_map_first_page(imgp) 438 struct image_params *imgp; 439 { 440 int s, rv, i; 441 int initial_pagein; 442 vm_page_t ma[VM_INITIAL_PAGEIN]; 443 vm_object_t object; 444 445 446 if (imgp->firstpage) { 447 exec_unmap_first_page(imgp); 448 } 449 450 VOP_GETVOBJECT(imgp->vp, &object); 451 s = splvm(); 452 453 ma[0] = vm_page_grab(object, 0, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); 454 455 if ((ma[0]->valid & VM_PAGE_BITS_ALL) != VM_PAGE_BITS_ALL) { 456 initial_pagein = VM_INITIAL_PAGEIN; 457 if (initial_pagein > object->size) 458 initial_pagein = object->size; 459 for (i = 1; i < initial_pagein; i++) { 460 if ((ma[i] = vm_page_lookup(object, i)) != NULL) { 461 if ((ma[i]->flags & PG_BUSY) || ma[i]->busy) 462 break; 463 if (ma[i]->valid) 464 break; 465 vm_page_busy(ma[i]); 466 } else { 467 ma[i] = vm_page_alloc(object, i, VM_ALLOC_NORMAL); 468 if (ma[i] == NULL) 469 break; 470 } 471 } 472 initial_pagein = i; 473 474 rv = vm_pager_get_pages(object, ma, initial_pagein, 0); 475 ma[0] = vm_page_lookup(object, 0); 476 477 if ((rv != VM_PAGER_OK) || (ma[0] == NULL) || (ma[0]->valid == 0)) { 478 if (ma[0]) { 479 vm_page_protect(ma[0], VM_PROT_NONE); 480 vm_page_free(ma[0]); 481 } 482 splx(s); 483 return EIO; 484 } 485 } 486 487 vm_page_wire(ma[0]); 488 vm_page_wakeup(ma[0]); 489 splx(s); 490 491 pmap_kenter((vm_offset_t) imgp->image_header, VM_PAGE_TO_PHYS(ma[0])); 492 imgp->firstpage = ma[0]; 493 494 return 0; 495 } 496 497 void 498 exec_unmap_first_page(imgp) 499 struct image_params *imgp; 500 { 501 if (imgp->firstpage) { 502 pmap_kremove((vm_offset_t) imgp->image_header); 503 vm_page_unwire(imgp->firstpage, 1); 504 imgp->firstpage = NULL; 505 } 506 } 507 508 /* 509 * Destroy old address space, and allocate a new stack 510 * The new stack is only SGROWSIZ large because it is grown 511 * automatically in trap.c. 512 */ 513 int 514 exec_new_vmspace(imgp) 515 struct image_params *imgp; 516 { 517 int error; 518 struct vmspace *vmspace = imgp->proc->p_vmspace; 519 vm_offset_t stack_addr = USRSTACK - maxssiz; 520 vm_map_t map = &vmspace->vm_map; 521 522 imgp->vmspace_destroyed = 1; 523 524 /* 525 * Prevent a pending AIO from modifying the new address space. 526 */ 527 aio_proc_rundown(imgp->proc); 528 529 /* 530 * Blow away entire process VM, if address space not shared, 531 * otherwise, create a new VM space so that other threads are 532 * not disrupted 533 */ 534 if (vmspace->vm_refcnt == 1) { 535 if (vmspace->vm_shm) 536 shmexit(imgp->proc); 537 pmap_remove_pages(vmspace_pmap(vmspace), 0, VM_MAXUSER_ADDRESS); 538 vm_map_remove(map, 0, VM_MAXUSER_ADDRESS); 539 } else { 540 vmspace_exec(imgp->proc); 541 vmspace = imgp->proc->p_vmspace; 542 map = &vmspace->vm_map; 543 } 544 545 /* Allocate a new stack */ 546 error = vm_map_stack(&vmspace->vm_map, stack_addr, (vm_size_t)maxssiz, 547 VM_PROT_ALL, VM_PROT_ALL, 0); 548 if (error) 549 return (error); 550 551 /* vm_ssize and vm_maxsaddr are somewhat antiquated concepts in the 552 * VM_STACK case, but they are still used to monitor the size of the 553 * process stack so we can check the stack rlimit. 554 */ 555 vmspace->vm_ssize = sgrowsiz >> PAGE_SHIFT; 556 vmspace->vm_maxsaddr = (char *)USRSTACK - maxssiz; 557 558 return(0); 559 } 560 561 /* 562 * Copy out argument and environment strings from the old process 563 * address space into the temporary string buffer. 564 */ 565 int 566 exec_extract_strings(imgp) 567 struct image_params *imgp; 568 { 569 char **argv, **envv; 570 char *argp, *envp; 571 int error; 572 size_t length; 573 574 /* 575 * extract arguments first 576 */ 577 578 argv = imgp->uap->argv; 579 580 if (argv) { 581 argp = (caddr_t) (intptr_t) fuword(argv); 582 if (argp == (caddr_t) -1) 583 return (EFAULT); 584 if (argp) 585 argv++; 586 if (imgp->argv0) 587 argp = imgp->argv0; 588 if (argp) { 589 do { 590 if (argp == (caddr_t) -1) 591 return (EFAULT); 592 if ((error = copyinstr(argp, imgp->stringp, 593 imgp->stringspace, &length))) { 594 if (error == ENAMETOOLONG) 595 return(E2BIG); 596 return (error); 597 } 598 imgp->stringspace -= length; 599 imgp->stringp += length; 600 imgp->argc++; 601 } while ((argp = (caddr_t) (intptr_t) fuword(argv++))); 602 } 603 } 604 605 imgp->endargs = imgp->stringp; 606 607 /* 608 * extract environment strings 609 */ 610 611 envv = imgp->uap->envv; 612 613 if (envv) { 614 while ((envp = (caddr_t) (intptr_t) fuword(envv++))) { 615 if (envp == (caddr_t) -1) 616 return (EFAULT); 617 if ((error = copyinstr(envp, imgp->stringp, 618 imgp->stringspace, &length))) { 619 if (error == ENAMETOOLONG) 620 return(E2BIG); 621 return (error); 622 } 623 imgp->stringspace -= length; 624 imgp->stringp += length; 625 imgp->envc++; 626 } 627 } 628 629 return (0); 630 } 631 632 /* 633 * Copy strings out to the new process address space, constructing 634 * new arg and env vector tables. Return a pointer to the base 635 * so that it can be used as the initial stack pointer. 636 */ 637 register_t * 638 exec_copyout_strings(imgp) 639 struct image_params *imgp; 640 { 641 int argc, envc; 642 char **vectp; 643 char *stringp, *destp; 644 register_t *stack_base; 645 struct ps_strings *arginfo; 646 int szsigcode; 647 648 /* 649 * Calculate string base and vector table pointers. 650 * Also deal with signal trampoline code for this exec type. 651 */ 652 arginfo = (struct ps_strings *)PS_STRINGS; 653 szsigcode = *(imgp->proc->p_sysent->sv_szsigcode); 654 destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE - 655 roundup((ARG_MAX - imgp->stringspace), sizeof(char *)); 656 657 /* 658 * install sigcode 659 */ 660 if (szsigcode) 661 copyout(imgp->proc->p_sysent->sv_sigcode, 662 ((caddr_t)arginfo - szsigcode), szsigcode); 663 664 /* 665 * If we have a valid auxargs ptr, prepare some room 666 * on the stack. 667 */ 668 if (imgp->auxargs) 669 /* 670 * The '+ 2' is for the null pointers at the end of each of the 671 * arg and env vector sets, and 'AT_COUNT*2' is room for the 672 * ELF Auxargs data. 673 */ 674 vectp = (char **)(destp - (imgp->argc + imgp->envc + 2 + 675 AT_COUNT*2) * sizeof(char*)); 676 else 677 /* 678 * The '+ 2' is for the null pointers at the end of each of the 679 * arg and env vector sets 680 */ 681 vectp = (char **) 682 (destp - (imgp->argc + imgp->envc + 2) * sizeof(char*)); 683 684 /* 685 * vectp also becomes our initial stack base 686 */ 687 stack_base = (register_t *)vectp; 688 689 stringp = imgp->stringbase; 690 argc = imgp->argc; 691 envc = imgp->envc; 692 693 /* 694 * Copy out strings - arguments and environment. 695 */ 696 copyout(stringp, destp, ARG_MAX - imgp->stringspace); 697 698 /* 699 * Fill in "ps_strings" struct for ps, w, etc. 700 */ 701 suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp); 702 suword(&arginfo->ps_nargvstr, argc); 703 704 /* 705 * Fill in argument portion of vector table. 706 */ 707 for (; argc > 0; --argc) { 708 suword(vectp++, (long)(intptr_t)destp); 709 while (*stringp++ != 0) 710 destp++; 711 destp++; 712 } 713 714 /* a null vector table pointer seperates the argp's from the envp's */ 715 suword(vectp++, 0); 716 717 suword(&arginfo->ps_envstr, (long)(intptr_t)vectp); 718 suword(&arginfo->ps_nenvstr, envc); 719 720 /* 721 * Fill in environment portion of vector table. 722 */ 723 for (; envc > 0; --envc) { 724 suword(vectp++, (long)(intptr_t)destp); 725 while (*stringp++ != 0) 726 destp++; 727 destp++; 728 } 729 730 /* end of vector table is a null pointer */ 731 suword(vectp, 0); 732 733 return (stack_base); 734 } 735 736 /* 737 * Check permissions of file to execute. 738 * Return 0 for success or error code on failure. 739 */ 740 int 741 exec_check_permissions(imgp) 742 struct image_params *imgp; 743 { 744 struct proc *p = imgp->proc; 745 struct vnode *vp = imgp->vp; 746 struct vattr *attr = imgp->attr; 747 int error; 748 749 /* Get file attributes */ 750 error = VOP_GETATTR(vp, attr, p->p_ucred, p); 751 if (error) 752 return (error); 753 754 /* 755 * 1) Check if file execution is disabled for the filesystem that this 756 * file resides on. 757 * 2) Insure that at least one execute bit is on - otherwise root 758 * will always succeed, and we don't want to happen unless the 759 * file really is executable. 760 * 3) Insure that the file is a regular file. 761 */ 762 if ((vp->v_mount->mnt_flag & MNT_NOEXEC) || 763 ((attr->va_mode & 0111) == 0) || 764 (attr->va_type != VREG)) { 765 return (EACCES); 766 } 767 768 /* 769 * Zero length files can't be exec'd 770 */ 771 if (attr->va_size == 0) 772 return (ENOEXEC); 773 774 /* 775 * Check for execute permission to file based on current credentials. 776 */ 777 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p); 778 if (error) 779 return (error); 780 781 /* 782 * Check number of open-for-writes on the file and deny execution 783 * if there are any. 784 */ 785 if (vp->v_writecount) 786 return (ETXTBSY); 787 788 /* 789 * Call filesystem specific open routine (which does nothing in the 790 * general case). 791 */ 792 error = VOP_OPEN(vp, FREAD, p->p_ucred, p); 793 if (error) 794 return (error); 795 796 return (0); 797 } 798 799 /* 800 * Exec handler registration 801 */ 802 int 803 exec_register(execsw_arg) 804 const struct execsw *execsw_arg; 805 { 806 const struct execsw **es, **xs, **newexecsw; 807 int count = 2; /* New slot and trailing NULL */ 808 809 if (execsw) 810 for (es = execsw; *es; es++) 811 count++; 812 newexecsw = malloc(count * sizeof(*es), M_TEMP, M_WAITOK); 813 if (newexecsw == NULL) 814 return ENOMEM; 815 xs = newexecsw; 816 if (execsw) 817 for (es = execsw; *es; es++) 818 *xs++ = *es; 819 *xs++ = execsw_arg; 820 *xs = NULL; 821 if (execsw) 822 free(execsw, M_TEMP); 823 execsw = newexecsw; 824 return 0; 825 } 826 827 int 828 exec_unregister(execsw_arg) 829 const struct execsw *execsw_arg; 830 { 831 const struct execsw **es, **xs, **newexecsw; 832 int count = 1; 833 834 if (execsw == NULL) 835 panic("unregister with no handlers left?\n"); 836 837 for (es = execsw; *es; es++) { 838 if (*es == execsw_arg) 839 break; 840 } 841 if (*es == NULL) 842 return ENOENT; 843 for (es = execsw; *es; es++) 844 if (*es != execsw_arg) 845 count++; 846 newexecsw = malloc(count * sizeof(*es), M_TEMP, M_WAITOK); 847 if (newexecsw == NULL) 848 return ENOMEM; 849 xs = newexecsw; 850 for (es = execsw; *es; es++) 851 if (*es != execsw_arg) 852 *xs++ = *es; 853 *xs = NULL; 854 if (execsw) 855 free(execsw, M_TEMP); 856 execsw = newexecsw; 857 return 0; 858 } 859