LCOV - code coverage report
Current view: top level - kern - kern_exec.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 366 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: kern_exec.c,v 1.201 2018/08/05 14:23:57 beck Exp $    */
       2             : /*      $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $  */
       3             : 
       4             : /*-
       5             :  * Copyright (C) 1993, 1994 Christopher G. Demetriou
       6             :  * Copyright (C) 1992 Wolfgang Solfrank.
       7             :  * Copyright (C) 1992 TooLs GmbH.
       8             :  * All rights reserved.
       9             :  *
      10             :  * Redistribution and use in source and binary forms, with or without
      11             :  * modification, are permitted provided that the following conditions
      12             :  * are met:
      13             :  * 1. Redistributions of source code must retain the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer.
      15             :  * 2. Redistributions in binary form must reproduce the above copyright
      16             :  *    notice, this list of conditions and the following disclaimer in the
      17             :  *    documentation and/or other materials provided with the distribution.
      18             :  * 3. All advertising materials mentioning features or use of this software
      19             :  *    must display the following acknowledgement:
      20             :  *      This product includes software developed by TooLs GmbH.
      21             :  * 4. The name of TooLs GmbH may not be used to endorse or promote products
      22             :  *    derived from this software without specific prior written permission.
      23             :  *
      24             :  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
      25             :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      26             :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      27             :  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      28             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
      29             :  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
      30             :  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
      31             :  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      32             :  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
      33             :  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      34             :  */
      35             : 
      36             : #include <sys/param.h>
      37             : #include <sys/systm.h>
      38             : #include <sys/filedesc.h>
      39             : #include <sys/kernel.h>
      40             : #include <sys/proc.h>
      41             : #include <sys/mount.h>
      42             : #include <sys/malloc.h>
      43             : #include <sys/pool.h>
      44             : #include <sys/namei.h>
      45             : #include <sys/vnode.h>
      46             : #include <sys/fcntl.h>
      47             : #include <sys/file.h>
      48             : #include <sys/acct.h>
      49             : #include <sys/exec.h>
      50             : #include <sys/ktrace.h>
      51             : #include <sys/resourcevar.h>
      52             : #include <sys/wait.h>
      53             : #include <sys/mman.h>
      54             : #include <sys/signalvar.h>
      55             : #include <sys/stat.h>
      56             : #include <sys/conf.h>
      57             : #include <sys/pledge.h>
      58             : #ifdef SYSVSHM
      59             : #include <sys/shm.h>
      60             : #endif
      61             : 
      62             : #include <sys/syscallargs.h>
      63             : 
      64             : #include <uvm/uvm_extern.h>
      65             : #include <machine/tcb.h>
      66             : 
      67             : void    unveil_destroy(struct process *ps);
      68             : 
      69             : const struct kmem_va_mode kv_exec = {
      70             :         .kv_wait = 1,
      71             :         .kv_map = &exec_map
      72             : };
      73             : 
      74             : /*
      75             :  * Map the shared signal code.
      76             :  */
      77             : int exec_sigcode_map(struct process *, struct emul *);
      78             : 
      79             : /*
      80             :  * If non-zero, stackgap_random specifies the upper limit of the random gap size
      81             :  * added to the fixed stack position. Must be n^2.
      82             :  */
      83             : int stackgap_random = STACKGAP_RANDOM;
      84             : 
      85             : /*
      86             :  * check exec:
      87             :  * given an "executable" described in the exec package's namei info,
      88             :  * see what we can do with it.
      89             :  *
      90             :  * ON ENTRY:
      91             :  *      exec package with appropriate namei info
      92             :  *      proc pointer of exec'ing proc
      93             :  *      NO SELF-LOCKED VNODES
      94             :  *
      95             :  * ON EXIT:
      96             :  *      error:  nothing held, etc.  exec header still allocated.
      97             :  *      ok:     filled exec package, one locked vnode.
      98             :  *
      99             :  * EXEC SWITCH ENTRY:
     100             :  *      Locked vnode to check, exec package, proc.
     101             :  *
     102             :  * EXEC SWITCH EXIT:
     103             :  *      ok:     return 0, filled exec package, one locked vnode.
     104             :  *      error:  destructive:
     105             :  *                      everything deallocated except exec header.
     106             :  *              non-destructive:
     107             :  *                      error code, locked vnode, exec header unmodified
     108             :  */
     109             : int
     110           0 : check_exec(struct proc *p, struct exec_package *epp)
     111             : {
     112             :         int error, i;
     113             :         struct vnode *vp;
     114             :         struct nameidata *ndp;
     115           0 :         size_t resid;
     116             : 
     117           0 :         ndp = epp->ep_ndp;
     118           0 :         ndp->ni_cnd.cn_nameiop = LOOKUP;
     119           0 :         ndp->ni_cnd.cn_flags = FOLLOW | LOCKLEAF | SAVENAME;
     120             :         /* first get the vnode */
     121           0 :         if ((error = namei(ndp)) != 0)
     122           0 :                 return (error);
     123           0 :         epp->ep_vp = vp = ndp->ni_vp;
     124             : 
     125             :         /* check for regular file */
     126           0 :         if (vp->v_type == VDIR) {
     127             :                 error = EISDIR;
     128           0 :                 goto bad1;
     129             :         }
     130           0 :         if (vp->v_type != VREG) {
     131             :                 error = EACCES;
     132           0 :                 goto bad1;
     133             :         }
     134             : 
     135             :         /* get attributes */
     136           0 :         if ((error = VOP_GETATTR(vp, epp->ep_vap, p->p_ucred, p)) != 0)
     137             :                 goto bad1;
     138             : 
     139             :         /* Check mount point */
     140           0 :         if (vp->v_mount->mnt_flag & MNT_NOEXEC) {
     141             :                 error = EACCES;
     142           0 :                 goto bad1;
     143             :         }
     144             : 
     145             :         /* SUID programs may not be started with execpromises */
     146           0 :         if ((epp->ep_vap->va_mode & (VSUID | VSGID)) &&
     147           0 :             (p->p_p->ps_flags & PS_EXECPLEDGE)) {
     148             :                 error = EACCES;
     149           0 :                 goto bad1;
     150             :         }
     151             : 
     152           0 :         if ((vp->v_mount->mnt_flag & MNT_NOSUID))
     153           0 :                 epp->ep_vap->va_mode &= ~(VSUID | VSGID);
     154             : 
     155             :         /* check access.  for root we have to see if any exec bit on */
     156           0 :         if ((error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p)) != 0)
     157             :                 goto bad1;
     158           0 :         if ((epp->ep_vap->va_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0) {
     159             :                 error = EACCES;
     160           0 :                 goto bad1;
     161             :         }
     162             : 
     163             :         /* try to open it */
     164           0 :         if ((error = VOP_OPEN(vp, FREAD, p->p_ucred, p)) != 0)
     165             :                 goto bad1;
     166             : 
     167             :         /* unlock vp, we need it unlocked from here */
     168           0 :         VOP_UNLOCK(vp);
     169             : 
     170             :         /* now we have the file, get the exec header */
     171           0 :         error = vn_rdwr(UIO_READ, vp, epp->ep_hdr, epp->ep_hdrlen, 0,
     172           0 :             UIO_SYSSPACE, 0, p->p_ucred, &resid, p);
     173           0 :         if (error)
     174             :                 goto bad2;
     175           0 :         epp->ep_hdrvalid = epp->ep_hdrlen - resid;
     176             : 
     177             :         /*
     178             :          * set up the vmcmds for creation of the process
     179             :          * address space
     180             :          */
     181             :         error = ENOEXEC;
     182           0 :         for (i = 0; i < nexecs && error != 0; i++) {
     183             :                 int newerror;
     184             : 
     185           0 :                 if (execsw[i].es_check == NULL)
     186           0 :                         continue;
     187           0 :                 newerror = (*execsw[i].es_check)(p, epp);
     188             :                 /* make sure the first "interesting" error code is saved. */
     189           0 :                 if (!newerror || error == ENOEXEC)
     190           0 :                         error = newerror;
     191           0 :                 if (epp->ep_flags & EXEC_DESTR && error != 0)
     192           0 :                         return (error);
     193           0 :         }
     194           0 :         if (!error) {
     195             :                 /* check that entry point is sane */
     196           0 :                 if (epp->ep_entry > VM_MAXUSER_ADDRESS) {
     197             :                         error = ENOEXEC;
     198           0 :                 }
     199             : 
     200             :                 /* check limits */
     201           0 :                 if ((epp->ep_tsize > MAXTSIZ) ||
     202           0 :                     (epp->ep_dsize > p->p_rlimit[RLIMIT_DATA].rlim_cur))
     203           0 :                         error = ENOMEM;
     204             : 
     205           0 :                 if (!error)
     206           0 :                         return (0);
     207             :         }
     208             : 
     209             :         /*
     210             :          * free any vmspace-creation commands,
     211             :          * and release their references
     212             :          */
     213           0 :         kill_vmcmds(&epp->ep_vmcmds);
     214             : 
     215             : bad2:
     216             :         /*
     217             :          * close the vnode, free the pathname buf, and punt.
     218             :          */
     219           0 :         vn_close(vp, FREAD, p->p_ucred, p);
     220           0 :         pool_put(&namei_pool, ndp->ni_cnd.cn_pnbuf);
     221           0 :         return (error);
     222             : 
     223             : bad1:
     224             :         /*
     225             :          * free the namei pathname buffer, and put the vnode
     226             :          * (which we don't yet have open).
     227             :          */
     228           0 :         pool_put(&namei_pool, ndp->ni_cnd.cn_pnbuf);
     229           0 :         vput(vp);
     230           0 :         return (error);
     231           0 : }
     232             : 
     233             : /*
     234             :  * exec system call
     235             :  */
     236             : int
     237           0 : sys_execve(struct proc *p, void *v, register_t *retval)
     238             : {
     239             :         struct sys_execve_args /* {
     240             :                 syscallarg(const char *) path;
     241             :                 syscallarg(char *const *) argp;
     242             :                 syscallarg(char *const *) envp;
     243           0 :         } */ *uap = v;
     244             :         int error;
     245           0 :         struct exec_package pack;
     246           0 :         struct nameidata nid;
     247           0 :         struct vattr attr;
     248           0 :         struct ucred *cred = p->p_ucred;
     249             :         char *argp;
     250           0 :         char * const *cpp, *dp, *sp;
     251             : #ifdef KTRACE
     252             :         char *env_start;
     253             : #endif
     254           0 :         struct process *pr = p->p_p;
     255             :         long argc, envc;
     256           0 :         size_t len, sgap, dstsize;
     257             : #ifdef MACHINE_STACK_GROWS_UP
     258             :         size_t slen;
     259             : #endif
     260             :         char *stack;
     261           0 :         struct ps_strings arginfo;
     262             :         struct vmspace *vm;
     263             :         extern struct emul emul_native;
     264             :         struct vnode *otvp;
     265             : 
     266             :         /* get other threads to stop */
     267           0 :         if ((error = single_thread_set(p, SINGLE_UNWIND, 1)))
     268           0 :                 return (error);
     269             : 
     270             :         /*
     271             :          * Cheap solution to complicated problems.
     272             :          * Mark this process as "leave me alone, I'm execing".
     273             :          */
     274           0 :         atomic_setbits_int(&pr->ps_flags, PS_INEXEC);
     275             : 
     276           0 :         NDINIT(&nid, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
     277           0 :         nid.ni_pledge = PLEDGE_EXEC;
     278           0 :         nid.ni_unveil = UNVEIL_EXEC;
     279             : 
     280             :         /*
     281             :          * initialize the fields of the exec package.
     282             :          */
     283           0 :         pack.ep_name = (char *)SCARG(uap, path);
     284           0 :         pack.ep_hdr = malloc(exec_maxhdrsz, M_EXEC, M_WAITOK);
     285           0 :         pack.ep_hdrlen = exec_maxhdrsz;
     286           0 :         pack.ep_hdrvalid = 0;
     287           0 :         pack.ep_ndp = &nid;
     288           0 :         pack.ep_interp = NULL;
     289           0 :         pack.ep_emul_arg = NULL;
     290           0 :         VMCMDSET_INIT(&pack.ep_vmcmds);
     291           0 :         pack.ep_vap = &attr;
     292           0 :         pack.ep_emul = &emul_native;
     293           0 :         pack.ep_flags = 0;
     294             : 
     295             :         /* see if we can run it. */
     296           0 :         if ((error = check_exec(p, &pack)) != 0) {
     297             :                 goto freehdr;
     298             :         }
     299             : 
     300             :         /* XXX -- THE FOLLOWING SECTION NEEDS MAJOR CLEANUP */
     301             : 
     302             :         /* allocate an argument buffer */
     303           0 :         argp = km_alloc(NCARGS, &kv_exec, &kp_pageable, &kd_waitok);
     304             : #ifdef DIAGNOSTIC
     305           0 :         if (argp == NULL)
     306           0 :                 panic("execve: argp == NULL");
     307             : #endif
     308             :         dp = argp;
     309             :         argc = 0;
     310             : 
     311             :         /*
     312             :          * Copy the fake args list, if there's one, freeing it as we go.
     313             :          * exec_script_makecmds() allocates either 2 or 3 fake args bounded
     314             :          * by MAXINTERP + MAXPATHLEN < NCARGS so no overflow can happen.
     315             :          */
     316           0 :         if (pack.ep_flags & EXEC_HASARGL) {
     317             :                 dstsize = NCARGS;
     318           0 :                 for(; pack.ep_fa[argc] != NULL; argc++) {
     319           0 :                         len = strlcpy(dp, pack.ep_fa[argc], dstsize);
     320           0 :                         len++;
     321           0 :                         dp += len; dstsize -= len;
     322           0 :                         if (pack.ep_fa[argc+1] != NULL)
     323           0 :                                 free(pack.ep_fa[argc], M_EXEC, len);
     324             :                         else
     325           0 :                                 free(pack.ep_fa[argc], M_EXEC, MAXPATHLEN);
     326             :                 }
     327           0 :                 free(pack.ep_fa, M_EXEC, 4 * sizeof(char *));
     328           0 :                 pack.ep_flags &= ~EXEC_HASARGL;
     329           0 :         }
     330             : 
     331             :         /* Now get argv & environment */
     332           0 :         if (!(cpp = SCARG(uap, argp))) {
     333             :                 error = EFAULT;
     334           0 :                 goto bad;
     335             :         }
     336             : 
     337           0 :         if (pack.ep_flags & EXEC_SKIPARG)
     338           0 :                 cpp++;
     339             : 
     340           0 :         while (1) {
     341           0 :                 len = argp + ARG_MAX - dp;
     342           0 :                 if ((error = copyin(cpp, &sp, sizeof(sp))) != 0)
     343             :                         goto bad;
     344           0 :                 if (!sp)
     345             :                         break;
     346           0 :                 if ((error = copyinstr(sp, dp, len, &len)) != 0) {
     347           0 :                         if (error == ENAMETOOLONG)
     348           0 :                                 error = E2BIG;
     349             :                         goto bad;
     350             :                 }
     351           0 :                 dp += len;
     352           0 :                 cpp++;
     353           0 :                 argc++;
     354             :         }
     355             : 
     356             :         /* must have at least one argument */
     357           0 :         if (argc == 0) {
     358             :                 error = EINVAL;
     359           0 :                 goto bad;
     360             :         }
     361             : 
     362             : #ifdef KTRACE
     363           0 :         if (KTRPOINT(p, KTR_EXECARGS))
     364           0 :                 ktrexec(p, KTR_EXECARGS, argp, dp - argp);
     365             : #endif
     366             : 
     367             :         envc = 0;
     368             :         /* environment does not need to be there */
     369           0 :         if ((cpp = SCARG(uap, envp)) != NULL ) {
     370             : #ifdef KTRACE
     371             :                 env_start = dp;
     372             : #endif
     373           0 :                 while (1) {
     374           0 :                         len = argp + ARG_MAX - dp;
     375           0 :                         if ((error = copyin(cpp, &sp, sizeof(sp))) != 0)
     376             :                                 goto bad;
     377           0 :                         if (!sp)
     378             :                                 break;
     379           0 :                         if ((error = copyinstr(sp, dp, len, &len)) != 0) {
     380           0 :                                 if (error == ENAMETOOLONG)
     381           0 :                                         error = E2BIG;
     382             :                                 goto bad;
     383             :                         }
     384           0 :                         dp += len;
     385           0 :                         cpp++;
     386           0 :                         envc++;
     387             :                 }
     388             : 
     389             : #ifdef KTRACE
     390           0 :                 if (KTRPOINT(p, KTR_EXECENV))
     391           0 :                         ktrexec(p, KTR_EXECENV, env_start, dp - env_start);
     392             : #endif
     393             :         }
     394             : 
     395           0 :         dp = (char *)(((long)dp + _STACKALIGNBYTES) & ~_STACKALIGNBYTES);
     396             : 
     397             :         sgap = STACKGAPLEN;
     398             : 
     399             :         /*
     400             :          * If we have enabled random stackgap, the stack itself has already
     401             :          * been moved from a random location, but is still aligned to a page
     402             :          * boundary.  Provide the lower bits of random placement now.
     403             :          */
     404           0 :         if (stackgap_random != 0) {
     405           0 :                 sgap += arc4random() & PAGE_MASK;
     406           0 :                 sgap = (sgap + _STACKALIGNBYTES) & ~_STACKALIGNBYTES;
     407           0 :         }
     408             : 
     409             :         /* Now check if args & environ fit into new stack */
     410           0 :         len = ((argc + envc + 2 + pack.ep_emul->e_arglen) * sizeof(char *) +
     411           0 :             sizeof(long) + dp + sgap + sizeof(struct ps_strings)) - argp;
     412             : 
     413           0 :         len = (len + _STACKALIGNBYTES) &~ _STACKALIGNBYTES;
     414             : 
     415           0 :         if (len > pack.ep_ssize) { /* in effect, compare to initial limit */
     416             :                 error = ENOMEM;
     417           0 :                 goto bad;
     418             :         }
     419             : 
     420             :         /* adjust "active stack depth" for process VSZ */
     421           0 :         pack.ep_ssize = len;    /* maybe should go elsewhere, but... */
     422             : 
     423             :         /*
     424             :          * we're committed: any further errors will kill the process, so
     425             :          * kill the other threads now.
     426             :          */
     427           0 :         single_thread_set(p, SINGLE_EXIT, 0);
     428             : 
     429             :         /*
     430             :          * Prepare vmspace for remapping. Note that uvmspace_exec can replace
     431             :          * ps_vmspace!
     432             :          */
     433           0 :         uvmspace_exec(p, VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS);
     434             : 
     435           0 :         vm = pr->ps_vmspace;
     436             :         /* Now map address space */
     437           0 :         vm->vm_taddr = (char *)trunc_page(pack.ep_taddr);
     438           0 :         vm->vm_tsize = atop(round_page(pack.ep_taddr + pack.ep_tsize) -
     439             :             trunc_page(pack.ep_taddr));
     440           0 :         vm->vm_daddr = (char *)trunc_page(pack.ep_daddr);
     441           0 :         vm->vm_dsize = atop(round_page(pack.ep_daddr + pack.ep_dsize) -
     442             :             trunc_page(pack.ep_daddr));
     443           0 :         vm->vm_dused = 0;
     444           0 :         vm->vm_ssize = atop(round_page(pack.ep_ssize));
     445           0 :         vm->vm_maxsaddr = (char *)pack.ep_maxsaddr;
     446           0 :         vm->vm_minsaddr = (char *)pack.ep_minsaddr;
     447             : 
     448             :         /* create the new process's VM space by running the vmcmds */
     449             : #ifdef DIAGNOSTIC
     450           0 :         if (pack.ep_vmcmds.evs_used == 0)
     451           0 :                 panic("execve: no vmcmds");
     452             : #endif
     453           0 :         error = exec_process_vmcmds(p, &pack);
     454             : 
     455             :         /* if an error happened, deallocate and punt */
     456           0 :         if (error)
     457             :                 goto exec_abort;
     458             : 
     459             : #ifdef MACHINE_STACK_GROWS_UP
     460             :         pr->ps_strings = (vaddr_t)vm->vm_maxsaddr + sgap;
     461             :         if (uvm_map_protect(&vm->vm_map, (vaddr_t)vm->vm_maxsaddr,
     462             :             trunc_page(pr->ps_strings), PROT_NONE, TRUE))
     463             :                 goto exec_abort;
     464             : #else
     465           0 :         pr->ps_strings = (vaddr_t)vm->vm_minsaddr - sizeof(arginfo) - sgap;
     466           0 :         if (uvm_map_protect(&vm->vm_map,
     467           0 :             round_page(pr->ps_strings + sizeof(arginfo)),
     468           0 :             (vaddr_t)vm->vm_minsaddr, PROT_NONE, TRUE))
     469             :                 goto exec_abort;
     470             : #endif
     471             : 
     472             :         /* remember information about the process */
     473           0 :         arginfo.ps_nargvstr = argc;
     474           0 :         arginfo.ps_nenvstr = envc;
     475             : 
     476             : #ifdef MACHINE_STACK_GROWS_UP
     477             :         stack = (char *)vm->vm_maxsaddr + sizeof(arginfo) + sgap;
     478             :         slen = len - sizeof(arginfo) - sgap;
     479             : #else
     480           0 :         stack = (char *)(vm->vm_minsaddr - len);
     481             : #endif
     482             :         /* Now copy argc, args & environ to new stack */
     483           0 :         if (!(*pack.ep_emul->e_copyargs)(&pack, &arginfo, stack, argp))
     484             :                 goto exec_abort;
     485             : 
     486             :         /* copy out the process's ps_strings structure */
     487           0 :         if (copyout(&arginfo, (char *)pr->ps_strings, sizeof(arginfo)))
     488             :                 goto exec_abort;
     489             : 
     490           0 :         stopprofclock(pr);      /* stop profiling */
     491           0 :         fdcloseexec(p);         /* handle close on exec */
     492           0 :         execsigs(p);            /* reset caught signals */
     493           0 :         TCB_SET(p, NULL);       /* reset the TCB address */
     494           0 :         pr->ps_kbind_addr = 0;       /* reset the kbind bits */
     495           0 :         pr->ps_kbind_cookie = 0;
     496           0 :         arc4random_buf(&pr->ps_sigcookie, sizeof pr->ps_sigcookie);
     497             : 
     498             :         /* set command name & other accounting info */
     499           0 :         memset(pr->ps_comm, 0, sizeof(pr->ps_comm));
     500           0 :         len = min(nid.ni_cnd.cn_namelen, MAXCOMLEN);
     501           0 :         memcpy(pr->ps_comm, nid.ni_cnd.cn_nameptr, len);
     502           0 :         pr->ps_acflag &= ~AFORK;
     503             : 
     504             :         /* record proc's vnode, for use by sysctl */
     505           0 :         otvp = pr->ps_textvp;
     506           0 :         vref(pack.ep_vp);
     507           0 :         pr->ps_textvp = pack.ep_vp;
     508           0 :         if (otvp)
     509           0 :                 vrele(otvp);
     510             : 
     511           0 :         atomic_setbits_int(&pr->ps_flags, PS_EXEC);
     512           0 :         if (pr->ps_flags & PS_PPWAIT) {
     513           0 :                 atomic_clearbits_int(&pr->ps_flags, PS_PPWAIT);
     514           0 :                 atomic_clearbits_int(&pr->ps_pptr->ps_flags, PS_ISPWAIT);
     515           0 :                 wakeup(pr->ps_pptr);
     516           0 :         }
     517             : 
     518             :         /*
     519             :          * If process does execve() while it has a mismatched real,
     520             :          * effective, or saved uid/gid, we set PS_SUGIDEXEC.
     521             :          */
     522           0 :         if (cred->cr_uid != cred->cr_ruid ||
     523           0 :             cred->cr_uid != cred->cr_svuid ||
     524           0 :             cred->cr_gid != cred->cr_rgid ||
     525           0 :             cred->cr_gid != cred->cr_svgid)
     526           0 :                 atomic_setbits_int(&pr->ps_flags, PS_SUGIDEXEC);
     527             :         else
     528           0 :                 atomic_clearbits_int(&pr->ps_flags, PS_SUGIDEXEC);
     529             : 
     530           0 :         if (pr->ps_flags & PS_EXECPLEDGE) {
     531           0 :                 pr->ps_pledge = pr->ps_execpledge;
     532           0 :                 atomic_setbits_int(&pr->ps_flags, PS_PLEDGE);
     533           0 :         } else {
     534           0 :                 atomic_clearbits_int(&pr->ps_flags, PS_PLEDGE);
     535           0 :                 pr->ps_pledge = 0;
     536             :                 /* XXX XXX XXX XXX */
     537             :                 /* Clear our unveil paths out so the child
     538             :                  * starts afresh
     539             :                  */
     540           0 :                 unveil_destroy(pr);
     541           0 :                 pr->ps_uvdone = 0;
     542             :         }
     543             : 
     544             :         /*
     545             :          * deal with set[ug]id.
     546             :          * MNT_NOEXEC has already been used to disable s[ug]id.
     547             :          */
     548           0 :         if ((attr.va_mode & (VSUID | VSGID)) && proc_cansugid(p)) {
     549             :                 int i;
     550             : 
     551           0 :                 atomic_setbits_int(&pr->ps_flags, PS_SUGID|PS_SUGIDEXEC);
     552             : 
     553             : #ifdef KTRACE
     554             :                 /*
     555             :                  * If process is being ktraced, turn off - unless
     556             :                  * root set it.
     557             :                  */
     558           0 :                 if (pr->ps_tracevp && !(pr->ps_traceflag & KTRFAC_ROOT))
     559           0 :                         ktrcleartrace(pr);
     560             : #endif
     561           0 :                 p->p_ucred = cred = crcopy(cred);
     562           0 :                 if (attr.va_mode & VSUID)
     563           0 :                         cred->cr_uid = attr.va_uid;
     564           0 :                 if (attr.va_mode & VSGID)
     565           0 :                         cred->cr_gid = attr.va_gid;
     566             : 
     567             :                 /*
     568             :                  * For set[ug]id processes, a few caveats apply to
     569             :                  * stdin, stdout, and stderr.
     570             :                  */
     571             :                 error = 0;
     572           0 :                 fdplock(p->p_fd);
     573           0 :                 for (i = 0; i < 3; i++) {
     574           0 :                         struct file *fp = NULL;
     575             : 
     576             :                         /*
     577             :                          * NOTE - This will never return NULL because of
     578             :                          * immature fds. The file descriptor table is not
     579             :                          * shared because we're suid.
     580             :                          */
     581           0 :                         fp = fd_getfile(p->p_fd, i);
     582             : 
     583             :                         /*
     584             :                          * Ensure that stdin, stdout, and stderr are already
     585             :                          * allocated.  We do not want userland to accidentally
     586             :                          * allocate descriptors in this range which has implied
     587             :                          * meaning to libc.
     588             :                          */
     589           0 :                         if (fp == NULL) {
     590           0 :                                 short flags = FREAD | (i == 0 ? 0 : FWRITE);
     591           0 :                                 struct vnode *vp;
     592           0 :                                 int indx;
     593             : 
     594           0 :                                 if ((error = falloc(p, &fp, &indx)) != 0)
     595           0 :                                         break;
     596             : #ifdef DIAGNOSTIC
     597           0 :                                 if (indx != i)
     598           0 :                                         panic("sys_execve: falloc indx != i");
     599             : #endif
     600           0 :                                 if ((error = cdevvp(getnulldev(), &vp)) != 0) {
     601           0 :                                         fdremove(p->p_fd, indx);
     602           0 :                                         closef(fp, p);
     603           0 :                                         break;
     604             :                                 }
     605           0 :                                 if ((error = VOP_OPEN(vp, flags, cred, p)) != 0) {
     606           0 :                                         fdremove(p->p_fd, indx);
     607           0 :                                         closef(fp, p);
     608           0 :                                         vrele(vp);
     609           0 :                                         break;
     610             :                                 }
     611           0 :                                 if (flags & FWRITE)
     612           0 :                                         vp->v_writecount++;
     613           0 :                                 fp->f_flag = flags;
     614           0 :                                 fp->f_type = DTYPE_VNODE;
     615           0 :                                 fp->f_ops = &vnops;
     616           0 :                                 fp->f_data = (caddr_t)vp;
     617           0 :                                 fdinsert(p->p_fd, indx, 0, fp);
     618           0 :                         }
     619           0 :                         FRELE(fp, p);
     620           0 :                 }
     621           0 :                 fdpunlock(p->p_fd);
     622           0 :                 if (error)
     623           0 :                         goto exec_abort;
     624           0 :         } else
     625           0 :                 atomic_clearbits_int(&pr->ps_flags, PS_SUGID);
     626             : 
     627             :         /*
     628             :          * Reset the saved ugids and update the process's copy of the
     629             :          * creds if the creds have been changed
     630             :          */
     631           0 :         if (cred->cr_uid != cred->cr_svuid ||
     632           0 :             cred->cr_gid != cred->cr_svgid) {
     633             :                 /* make sure we have unshared ucreds */
     634           0 :                 p->p_ucred = cred = crcopy(cred);
     635           0 :                 cred->cr_svuid = cred->cr_uid;
     636           0 :                 cred->cr_svgid = cred->cr_gid;
     637           0 :         }
     638             : 
     639           0 :         if (pr->ps_ucred != cred) {
     640             :                 struct ucred *ocred;
     641             : 
     642             :                 ocred = pr->ps_ucred;
     643           0 :                 crhold(cred);
     644           0 :                 pr->ps_ucred = cred;
     645           0 :                 crfree(ocred);
     646           0 :         }
     647             : 
     648           0 :         if (pr->ps_flags & PS_SUGIDEXEC) {
     649           0 :                 int i, s = splclock();
     650             : 
     651           0 :                 timeout_del(&pr->ps_realit_to);
     652           0 :                 for (i = 0; i < nitems(pr->ps_timer); i++) {
     653           0 :                         timerclear(&pr->ps_timer[i].it_interval);
     654           0 :                         timerclear(&pr->ps_timer[i].it_value);
     655             :                 }
     656           0 :                 splx(s);
     657           0 :         }
     658             : 
     659             :         /* reset CPU time usage for the thread, but not the process */
     660           0 :         timespecclear(&p->p_tu.tu_runtime);
     661           0 :         p->p_tu.tu_uticks = p->p_tu.tu_sticks = p->p_tu.tu_iticks = 0;
     662             : 
     663           0 :         km_free(argp, NCARGS, &kv_exec, &kp_pageable);
     664             : 
     665           0 :         pool_put(&namei_pool, nid.ni_cnd.cn_pnbuf);
     666           0 :         vn_close(pack.ep_vp, FREAD, cred, p);
     667             : 
     668             :         /*
     669             :          * notify others that we exec'd
     670             :          */
     671           0 :         KNOTE(&pr->ps_klist, NOTE_EXEC);
     672             : 
     673             :         /* setup new registers and do misc. setup. */
     674           0 :         if (pack.ep_emul->e_fixup != NULL) {
     675           0 :                 if ((*pack.ep_emul->e_fixup)(p, &pack) != 0)
     676             :                         goto free_pack_abort;
     677             :         }
     678             : #ifdef MACHINE_STACK_GROWS_UP
     679             :         (*pack.ep_emul->e_setregs)(p, &pack, (u_long)stack + slen, retval);
     680             : #else
     681           0 :         (*pack.ep_emul->e_setregs)(p, &pack, (u_long)stack, retval);
     682             : #endif
     683             : 
     684             :         /* map the process's signal trampoline code */
     685           0 :         if (exec_sigcode_map(pr, pack.ep_emul))
     686             :                 goto free_pack_abort;
     687             : 
     688             : #ifdef __HAVE_EXEC_MD_MAP
     689             :         /* perform md specific mappings that process might need */
     690             :         if (exec_md_map(p, &pack))
     691             :                 goto free_pack_abort;
     692             : #endif
     693             : 
     694           0 :         if (pr->ps_flags & PS_TRACED)
     695           0 :                 psignal(p, SIGTRAP);
     696             : 
     697           0 :         free(pack.ep_hdr, M_EXEC, pack.ep_hdrlen);
     698             : 
     699           0 :         p->p_descfd = 255;
     700           0 :         if ((pack.ep_flags & EXEC_HASFD) && pack.ep_fd < 255)
     701           0 :                 p->p_descfd = pack.ep_fd;
     702             : 
     703           0 :         if (pack.ep_flags & EXEC_WXNEEDED)
     704           0 :                 p->p_p->ps_flags |= PS_WXNEEDED;
     705             :         else
     706           0 :                 p->p_p->ps_flags &= ~PS_WXNEEDED;
     707             : 
     708             :         /* update ps_emul, the old value is no longer needed */
     709           0 :         pr->ps_emul = pack.ep_emul;
     710             : 
     711           0 :         atomic_clearbits_int(&pr->ps_flags, PS_INEXEC);
     712           0 :         single_thread_clear(p, P_SUSPSIG);
     713             : 
     714           0 :         return (0);
     715             : 
     716             : bad:
     717             :         /* free the vmspace-creation commands, and release their references */
     718           0 :         kill_vmcmds(&pack.ep_vmcmds);
     719             :         /* kill any opened file descriptor, if necessary */
     720           0 :         if (pack.ep_flags & EXEC_HASFD) {
     721           0 :                 pack.ep_flags &= ~EXEC_HASFD;
     722           0 :                 fdplock(p->p_fd);
     723           0 :                 (void) fdrelease(p, pack.ep_fd);
     724           0 :                 fdpunlock(p->p_fd);
     725           0 :         }
     726           0 :         if (pack.ep_interp != NULL)
     727           0 :                 pool_put(&namei_pool, pack.ep_interp);
     728           0 :         if (pack.ep_emul_arg != NULL)
     729           0 :                 free(pack.ep_emul_arg, M_TEMP, pack.ep_emul_argsize);
     730             :         /* close and put the exec'd file */
     731           0 :         vn_close(pack.ep_vp, FREAD, cred, p);
     732           0 :         pool_put(&namei_pool, nid.ni_cnd.cn_pnbuf);
     733           0 :         km_free(argp, NCARGS, &kv_exec, &kp_pageable);
     734             : 
     735             : freehdr:
     736           0 :         free(pack.ep_hdr, M_EXEC, pack.ep_hdrlen);
     737           0 :         atomic_clearbits_int(&pr->ps_flags, PS_INEXEC);
     738           0 :         single_thread_clear(p, P_SUSPSIG);
     739             : 
     740           0 :         return (error);
     741             : 
     742             : exec_abort:
     743             :         /*
     744             :          * the old process doesn't exist anymore.  exit gracefully.
     745             :          * get rid of the (new) address space we have created, if any, get rid
     746             :          * of our namei data and vnode, and exit noting failure
     747             :          */
     748           0 :         uvm_deallocate(&vm->vm_map, VM_MIN_ADDRESS,
     749             :                 VM_MAXUSER_ADDRESS - VM_MIN_ADDRESS);
     750           0 :         if (pack.ep_interp != NULL)
     751           0 :                 pool_put(&namei_pool, pack.ep_interp);
     752           0 :         if (pack.ep_emul_arg != NULL)
     753           0 :                 free(pack.ep_emul_arg, M_TEMP, pack.ep_emul_argsize);
     754           0 :         pool_put(&namei_pool, nid.ni_cnd.cn_pnbuf);
     755           0 :         vn_close(pack.ep_vp, FREAD, cred, p);
     756           0 :         km_free(argp, NCARGS, &kv_exec, &kp_pageable);
     757             : 
     758             : free_pack_abort:
     759           0 :         free(pack.ep_hdr, M_EXEC, pack.ep_hdrlen);
     760           0 :         exit1(p, W_EXITCODE(0, SIGABRT), EXIT_NORMAL);
     761             : 
     762             :         /* NOTREACHED */
     763           0 :         atomic_clearbits_int(&pr->ps_flags, PS_INEXEC);
     764             : 
     765           0 :         return (0);
     766           0 : }
     767             : 
     768             : 
     769             : void *
     770           0 : copyargs(struct exec_package *pack, struct ps_strings *arginfo, void *stack,
     771             :     void *argp)
     772             : {
     773           0 :         char **cpp = stack;
     774           0 :         char *dp, *sp;
     775           0 :         size_t len;
     776           0 :         void *nullp = NULL;
     777           0 :         long argc = arginfo->ps_nargvstr;
     778           0 :         int envc = arginfo->ps_nenvstr;
     779             : 
     780           0 :         if (copyout(&argc, cpp++, sizeof(argc)))
     781           0 :                 return (NULL);
     782             : 
     783           0 :         dp = (char *) (cpp + argc + envc + 2 + pack->ep_emul->e_arglen);
     784             :         sp = argp;
     785             : 
     786             :         /* XXX don't copy them out, remap them! */
     787           0 :         arginfo->ps_argvstr = cpp; /* remember location of argv for later */
     788             : 
     789           0 :         for (; --argc >= 0; sp += len, dp += len)
     790           0 :                 if (copyout(&dp, cpp++, sizeof(dp)) ||
     791           0 :                     copyoutstr(sp, dp, ARG_MAX, &len))
     792           0 :                         return (NULL);
     793             : 
     794           0 :         if (copyout(&nullp, cpp++, sizeof(nullp)))
     795           0 :                 return (NULL);
     796             : 
     797           0 :         arginfo->ps_envstr = cpp; /* remember location of envp for later */
     798             : 
     799           0 :         for (; --envc >= 0; sp += len, dp += len)
     800           0 :                 if (copyout(&dp, cpp++, sizeof(dp)) ||
     801           0 :                     copyoutstr(sp, dp, ARG_MAX, &len))
     802           0 :                         return (NULL);
     803             : 
     804           0 :         if (copyout(&nullp, cpp++, sizeof(nullp)))
     805           0 :                 return (NULL);
     806             : 
     807           0 :         return (cpp);
     808           0 : }
     809             : 
     810             : int
     811           0 : exec_sigcode_map(struct process *pr, struct emul *e)
     812             : {
     813             :         vsize_t sz;
     814             : 
     815           0 :         sz = (vaddr_t)e->e_esigcode - (vaddr_t)e->e_sigcode;
     816             : 
     817             :         /*
     818             :          * If we don't have a sigobject for this emulation, create one.
     819             :          *
     820             :          * sigobject is an anonymous memory object (just like SYSV shared
     821             :          * memory) that we keep a permanent reference to and that we map
     822             :          * in all processes that need this sigcode. The creation is simple,
     823             :          * we create an object, add a permanent reference to it, map it in
     824             :          * kernel space, copy out the sigcode to it and unmap it.
     825             :          * Then we map it with PROT_READ|PROT_EXEC into the process just
     826             :          * the way sys_mmap would map it.
     827             :          */
     828           0 :         if (e->e_sigobject == NULL) {
     829             :                 extern int sigfillsiz;
     830             :                 extern u_char sigfill[];
     831             :                 size_t off;
     832           0 :                 vaddr_t va;
     833             :                 int r;
     834             : 
     835           0 :                 e->e_sigobject = uao_create(sz, 0);
     836           0 :                 uao_reference(e->e_sigobject);       /* permanent reference */
     837             : 
     838           0 :                 if ((r = uvm_map(kernel_map, &va, round_page(sz), e->e_sigobject,
     839             :                     0, 0, UVM_MAPFLAG(PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE,
     840             :                     MAP_INHERIT_SHARE, MADV_RANDOM, 0)))) {
     841           0 :                         uao_detach(e->e_sigobject);
     842           0 :                         return (ENOMEM);
     843             :                 }
     844             : 
     845           0 :                 for (off = 0; off < round_page(sz); off += sigfillsiz)
     846           0 :                         memcpy((caddr_t)va + off, sigfill, sigfillsiz);
     847           0 :                 memcpy((caddr_t)va, e->e_sigcode, sz);
     848           0 :                 uvm_unmap(kernel_map, va, va + round_page(sz));
     849           0 :         }
     850             : 
     851           0 :         pr->ps_sigcode = 0; /* no hint */
     852           0 :         uao_reference(e->e_sigobject);
     853           0 :         if (uvm_map(&pr->ps_vmspace->vm_map, &pr->ps_sigcode, round_page(sz),
     854           0 :             e->e_sigobject, 0, 0, UVM_MAPFLAG(PROT_READ | PROT_EXEC,
     855             :             PROT_READ | PROT_WRITE | PROT_EXEC, MAP_INHERIT_COPY,
     856             :             MADV_RANDOM, UVM_FLAG_COPYONW))) {
     857           0 :                 uao_detach(e->e_sigobject);
     858           0 :                 return (ENOMEM);
     859             :         }
     860             : 
     861             :         /* Calculate PC at point of sigreturn entry */
     862           0 :         pr->ps_sigcoderet = pr->ps_sigcode +
     863           0 :             (pr->ps_emul->e_esigret - pr->ps_emul->e_sigcode);
     864             : 
     865           0 :         return (0);
     866           0 : }

Generated by: LCOV version 1.13