The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/kern_prot.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-3-Clause
    3  *
    4  * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
    5  *      The Regents of the University of California.
    6  * (c) UNIX System Laboratories, Inc.
    7  * Copyright (c) 2000-2001 Robert N. M. Watson.
    8  * All rights reserved.
    9  *
   10  * All or some portions of this file are derived from material licensed
   11  * to the University of California by American Telephone and Telegraph
   12  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   13  * the permission of UNIX System Laboratories, Inc.
   14  *
   15  * Redistribution and use in source and binary forms, with or without
   16  * modification, are permitted provided that the following conditions
   17  * are met:
   18  * 1. Redistributions of source code must retain the above copyright
   19  *    notice, this list of conditions and the following disclaimer.
   20  * 2. Redistributions in binary form must reproduce the above copyright
   21  *    notice, this list of conditions and the following disclaimer in the
   22  *    documentation and/or other materials provided with the distribution.
   23  * 3. Neither the name of the University nor the names of its contributors
   24  *    may be used to endorse or promote products derived from this software
   25  *    without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   28  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   30  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   31  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   37  * SUCH DAMAGE.
   38  *
   39  *      @(#)kern_prot.c 8.6 (Berkeley) 1/21/94
   40  */
   41 
   42 /*
   43  * System calls related to processes and protection
   44  */
   45 
   46 #include <sys/cdefs.h>
   47 __FBSDID("$FreeBSD$");
   48 
   49 #include "opt_inet.h"
   50 #include "opt_inet6.h"
   51 
   52 #include <sys/param.h>
   53 #include <sys/systm.h>
   54 #include <sys/acct.h>
   55 #include <sys/kdb.h>
   56 #include <sys/kernel.h>
   57 #include <sys/lock.h>
   58 #include <sys/loginclass.h>
   59 #include <sys/malloc.h>
   60 #include <sys/mutex.h>
   61 #include <sys/ptrace.h>
   62 #include <sys/refcount.h>
   63 #include <sys/sx.h>
   64 #include <sys/priv.h>
   65 #include <sys/proc.h>
   66 #ifdef COMPAT_43
   67 #include <sys/sysent.h>
   68 #endif
   69 #include <sys/sysproto.h>
   70 #include <sys/jail.h>
   71 #include <sys/racct.h>
   72 #include <sys/rctl.h>
   73 #include <sys/resourcevar.h>
   74 #include <sys/socket.h>
   75 #include <sys/socketvar.h>
   76 #include <sys/syscallsubr.h>
   77 #include <sys/sysctl.h>
   78 
   79 #ifdef REGRESSION
   80 FEATURE(regression,
   81     "Kernel support for interfaces necessary for regression testing (SECURITY RISK!)");
   82 #endif
   83 
   84 #include <security/audit/audit.h>
   85 #include <security/mac/mac_framework.h>
   86 
   87 static MALLOC_DEFINE(M_CRED, "cred", "credentials");
   88 
   89 SYSCTL_NODE(_security, OID_AUTO, bsd, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
   90     "BSD security policy");
   91 
   92 static void crfree_final(struct ucred *cr);
   93 static void crsetgroups_locked(struct ucred *cr, int ngrp,
   94     gid_t *groups);
   95 
   96 #ifndef _SYS_SYSPROTO_H_
   97 struct getpid_args {
   98         int     dummy;
   99 };
  100 #endif
  101 /* ARGSUSED */
  102 int
  103 sys_getpid(struct thread *td, struct getpid_args *uap)
  104 {
  105         struct proc *p = td->td_proc;
  106 
  107         td->td_retval[0] = p->p_pid;
  108 #if defined(COMPAT_43)
  109         if (SV_PROC_FLAG(p, SV_AOUT))
  110                 td->td_retval[1] = kern_getppid(td);
  111 #endif
  112         return (0);
  113 }
  114 
  115 #ifndef _SYS_SYSPROTO_H_
  116 struct getppid_args {
  117         int     dummy;
  118 };
  119 #endif
  120 /* ARGSUSED */
  121 int
  122 sys_getppid(struct thread *td, struct getppid_args *uap)
  123 {
  124 
  125         td->td_retval[0] = kern_getppid(td);
  126         return (0);
  127 }
  128 
  129 int
  130 kern_getppid(struct thread *td)
  131 {
  132         struct proc *p = td->td_proc;
  133 
  134         return (p->p_oppid);
  135 }
  136 
  137 /*
  138  * Get process group ID; note that POSIX getpgrp takes no parameter.
  139  */
  140 #ifndef _SYS_SYSPROTO_H_
  141 struct getpgrp_args {
  142         int     dummy;
  143 };
  144 #endif
  145 int
  146 sys_getpgrp(struct thread *td, struct getpgrp_args *uap)
  147 {
  148         struct proc *p = td->td_proc;
  149 
  150         PROC_LOCK(p);
  151         td->td_retval[0] = p->p_pgrp->pg_id;
  152         PROC_UNLOCK(p);
  153         return (0);
  154 }
  155 
  156 /* Get an arbitrary pid's process group id */
  157 #ifndef _SYS_SYSPROTO_H_
  158 struct getpgid_args {
  159         pid_t   pid;
  160 };
  161 #endif
  162 int
  163 sys_getpgid(struct thread *td, struct getpgid_args *uap)
  164 {
  165         struct proc *p;
  166         int error;
  167 
  168         if (uap->pid == 0) {
  169                 p = td->td_proc;
  170                 PROC_LOCK(p);
  171         } else {
  172                 p = pfind(uap->pid);
  173                 if (p == NULL)
  174                         return (ESRCH);
  175                 error = p_cansee(td, p);
  176                 if (error) {
  177                         PROC_UNLOCK(p);
  178                         return (error);
  179                 }
  180         }
  181         td->td_retval[0] = p->p_pgrp->pg_id;
  182         PROC_UNLOCK(p);
  183         return (0);
  184 }
  185 
  186 /*
  187  * Get an arbitrary pid's session id.
  188  */
  189 #ifndef _SYS_SYSPROTO_H_
  190 struct getsid_args {
  191         pid_t   pid;
  192 };
  193 #endif
  194 int
  195 sys_getsid(struct thread *td, struct getsid_args *uap)
  196 {
  197 
  198         return (kern_getsid(td, uap->pid));
  199 }
  200 
  201 int
  202 kern_getsid(struct thread *td, pid_t pid)
  203 {
  204         struct proc *p;
  205         int error;
  206 
  207         if (pid == 0) {
  208                 p = td->td_proc;
  209                 PROC_LOCK(p);
  210         } else {
  211                 p = pfind(pid);
  212                 if (p == NULL)
  213                         return (ESRCH);
  214                 error = p_cansee(td, p);
  215                 if (error) {
  216                         PROC_UNLOCK(p);
  217                         return (error);
  218                 }
  219         }
  220         td->td_retval[0] = p->p_session->s_sid;
  221         PROC_UNLOCK(p);
  222         return (0);
  223 }
  224 
  225 #ifndef _SYS_SYSPROTO_H_
  226 struct getuid_args {
  227         int     dummy;
  228 };
  229 #endif
  230 /* ARGSUSED */
  231 int
  232 sys_getuid(struct thread *td, struct getuid_args *uap)
  233 {
  234 
  235         td->td_retval[0] = td->td_ucred->cr_ruid;
  236 #if defined(COMPAT_43)
  237         td->td_retval[1] = td->td_ucred->cr_uid;
  238 #endif
  239         return (0);
  240 }
  241 
  242 #ifndef _SYS_SYSPROTO_H_
  243 struct geteuid_args {
  244         int     dummy;
  245 };
  246 #endif
  247 /* ARGSUSED */
  248 int
  249 sys_geteuid(struct thread *td, struct geteuid_args *uap)
  250 {
  251 
  252         td->td_retval[0] = td->td_ucred->cr_uid;
  253         return (0);
  254 }
  255 
  256 #ifndef _SYS_SYSPROTO_H_
  257 struct getgid_args {
  258         int     dummy;
  259 };
  260 #endif
  261 /* ARGSUSED */
  262 int
  263 sys_getgid(struct thread *td, struct getgid_args *uap)
  264 {
  265 
  266         td->td_retval[0] = td->td_ucred->cr_rgid;
  267 #if defined(COMPAT_43)
  268         td->td_retval[1] = td->td_ucred->cr_groups[0];
  269 #endif
  270         return (0);
  271 }
  272 
  273 /*
  274  * Get effective group ID.  The "egid" is groups[0], and could be obtained
  275  * via getgroups.  This syscall exists because it is somewhat painful to do
  276  * correctly in a library function.
  277  */
  278 #ifndef _SYS_SYSPROTO_H_
  279 struct getegid_args {
  280         int     dummy;
  281 };
  282 #endif
  283 /* ARGSUSED */
  284 int
  285 sys_getegid(struct thread *td, struct getegid_args *uap)
  286 {
  287 
  288         td->td_retval[0] = td->td_ucred->cr_groups[0];
  289         return (0);
  290 }
  291 
  292 #ifndef _SYS_SYSPROTO_H_
  293 struct getgroups_args {
  294         int     gidsetsize;
  295         gid_t   *gidset;
  296 };
  297 #endif
  298 int
  299 sys_getgroups(struct thread *td, struct getgroups_args *uap)
  300 {
  301         struct ucred *cred;
  302         int ngrp, error;
  303 
  304         cred = td->td_ucred;
  305         ngrp = cred->cr_ngroups;
  306 
  307         if (uap->gidsetsize == 0) {
  308                 error = 0;
  309                 goto out;
  310         }
  311         if (uap->gidsetsize < ngrp)
  312                 return (EINVAL);
  313 
  314         error = copyout(cred->cr_groups, uap->gidset, ngrp * sizeof(gid_t));
  315 out:
  316         td->td_retval[0] = ngrp;
  317         return (error);
  318 }
  319 
  320 #ifndef _SYS_SYSPROTO_H_
  321 struct setsid_args {
  322         int     dummy;
  323 };
  324 #endif
  325 /* ARGSUSED */
  326 int
  327 sys_setsid(struct thread *td, struct setsid_args *uap)
  328 {
  329         struct pgrp *pgrp;
  330         int error;
  331         struct proc *p = td->td_proc;
  332         struct pgrp *newpgrp;
  333         struct session *newsess;
  334 
  335         error = 0;
  336         pgrp = NULL;
  337 
  338         newpgrp = uma_zalloc(pgrp_zone, M_WAITOK);
  339         newsess = malloc(sizeof(struct session), M_SESSION, M_WAITOK | M_ZERO);
  340 
  341         sx_xlock(&proctree_lock);
  342 
  343         if (p->p_pgid == p->p_pid || (pgrp = pgfind(p->p_pid)) != NULL) {
  344                 if (pgrp != NULL)
  345                         PGRP_UNLOCK(pgrp);
  346                 error = EPERM;
  347         } else {
  348                 (void)enterpgrp(p, p->p_pid, newpgrp, newsess);
  349                 td->td_retval[0] = p->p_pid;
  350                 newpgrp = NULL;
  351                 newsess = NULL;
  352         }
  353 
  354         sx_xunlock(&proctree_lock);
  355 
  356         uma_zfree(pgrp_zone, newpgrp);
  357         free(newsess, M_SESSION);
  358 
  359         return (error);
  360 }
  361 
  362 /*
  363  * set process group (setpgid/old setpgrp)
  364  *
  365  * caller does setpgid(targpid, targpgid)
  366  *
  367  * pid must be caller or child of caller (ESRCH)
  368  * if a child
  369  *      pid must be in same session (EPERM)
  370  *      pid can't have done an exec (EACCES)
  371  * if pgid != pid
  372  *      there must exist some pid in same session having pgid (EPERM)
  373  * pid must not be session leader (EPERM)
  374  */
  375 #ifndef _SYS_SYSPROTO_H_
  376 struct setpgid_args {
  377         int     pid;            /* target process id */
  378         int     pgid;           /* target pgrp id */
  379 };
  380 #endif
  381 /* ARGSUSED */
  382 int
  383 sys_setpgid(struct thread *td, struct setpgid_args *uap)
  384 {
  385         struct proc *curp = td->td_proc;
  386         struct proc *targp;     /* target process */
  387         struct pgrp *pgrp;      /* target pgrp */
  388         int error;
  389         struct pgrp *newpgrp;
  390 
  391         if (uap->pgid < 0)
  392                 return (EINVAL);
  393 
  394         error = 0;
  395 
  396         newpgrp = uma_zalloc(pgrp_zone, M_WAITOK);
  397 
  398         sx_xlock(&proctree_lock);
  399         if (uap->pid != 0 && uap->pid != curp->p_pid) {
  400                 if ((targp = pfind(uap->pid)) == NULL) {
  401                         error = ESRCH;
  402                         goto done;
  403                 }
  404                 if (!inferior(targp)) {
  405                         PROC_UNLOCK(targp);
  406                         error = ESRCH;
  407                         goto done;
  408                 }
  409                 if ((error = p_cansee(td, targp))) {
  410                         PROC_UNLOCK(targp);
  411                         goto done;
  412                 }
  413                 if (targp->p_pgrp == NULL ||
  414                     targp->p_session != curp->p_session) {
  415                         PROC_UNLOCK(targp);
  416                         error = EPERM;
  417                         goto done;
  418                 }
  419                 if (targp->p_flag & P_EXEC) {
  420                         PROC_UNLOCK(targp);
  421                         error = EACCES;
  422                         goto done;
  423                 }
  424                 PROC_UNLOCK(targp);
  425         } else
  426                 targp = curp;
  427         if (SESS_LEADER(targp)) {
  428                 error = EPERM;
  429                 goto done;
  430         }
  431         if (uap->pgid == 0)
  432                 uap->pgid = targp->p_pid;
  433         if ((pgrp = pgfind(uap->pgid)) == NULL) {
  434                 if (uap->pgid == targp->p_pid) {
  435                         error = enterpgrp(targp, uap->pgid, newpgrp,
  436                             NULL);
  437                         if (error == 0)
  438                                 newpgrp = NULL;
  439                 } else
  440                         error = EPERM;
  441         } else {
  442                 if (pgrp == targp->p_pgrp) {
  443                         PGRP_UNLOCK(pgrp);
  444                         goto done;
  445                 }
  446                 if (pgrp->pg_id != targp->p_pid &&
  447                     pgrp->pg_session != curp->p_session) {
  448                         PGRP_UNLOCK(pgrp);
  449                         error = EPERM;
  450                         goto done;
  451                 }
  452                 PGRP_UNLOCK(pgrp);
  453                 error = enterthispgrp(targp, pgrp);
  454         }
  455 done:
  456         sx_xunlock(&proctree_lock);
  457         KASSERT((error == 0) || (newpgrp != NULL),
  458             ("setpgid failed and newpgrp is NULL"));
  459         uma_zfree(pgrp_zone, newpgrp);
  460         return (error);
  461 }
  462 
  463 /*
  464  * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD
  465  * compatible.  It says that setting the uid/gid to euid/egid is a special
  466  * case of "appropriate privilege".  Once the rules are expanded out, this
  467  * basically means that setuid(nnn) sets all three id's, in all permitted
  468  * cases unless _POSIX_SAVED_IDS is enabled.  In that case, setuid(getuid())
  469  * does not set the saved id - this is dangerous for traditional BSD
  470  * programs.  For this reason, we *really* do not want to set
  471  * _POSIX_SAVED_IDS and do not want to clear POSIX_APPENDIX_B_4_2_2.
  472  */
  473 #define POSIX_APPENDIX_B_4_2_2
  474 
  475 #ifndef _SYS_SYSPROTO_H_
  476 struct setuid_args {
  477         uid_t   uid;
  478 };
  479 #endif
  480 /* ARGSUSED */
  481 int
  482 sys_setuid(struct thread *td, struct setuid_args *uap)
  483 {
  484         struct proc *p = td->td_proc;
  485         struct ucred *newcred, *oldcred;
  486         uid_t uid;
  487         struct uidinfo *uip;
  488         int error;
  489 
  490         uid = uap->uid;
  491         AUDIT_ARG_UID(uid);
  492         newcred = crget();
  493         uip = uifind(uid);
  494         PROC_LOCK(p);
  495         /*
  496          * Copy credentials so other references do not see our changes.
  497          */
  498         oldcred = crcopysafe(p, newcred);
  499 
  500 #ifdef MAC
  501         error = mac_cred_check_setuid(oldcred, uid);
  502         if (error)
  503                 goto fail;
  504 #endif
  505 
  506         /*
  507          * See if we have "permission" by POSIX 1003.1 rules.
  508          *
  509          * Note that setuid(geteuid()) is a special case of
  510          * "appropriate privileges" in appendix B.4.2.2.  We need
  511          * to use this clause to be compatible with traditional BSD
  512          * semantics.  Basically, it means that "setuid(xx)" sets all
  513          * three id's (assuming you have privs).
  514          *
  515          * Notes on the logic.  We do things in three steps.
  516          * 1: We determine if the euid is going to change, and do EPERM
  517          *    right away.  We unconditionally change the euid later if this
  518          *    test is satisfied, simplifying that part of the logic.
  519          * 2: We determine if the real and/or saved uids are going to
  520          *    change.  Determined by compile options.
  521          * 3: Change euid last. (after tests in #2 for "appropriate privs")
  522          */
  523         if (uid != oldcred->cr_ruid &&          /* allow setuid(getuid()) */
  524 #ifdef _POSIX_SAVED_IDS
  525             uid != oldcred->cr_svuid &&         /* allow setuid(saved gid) */
  526 #endif
  527 #ifdef POSIX_APPENDIX_B_4_2_2   /* Use BSD-compat clause from B.4.2.2 */
  528             uid != oldcred->cr_uid &&           /* allow setuid(geteuid()) */
  529 #endif
  530             (error = priv_check_cred(oldcred, PRIV_CRED_SETUID)) != 0)
  531                 goto fail;
  532 
  533 #ifdef _POSIX_SAVED_IDS
  534         /*
  535          * Do we have "appropriate privileges" (are we root or uid == euid)
  536          * If so, we are changing the real uid and/or saved uid.
  537          */
  538         if (
  539 #ifdef POSIX_APPENDIX_B_4_2_2   /* Use the clause from B.4.2.2 */
  540             uid == oldcred->cr_uid ||
  541 #endif
  542             /* We are using privs. */
  543             priv_check_cred(oldcred, PRIV_CRED_SETUID) == 0)
  544 #endif
  545         {
  546                 /*
  547                  * Set the real uid and transfer proc count to new user.
  548                  */
  549                 if (uid != oldcred->cr_ruid) {
  550                         change_ruid(newcred, uip);
  551                         setsugid(p);
  552                 }
  553                 /*
  554                  * Set saved uid
  555                  *
  556                  * XXX always set saved uid even if not _POSIX_SAVED_IDS, as
  557                  * the security of seteuid() depends on it.  B.4.2.2 says it
  558                  * is important that we should do this.
  559                  */
  560                 if (uid != oldcred->cr_svuid) {
  561                         change_svuid(newcred, uid);
  562                         setsugid(p);
  563                 }
  564         }
  565 
  566         /*
  567          * In all permitted cases, we are changing the euid.
  568          */
  569         if (uid != oldcred->cr_uid) {
  570                 change_euid(newcred, uip);
  571                 setsugid(p);
  572         }
  573         proc_set_cred(p, newcred);
  574 #ifdef RACCT
  575         racct_proc_ucred_changed(p, oldcred, newcred);
  576         crhold(newcred);
  577 #endif
  578         PROC_UNLOCK(p);
  579 #ifdef RCTL
  580         rctl_proc_ucred_changed(p, newcred);
  581         crfree(newcred);
  582 #endif
  583         uifree(uip);
  584         crfree(oldcred);
  585         return (0);
  586 
  587 fail:
  588         PROC_UNLOCK(p);
  589         uifree(uip);
  590         crfree(newcred);
  591         return (error);
  592 }
  593 
  594 #ifndef _SYS_SYSPROTO_H_
  595 struct seteuid_args {
  596         uid_t   euid;
  597 };
  598 #endif
  599 /* ARGSUSED */
  600 int
  601 sys_seteuid(struct thread *td, struct seteuid_args *uap)
  602 {
  603         struct proc *p = td->td_proc;
  604         struct ucred *newcred, *oldcred;
  605         uid_t euid;
  606         struct uidinfo *euip;
  607         int error;
  608 
  609         euid = uap->euid;
  610         AUDIT_ARG_EUID(euid);
  611         newcred = crget();
  612         euip = uifind(euid);
  613         PROC_LOCK(p);
  614         /*
  615          * Copy credentials so other references do not see our changes.
  616          */
  617         oldcred = crcopysafe(p, newcred);
  618 
  619 #ifdef MAC
  620         error = mac_cred_check_seteuid(oldcred, euid);
  621         if (error)
  622                 goto fail;
  623 #endif
  624 
  625         if (euid != oldcred->cr_ruid &&         /* allow seteuid(getuid()) */
  626             euid != oldcred->cr_svuid &&        /* allow seteuid(saved uid) */
  627             (error = priv_check_cred(oldcred, PRIV_CRED_SETEUID)) != 0)
  628                 goto fail;
  629 
  630         /*
  631          * Everything's okay, do it.
  632          */
  633         if (oldcred->cr_uid != euid) {
  634                 change_euid(newcred, euip);
  635                 setsugid(p);
  636         }
  637         proc_set_cred(p, newcred);
  638         PROC_UNLOCK(p);
  639         uifree(euip);
  640         crfree(oldcred);
  641         return (0);
  642 
  643 fail:
  644         PROC_UNLOCK(p);
  645         uifree(euip);
  646         crfree(newcred);
  647         return (error);
  648 }
  649 
  650 #ifndef _SYS_SYSPROTO_H_
  651 struct setgid_args {
  652         gid_t   gid;
  653 };
  654 #endif
  655 /* ARGSUSED */
  656 int
  657 sys_setgid(struct thread *td, struct setgid_args *uap)
  658 {
  659         struct proc *p = td->td_proc;
  660         struct ucred *newcred, *oldcred;
  661         gid_t gid;
  662         int error;
  663 
  664         gid = uap->gid;
  665         AUDIT_ARG_GID(gid);
  666         newcred = crget();
  667         PROC_LOCK(p);
  668         oldcred = crcopysafe(p, newcred);
  669 
  670 #ifdef MAC
  671         error = mac_cred_check_setgid(oldcred, gid);
  672         if (error)
  673                 goto fail;
  674 #endif
  675 
  676         /*
  677          * See if we have "permission" by POSIX 1003.1 rules.
  678          *
  679          * Note that setgid(getegid()) is a special case of
  680          * "appropriate privileges" in appendix B.4.2.2.  We need
  681          * to use this clause to be compatible with traditional BSD
  682          * semantics.  Basically, it means that "setgid(xx)" sets all
  683          * three id's (assuming you have privs).
  684          *
  685          * For notes on the logic here, see setuid() above.
  686          */
  687         if (gid != oldcred->cr_rgid &&          /* allow setgid(getgid()) */
  688 #ifdef _POSIX_SAVED_IDS
  689             gid != oldcred->cr_svgid &&         /* allow setgid(saved gid) */
  690 #endif
  691 #ifdef POSIX_APPENDIX_B_4_2_2   /* Use BSD-compat clause from B.4.2.2 */
  692             gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */
  693 #endif
  694             (error = priv_check_cred(oldcred, PRIV_CRED_SETGID)) != 0)
  695                 goto fail;
  696 
  697 #ifdef _POSIX_SAVED_IDS
  698         /*
  699          * Do we have "appropriate privileges" (are we root or gid == egid)
  700          * If so, we are changing the real uid and saved gid.
  701          */
  702         if (
  703 #ifdef POSIX_APPENDIX_B_4_2_2   /* use the clause from B.4.2.2 */
  704             gid == oldcred->cr_groups[0] ||
  705 #endif
  706             /* We are using privs. */
  707             priv_check_cred(oldcred, PRIV_CRED_SETGID) == 0)
  708 #endif
  709         {
  710                 /*
  711                  * Set real gid
  712                  */
  713                 if (oldcred->cr_rgid != gid) {
  714                         change_rgid(newcred, gid);
  715                         setsugid(p);
  716                 }
  717                 /*
  718                  * Set saved gid
  719                  *
  720                  * XXX always set saved gid even if not _POSIX_SAVED_IDS, as
  721                  * the security of setegid() depends on it.  B.4.2.2 says it
  722                  * is important that we should do this.
  723                  */
  724                 if (oldcred->cr_svgid != gid) {
  725                         change_svgid(newcred, gid);
  726                         setsugid(p);
  727                 }
  728         }
  729         /*
  730          * In all cases permitted cases, we are changing the egid.
  731          * Copy credentials so other references do not see our changes.
  732          */
  733         if (oldcred->cr_groups[0] != gid) {
  734                 change_egid(newcred, gid);
  735                 setsugid(p);
  736         }
  737         proc_set_cred(p, newcred);
  738         PROC_UNLOCK(p);
  739         crfree(oldcred);
  740         return (0);
  741 
  742 fail:
  743         PROC_UNLOCK(p);
  744         crfree(newcred);
  745         return (error);
  746 }
  747 
  748 #ifndef _SYS_SYSPROTO_H_
  749 struct setegid_args {
  750         gid_t   egid;
  751 };
  752 #endif
  753 /* ARGSUSED */
  754 int
  755 sys_setegid(struct thread *td, struct setegid_args *uap)
  756 {
  757         struct proc *p = td->td_proc;
  758         struct ucred *newcred, *oldcred;
  759         gid_t egid;
  760         int error;
  761 
  762         egid = uap->egid;
  763         AUDIT_ARG_EGID(egid);
  764         newcred = crget();
  765         PROC_LOCK(p);
  766         oldcred = crcopysafe(p, newcred);
  767 
  768 #ifdef MAC
  769         error = mac_cred_check_setegid(oldcred, egid);
  770         if (error)
  771                 goto fail;
  772 #endif
  773 
  774         if (egid != oldcred->cr_rgid &&         /* allow setegid(getgid()) */
  775             egid != oldcred->cr_svgid &&        /* allow setegid(saved gid) */
  776             (error = priv_check_cred(oldcred, PRIV_CRED_SETEGID)) != 0)
  777                 goto fail;
  778 
  779         if (oldcred->cr_groups[0] != egid) {
  780                 change_egid(newcred, egid);
  781                 setsugid(p);
  782         }
  783         proc_set_cred(p, newcred);
  784         PROC_UNLOCK(p);
  785         crfree(oldcred);
  786         return (0);
  787 
  788 fail:
  789         PROC_UNLOCK(p);
  790         crfree(newcred);
  791         return (error);
  792 }
  793 
  794 #ifndef _SYS_SYSPROTO_H_
  795 struct setgroups_args {
  796         int     gidsetsize;
  797         gid_t   *gidset;
  798 };
  799 #endif
  800 /* ARGSUSED */
  801 int
  802 sys_setgroups(struct thread *td, struct setgroups_args *uap)
  803 {
  804         gid_t smallgroups[XU_NGROUPS];
  805         gid_t *groups;
  806         int gidsetsize, error;
  807 
  808         gidsetsize = uap->gidsetsize;
  809         if (gidsetsize > ngroups_max + 1 || gidsetsize < 0)
  810                 return (EINVAL);
  811 
  812         if (gidsetsize > XU_NGROUPS)
  813                 groups = malloc(gidsetsize * sizeof(gid_t), M_TEMP, M_WAITOK);
  814         else
  815                 groups = smallgroups;
  816 
  817         error = copyin(uap->gidset, groups, gidsetsize * sizeof(gid_t));
  818         if (error == 0)
  819                 error = kern_setgroups(td, gidsetsize, groups);
  820 
  821         if (gidsetsize > XU_NGROUPS)
  822                 free(groups, M_TEMP);
  823         return (error);
  824 }
  825 
  826 int
  827 kern_setgroups(struct thread *td, u_int ngrp, gid_t *groups)
  828 {
  829         struct proc *p = td->td_proc;
  830         struct ucred *newcred, *oldcred;
  831         int error;
  832 
  833         MPASS(ngrp <= ngroups_max + 1);
  834         AUDIT_ARG_GROUPSET(groups, ngrp);
  835         newcred = crget();
  836         crextend(newcred, ngrp);
  837         PROC_LOCK(p);
  838         oldcred = crcopysafe(p, newcred);
  839 
  840 #ifdef MAC
  841         error = mac_cred_check_setgroups(oldcred, ngrp, groups);
  842         if (error)
  843                 goto fail;
  844 #endif
  845 
  846         error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS);
  847         if (error)
  848                 goto fail;
  849 
  850         if (ngrp == 0) {
  851                 /*
  852                  * setgroups(0, NULL) is a legitimate way of clearing the
  853                  * groups vector on non-BSD systems (which generally do not
  854                  * have the egid in the groups[0]).  We risk security holes
  855                  * when running non-BSD software if we do not do the same.
  856                  */
  857                 newcred->cr_ngroups = 1;
  858         } else {
  859                 crsetgroups_locked(newcred, ngrp, groups);
  860         }
  861         setsugid(p);
  862         proc_set_cred(p, newcred);
  863         PROC_UNLOCK(p);
  864         crfree(oldcred);
  865         return (0);
  866 
  867 fail:
  868         PROC_UNLOCK(p);
  869         crfree(newcred);
  870         return (error);
  871 }
  872 
  873 #ifndef _SYS_SYSPROTO_H_
  874 struct setreuid_args {
  875         uid_t   ruid;
  876         uid_t   euid;
  877 };
  878 #endif
  879 /* ARGSUSED */
  880 int
  881 sys_setreuid(struct thread *td, struct setreuid_args *uap)
  882 {
  883         struct proc *p = td->td_proc;
  884         struct ucred *newcred, *oldcred;
  885         uid_t euid, ruid;
  886         struct uidinfo *euip, *ruip;
  887         int error;
  888 
  889         euid = uap->euid;
  890         ruid = uap->ruid;
  891         AUDIT_ARG_EUID(euid);
  892         AUDIT_ARG_RUID(ruid);
  893         newcred = crget();
  894         euip = uifind(euid);
  895         ruip = uifind(ruid);
  896         PROC_LOCK(p);
  897         oldcred = crcopysafe(p, newcred);
  898 
  899 #ifdef MAC
  900         error = mac_cred_check_setreuid(oldcred, ruid, euid);
  901         if (error)
  902                 goto fail;
  903 #endif
  904 
  905         if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid &&
  906               ruid != oldcred->cr_svuid) ||
  907              (euid != (uid_t)-1 && euid != oldcred->cr_uid &&
  908               euid != oldcred->cr_ruid && euid != oldcred->cr_svuid)) &&
  909             (error = priv_check_cred(oldcred, PRIV_CRED_SETREUID)) != 0)
  910                 goto fail;
  911 
  912         if (euid != (uid_t)-1 && oldcred->cr_uid != euid) {
  913                 change_euid(newcred, euip);
  914                 setsugid(p);
  915         }
  916         if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) {
  917                 change_ruid(newcred, ruip);
  918                 setsugid(p);
  919         }
  920         if ((ruid != (uid_t)-1 || newcred->cr_uid != newcred->cr_ruid) &&
  921             newcred->cr_svuid != newcred->cr_uid) {
  922                 change_svuid(newcred, newcred->cr_uid);
  923                 setsugid(p);
  924         }
  925         proc_set_cred(p, newcred);
  926 #ifdef RACCT
  927         racct_proc_ucred_changed(p, oldcred, newcred);
  928         crhold(newcred);
  929 #endif
  930         PROC_UNLOCK(p);
  931 #ifdef RCTL
  932         rctl_proc_ucred_changed(p, newcred);
  933         crfree(newcred);
  934 #endif
  935         uifree(ruip);
  936         uifree(euip);
  937         crfree(oldcred);
  938         return (0);
  939 
  940 fail:
  941         PROC_UNLOCK(p);
  942         uifree(ruip);
  943         uifree(euip);
  944         crfree(newcred);
  945         return (error);
  946 }
  947 
  948 #ifndef _SYS_SYSPROTO_H_
  949 struct setregid_args {
  950         gid_t   rgid;
  951         gid_t   egid;
  952 };
  953 #endif
  954 /* ARGSUSED */
  955 int
  956 sys_setregid(struct thread *td, struct setregid_args *uap)
  957 {
  958         struct proc *p = td->td_proc;
  959         struct ucred *newcred, *oldcred;
  960         gid_t egid, rgid;
  961         int error;
  962 
  963         egid = uap->egid;
  964         rgid = uap->rgid;
  965         AUDIT_ARG_EGID(egid);
  966         AUDIT_ARG_RGID(rgid);
  967         newcred = crget();
  968         PROC_LOCK(p);
  969         oldcred = crcopysafe(p, newcred);
  970 
  971 #ifdef MAC
  972         error = mac_cred_check_setregid(oldcred, rgid, egid);
  973         if (error)
  974                 goto fail;
  975 #endif
  976 
  977         if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid &&
  978             rgid != oldcred->cr_svgid) ||
  979              (egid != (gid_t)-1 && egid != oldcred->cr_groups[0] &&
  980              egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) &&
  981             (error = priv_check_cred(oldcred, PRIV_CRED_SETREGID)) != 0)
  982                 goto fail;
  983 
  984         if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) {
  985                 change_egid(newcred, egid);
  986                 setsugid(p);
  987         }
  988         if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) {
  989                 change_rgid(newcred, rgid);
  990                 setsugid(p);
  991         }
  992         if ((rgid != (gid_t)-1 || newcred->cr_groups[0] != newcred->cr_rgid) &&
  993             newcred->cr_svgid != newcred->cr_groups[0]) {
  994                 change_svgid(newcred, newcred->cr_groups[0]);
  995                 setsugid(p);
  996         }
  997         proc_set_cred(p, newcred);
  998         PROC_UNLOCK(p);
  999         crfree(oldcred);
 1000         return (0);
 1001 
 1002 fail:
 1003         PROC_UNLOCK(p);
 1004         crfree(newcred);
 1005         return (error);
 1006 }
 1007 
 1008 /*
 1009  * setresuid(ruid, euid, suid) is like setreuid except control over the saved
 1010  * uid is explicit.
 1011  */
 1012 #ifndef _SYS_SYSPROTO_H_
 1013 struct setresuid_args {
 1014         uid_t   ruid;
 1015         uid_t   euid;
 1016         uid_t   suid;
 1017 };
 1018 #endif
 1019 /* ARGSUSED */
 1020 int
 1021 sys_setresuid(struct thread *td, struct setresuid_args *uap)
 1022 {
 1023         struct proc *p = td->td_proc;
 1024         struct ucred *newcred, *oldcred;
 1025         uid_t euid, ruid, suid;
 1026         struct uidinfo *euip, *ruip;
 1027         int error;
 1028 
 1029         euid = uap->euid;
 1030         ruid = uap->ruid;
 1031         suid = uap->suid;
 1032         AUDIT_ARG_EUID(euid);
 1033         AUDIT_ARG_RUID(ruid);
 1034         AUDIT_ARG_SUID(suid);
 1035         newcred = crget();
 1036         euip = uifind(euid);
 1037         ruip = uifind(ruid);
 1038         PROC_LOCK(p);
 1039         oldcred = crcopysafe(p, newcred);
 1040 
 1041 #ifdef MAC
 1042         error = mac_cred_check_setresuid(oldcred, ruid, euid, suid);
 1043         if (error)
 1044                 goto fail;
 1045 #endif
 1046 
 1047         if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid &&
 1048              ruid != oldcred->cr_svuid &&
 1049               ruid != oldcred->cr_uid) ||
 1050              (euid != (uid_t)-1 && euid != oldcred->cr_ruid &&
 1051             euid != oldcred->cr_svuid &&
 1052               euid != oldcred->cr_uid) ||
 1053              (suid != (uid_t)-1 && suid != oldcred->cr_ruid &&
 1054             suid != oldcred->cr_svuid &&
 1055               suid != oldcred->cr_uid)) &&
 1056             (error = priv_check_cred(oldcred, PRIV_CRED_SETRESUID)) != 0)
 1057                 goto fail;
 1058 
 1059         if (euid != (uid_t)-1 && oldcred->cr_uid != euid) {
 1060                 change_euid(newcred, euip);
 1061                 setsugid(p);
 1062         }
 1063         if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) {
 1064                 change_ruid(newcred, ruip);
 1065                 setsugid(p);
 1066         }
 1067         if (suid != (uid_t)-1 && oldcred->cr_svuid != suid) {
 1068                 change_svuid(newcred, suid);
 1069                 setsugid(p);
 1070         }
 1071         proc_set_cred(p, newcred);
 1072 #ifdef RACCT
 1073         racct_proc_ucred_changed(p, oldcred, newcred);
 1074         crhold(newcred);
 1075 #endif
 1076         PROC_UNLOCK(p);
 1077 #ifdef RCTL
 1078         rctl_proc_ucred_changed(p, newcred);
 1079         crfree(newcred);
 1080 #endif
 1081         uifree(ruip);
 1082         uifree(euip);
 1083         crfree(oldcred);
 1084         return (0);
 1085 
 1086 fail:
 1087         PROC_UNLOCK(p);
 1088         uifree(ruip);
 1089         uifree(euip);
 1090         crfree(newcred);
 1091         return (error);
 1092 
 1093 }
 1094 
 1095 /*
 1096  * setresgid(rgid, egid, sgid) is like setregid except control over the saved
 1097  * gid is explicit.
 1098  */
 1099 #ifndef _SYS_SYSPROTO_H_
 1100 struct setresgid_args {
 1101         gid_t   rgid;
 1102         gid_t   egid;
 1103         gid_t   sgid;
 1104 };
 1105 #endif
 1106 /* ARGSUSED */
 1107 int
 1108 sys_setresgid(struct thread *td, struct setresgid_args *uap)
 1109 {
 1110         struct proc *p = td->td_proc;
 1111         struct ucred *newcred, *oldcred;
 1112         gid_t egid, rgid, sgid;
 1113         int error;
 1114 
 1115         egid = uap->egid;
 1116         rgid = uap->rgid;
 1117         sgid = uap->sgid;
 1118         AUDIT_ARG_EGID(egid);
 1119         AUDIT_ARG_RGID(rgid);
 1120         AUDIT_ARG_SGID(sgid);
 1121         newcred = crget();
 1122         PROC_LOCK(p);
 1123         oldcred = crcopysafe(p, newcred);
 1124 
 1125 #ifdef MAC
 1126         error = mac_cred_check_setresgid(oldcred, rgid, egid, sgid);
 1127         if (error)
 1128                 goto fail;
 1129 #endif
 1130 
 1131         if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid &&
 1132               rgid != oldcred->cr_svgid &&
 1133               rgid != oldcred->cr_groups[0]) ||
 1134              (egid != (gid_t)-1 && egid != oldcred->cr_rgid &&
 1135               egid != oldcred->cr_svgid &&
 1136               egid != oldcred->cr_groups[0]) ||
 1137              (sgid != (gid_t)-1 && sgid != oldcred->cr_rgid &&
 1138               sgid != oldcred->cr_svgid &&
 1139               sgid != oldcred->cr_groups[0])) &&
 1140             (error = priv_check_cred(oldcred, PRIV_CRED_SETRESGID)) != 0)
 1141                 goto fail;
 1142 
 1143         if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) {
 1144                 change_egid(newcred, egid);
 1145                 setsugid(p);
 1146         }
 1147         if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) {
 1148                 change_rgid(newcred, rgid);
 1149                 setsugid(p);
 1150         }
 1151         if (sgid != (gid_t)-1 && oldcred->cr_svgid != sgid) {
 1152                 change_svgid(newcred, sgid);
 1153                 setsugid(p);
 1154         }
 1155         proc_set_cred(p, newcred);
 1156         PROC_UNLOCK(p);
 1157         crfree(oldcred);
 1158         return (0);
 1159 
 1160 fail:
 1161         PROC_UNLOCK(p);
 1162         crfree(newcred);
 1163         return (error);
 1164 }
 1165 
 1166 #ifndef _SYS_SYSPROTO_H_
 1167 struct getresuid_args {
 1168         uid_t   *ruid;
 1169         uid_t   *euid;
 1170         uid_t   *suid;
 1171 };
 1172 #endif
 1173 /* ARGSUSED */
 1174 int
 1175 sys_getresuid(struct thread *td, struct getresuid_args *uap)
 1176 {
 1177         struct ucred *cred;
 1178         int error1 = 0, error2 = 0, error3 = 0;
 1179 
 1180         cred = td->td_ucred;
 1181         if (uap->ruid)
 1182                 error1 = copyout(&cred->cr_ruid,
 1183                     uap->ruid, sizeof(cred->cr_ruid));
 1184         if (uap->euid)
 1185                 error2 = copyout(&cred->cr_uid,
 1186                     uap->euid, sizeof(cred->cr_uid));
 1187         if (uap->suid)
 1188                 error3 = copyout(&cred->cr_svuid,
 1189                     uap->suid, sizeof(cred->cr_svuid));
 1190         return (error1 ? error1 : error2 ? error2 : error3);
 1191 }
 1192 
 1193 #ifndef _SYS_SYSPROTO_H_
 1194 struct getresgid_args {
 1195         gid_t   *rgid;
 1196         gid_t   *egid;
 1197         gid_t   *sgid;
 1198 };
 1199 #endif
 1200 /* ARGSUSED */
 1201 int
 1202 sys_getresgid(struct thread *td, struct getresgid_args *uap)
 1203 {
 1204         struct ucred *cred;
 1205         int error1 = 0, error2 = 0, error3 = 0;
 1206 
 1207         cred = td->td_ucred;
 1208         if (uap->rgid)
 1209                 error1 = copyout(&cred->cr_rgid,
 1210                     uap->rgid, sizeof(cred->cr_rgid));
 1211         if (uap->egid)
 1212                 error2 = copyout(&cred->cr_groups[0],
 1213                     uap->egid, sizeof(cred->cr_groups[0]));
 1214         if (uap->sgid)
 1215                 error3 = copyout(&cred->cr_svgid,
 1216                     uap->sgid, sizeof(cred->cr_svgid));
 1217         return (error1 ? error1 : error2 ? error2 : error3);
 1218 }
 1219 
 1220 #ifndef _SYS_SYSPROTO_H_
 1221 struct issetugid_args {
 1222         int dummy;
 1223 };
 1224 #endif
 1225 /* ARGSUSED */
 1226 int
 1227 sys_issetugid(struct thread *td, struct issetugid_args *uap)
 1228 {
 1229         struct proc *p = td->td_proc;
 1230 
 1231         /*
 1232          * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time,
 1233          * we use P_SUGID because we consider changing the owners as
 1234          * "tainting" as well.
 1235          * This is significant for procs that start as root and "become"
 1236          * a user without an exec - programs cannot know *everything*
 1237          * that libc *might* have put in their data segment.
 1238          */
 1239         td->td_retval[0] = (p->p_flag & P_SUGID) ? 1 : 0;
 1240         return (0);
 1241 }
 1242 
 1243 int
 1244 sys___setugid(struct thread *td, struct __setugid_args *uap)
 1245 {
 1246 #ifdef REGRESSION
 1247         struct proc *p;
 1248 
 1249         p = td->td_proc;
 1250         switch (uap->flag) {
 1251         case 0:
 1252                 PROC_LOCK(p);
 1253                 p->p_flag &= ~P_SUGID;
 1254                 PROC_UNLOCK(p);
 1255                 return (0);
 1256         case 1:
 1257                 PROC_LOCK(p);
 1258                 p->p_flag |= P_SUGID;
 1259                 PROC_UNLOCK(p);
 1260                 return (0);
 1261         default:
 1262                 return (EINVAL);
 1263         }
 1264 #else /* !REGRESSION */
 1265 
 1266         return (ENOSYS);
 1267 #endif /* REGRESSION */
 1268 }
 1269 
 1270 /*
 1271  * Check if gid is a member of the group set.
 1272  */
 1273 int
 1274 groupmember(gid_t gid, struct ucred *cred)
 1275 {
 1276         int l;
 1277         int h;
 1278         int m;
 1279 
 1280         if (cred->cr_groups[0] == gid)
 1281                 return(1);
 1282 
 1283         /*
 1284          * If gid was not our primary group, perform a binary search
 1285          * of the supplemental groups.  This is possible because we
 1286          * sort the groups in crsetgroups().
 1287          */
 1288         l = 1;
 1289         h = cred->cr_ngroups;
 1290         while (l < h) {
 1291                 m = l + ((h - l) / 2);
 1292                 if (cred->cr_groups[m] < gid)
 1293                         l = m + 1; 
 1294                 else
 1295                         h = m; 
 1296         }
 1297         if ((l < cred->cr_ngroups) && (cred->cr_groups[l] == gid))
 1298                 return (1);
 1299 
 1300         return (0);
 1301 }
 1302 
 1303 /*
 1304  * Test the active securelevel against a given level.  securelevel_gt()
 1305  * implements (securelevel > level).  securelevel_ge() implements
 1306  * (securelevel >= level).  Note that the logic is inverted -- these
 1307  * functions return EPERM on "success" and 0 on "failure".
 1308  *
 1309  * Due to care taken when setting the securelevel, we know that no jail will
 1310  * be less secure that its parent (or the physical system), so it is sufficient
 1311  * to test the current jail only.
 1312  *
 1313  * XXXRW: Possibly since this has to do with privilege, it should move to
 1314  * kern_priv.c.
 1315  */
 1316 int
 1317 securelevel_gt(struct ucred *cr, int level)
 1318 {
 1319 
 1320         return (cr->cr_prison->pr_securelevel > level ? EPERM : 0);
 1321 }
 1322 
 1323 int
 1324 securelevel_ge(struct ucred *cr, int level)
 1325 {
 1326 
 1327         return (cr->cr_prison->pr_securelevel >= level ? EPERM : 0);
 1328 }
 1329 
 1330 /*
 1331  * 'see_other_uids' determines whether or not visibility of processes
 1332  * and sockets with credentials holding different real uids is possible
 1333  * using a variety of system MIBs.
 1334  * XXX: data declarations should be together near the beginning of the file.
 1335  */
 1336 static int      see_other_uids = 1;
 1337 SYSCTL_INT(_security_bsd, OID_AUTO, see_other_uids, CTLFLAG_RW,
 1338     &see_other_uids, 0,
 1339     "Unprivileged processes may see subjects/objects with different real uid");
 1340 
 1341 /*-
 1342  * Determine if u1 "can see" the subject specified by u2, according to the
 1343  * 'see_other_uids' policy.
 1344  * Returns: 0 for permitted, ESRCH otherwise
 1345  * Locks: none
 1346  * References: *u1 and *u2 must not change during the call
 1347  *             u1 may equal u2, in which case only one reference is required
 1348  */
 1349 int
 1350 cr_canseeotheruids(struct ucred *u1, struct ucred *u2)
 1351 {
 1352 
 1353         if (!see_other_uids && u1->cr_ruid != u2->cr_ruid) {
 1354                 if (priv_check_cred(u1, PRIV_SEEOTHERUIDS) != 0)
 1355                         return (ESRCH);
 1356         }
 1357         return (0);
 1358 }
 1359 
 1360 /*
 1361  * 'see_other_gids' determines whether or not visibility of processes
 1362  * and sockets with credentials holding different real gids is possible
 1363  * using a variety of system MIBs.
 1364  * XXX: data declarations should be together near the beginning of the file.
 1365  */
 1366 static int      see_other_gids = 1;
 1367 SYSCTL_INT(_security_bsd, OID_AUTO, see_other_gids, CTLFLAG_RW,
 1368     &see_other_gids, 0,
 1369     "Unprivileged processes may see subjects/objects with different real gid");
 1370 
 1371 /*
 1372  * Determine if u1 can "see" the subject specified by u2, according to the
 1373  * 'see_other_gids' policy.
 1374  * Returns: 0 for permitted, ESRCH otherwise
 1375  * Locks: none
 1376  * References: *u1 and *u2 must not change during the call
 1377  *             u1 may equal u2, in which case only one reference is required
 1378  */
 1379 int
 1380 cr_canseeothergids(struct ucred *u1, struct ucred *u2)
 1381 {
 1382         int i, match;
 1383 
 1384         if (!see_other_gids) {
 1385                 match = 0;
 1386                 for (i = 0; i < u1->cr_ngroups; i++) {
 1387                         if (groupmember(u1->cr_groups[i], u2))
 1388                                 match = 1;
 1389                         if (match)
 1390                                 break;
 1391                 }
 1392                 if (!match) {
 1393                         if (priv_check_cred(u1, PRIV_SEEOTHERGIDS) != 0)
 1394                                 return (ESRCH);
 1395                 }
 1396         }
 1397         return (0);
 1398 }
 1399 
 1400 /*
 1401  * 'see_jail_proc' determines whether or not visibility of processes and
 1402  * sockets with credentials holding different jail ids is possible using a
 1403  * variety of system MIBs.
 1404  *
 1405  * XXX: data declarations should be together near the beginning of the file.
 1406  */
 1407 
 1408 static int      see_jail_proc = 1;
 1409 SYSCTL_INT(_security_bsd, OID_AUTO, see_jail_proc, CTLFLAG_RW,
 1410     &see_jail_proc, 0,
 1411     "Unprivileged processes may see subjects/objects with different jail ids");
 1412 
 1413 /*-
 1414  * Determine if u1 "can see" the subject specified by u2, according to the
 1415  * 'see_jail_proc' policy.
 1416  * Returns: 0 for permitted, ESRCH otherwise
 1417  * Locks: none
 1418  * References: *u1 and *u2 must not change during the call
 1419  *             u1 may equal u2, in which case only one reference is required
 1420  */
 1421 int
 1422 cr_canseejailproc(struct ucred *u1, struct ucred *u2)
 1423 {
 1424         if (u1->cr_uid == 0)
 1425                 return (0);
 1426         return (!see_jail_proc && u1->cr_prison != u2->cr_prison ? ESRCH : 0);
 1427 }
 1428 
 1429 /*-
 1430  * Determine if u1 "can see" the subject specified by u2.
 1431  * Returns: 0 for permitted, an errno value otherwise
 1432  * Locks: none
 1433  * References: *u1 and *u2 must not change during the call
 1434  *             u1 may equal u2, in which case only one reference is required
 1435  */
 1436 int
 1437 cr_cansee(struct ucred *u1, struct ucred *u2)
 1438 {
 1439         int error;
 1440 
 1441         if ((error = prison_check(u1, u2)))
 1442                 return (error);
 1443 #ifdef MAC
 1444         if ((error = mac_cred_check_visible(u1, u2)))
 1445                 return (error);
 1446 #endif
 1447         if ((error = cr_canseeotheruids(u1, u2)))
 1448                 return (error);
 1449         if ((error = cr_canseeothergids(u1, u2)))
 1450                 return (error);
 1451         if ((error = cr_canseejailproc(u1, u2)))
 1452                 return (error);
 1453         return (0);
 1454 }
 1455 
 1456 /*-
 1457  * Determine if td "can see" the subject specified by p.
 1458  * Returns: 0 for permitted, an errno value otherwise
 1459  * Locks: Sufficient locks to protect p->p_ucred must be held.  td really
 1460  *        should be curthread.
 1461  * References: td and p must be valid for the lifetime of the call
 1462  */
 1463 int
 1464 p_cansee(struct thread *td, struct proc *p)
 1465 {
 1466         /* Wrap cr_cansee() for all functionality. */
 1467         KASSERT(td == curthread, ("%s: td not curthread", __func__));
 1468         PROC_LOCK_ASSERT(p, MA_OWNED);
 1469 
 1470         if (td->td_proc == p)
 1471                 return (0);
 1472         return (cr_cansee(td->td_ucred, p->p_ucred));
 1473 }
 1474 
 1475 /*
 1476  * 'conservative_signals' prevents the delivery of a broad class of
 1477  * signals by unprivileged processes to processes that have changed their
 1478  * credentials since the last invocation of execve().  This can prevent
 1479  * the leakage of cached information or retained privileges as a result
 1480  * of a common class of signal-related vulnerabilities.  However, this
 1481  * may interfere with some applications that expect to be able to
 1482  * deliver these signals to peer processes after having given up
 1483  * privilege.
 1484  */
 1485 static int      conservative_signals = 1;
 1486 SYSCTL_INT(_security_bsd, OID_AUTO, conservative_signals, CTLFLAG_RW,
 1487     &conservative_signals, 0, "Unprivileged processes prevented from "
 1488     "sending certain signals to processes whose credentials have changed");
 1489 /*-
 1490  * Determine whether cred may deliver the specified signal to proc.
 1491  * Returns: 0 for permitted, an errno value otherwise.
 1492  * Locks: A lock must be held for proc.
 1493  * References: cred and proc must be valid for the lifetime of the call.
 1494  */
 1495 int
 1496 cr_cansignal(struct ucred *cred, struct proc *proc, int signum)
 1497 {
 1498         int error;
 1499 
 1500         PROC_LOCK_ASSERT(proc, MA_OWNED);
 1501         /*
 1502          * Jail semantics limit the scope of signalling to proc in the
 1503          * same jail as cred, if cred is in jail.
 1504          */
 1505         error = prison_check(cred, proc->p_ucred);
 1506         if (error)
 1507                 return (error);
 1508 #ifdef MAC
 1509         if ((error = mac_proc_check_signal(cred, proc, signum)))
 1510                 return (error);
 1511 #endif
 1512         if ((error = cr_canseeotheruids(cred, proc->p_ucred)))
 1513                 return (error);
 1514         if ((error = cr_canseeothergids(cred, proc->p_ucred)))
 1515                 return (error);
 1516 
 1517         /*
 1518          * UNIX signal semantics depend on the status of the P_SUGID
 1519          * bit on the target process.  If the bit is set, then additional
 1520          * restrictions are placed on the set of available signals.
 1521          */
 1522         if (conservative_signals && (proc->p_flag & P_SUGID)) {
 1523                 switch (signum) {
 1524                 case 0:
 1525                 case SIGKILL:
 1526                 case SIGINT:
 1527                 case SIGTERM:
 1528                 case SIGALRM:
 1529                 case SIGSTOP:
 1530                 case SIGTTIN:
 1531                 case SIGTTOU:
 1532                 case SIGTSTP:
 1533                 case SIGHUP:
 1534                 case SIGUSR1:
 1535                 case SIGUSR2:
 1536                         /*
 1537                          * Generally, permit job and terminal control
 1538                          * signals.
 1539                          */
 1540                         break;
 1541                 default:
 1542                         /* Not permitted without privilege. */
 1543                         error = priv_check_cred(cred, PRIV_SIGNAL_SUGID);
 1544                         if (error)
 1545                                 return (error);
 1546                 }
 1547         }
 1548 
 1549         /*
 1550          * Generally, the target credential's ruid or svuid must match the
 1551          * subject credential's ruid or euid.
 1552          */
 1553         if (cred->cr_ruid != proc->p_ucred->cr_ruid &&
 1554             cred->cr_ruid != proc->p_ucred->cr_svuid &&
 1555             cred->cr_uid != proc->p_ucred->cr_ruid &&
 1556             cred->cr_uid != proc->p_ucred->cr_svuid) {
 1557                 error = priv_check_cred(cred, PRIV_SIGNAL_DIFFCRED);
 1558                 if (error)
 1559                         return (error);
 1560         }
 1561 
 1562         return (0);
 1563 }
 1564 
 1565 /*-
 1566  * Determine whether td may deliver the specified signal to p.
 1567  * Returns: 0 for permitted, an errno value otherwise
 1568  * Locks: Sufficient locks to protect various components of td and p
 1569  *        must be held.  td must be curthread, and a lock must be
 1570  *        held for p.
 1571  * References: td and p must be valid for the lifetime of the call
 1572  */
 1573 int
 1574 p_cansignal(struct thread *td, struct proc *p, int signum)
 1575 {
 1576 
 1577         KASSERT(td == curthread, ("%s: td not curthread", __func__));
 1578         PROC_LOCK_ASSERT(p, MA_OWNED);
 1579         if (td->td_proc == p)
 1580                 return (0);
 1581 
 1582         /*
 1583          * UNIX signalling semantics require that processes in the same
 1584          * session always be able to deliver SIGCONT to one another,
 1585          * overriding the remaining protections.
 1586          */
 1587         /* XXX: This will require an additional lock of some sort. */
 1588         if (signum == SIGCONT && td->td_proc->p_session == p->p_session)
 1589                 return (0);
 1590         /*
 1591          * Some compat layers use SIGTHR and higher signals for
 1592          * communication between different kernel threads of the same
 1593          * process, so that they expect that it's always possible to
 1594          * deliver them, even for suid applications where cr_cansignal() can
 1595          * deny such ability for security consideration.  It should be
 1596          * pretty safe to do since the only way to create two processes
 1597          * with the same p_leader is via rfork(2).
 1598          */
 1599         if (td->td_proc->p_leader != NULL && signum >= SIGTHR &&
 1600             signum < SIGTHR + 4 && td->td_proc->p_leader == p->p_leader)
 1601                 return (0);
 1602 
 1603         return (cr_cansignal(td->td_ucred, p, signum));
 1604 }
 1605 
 1606 /*-
 1607  * Determine whether td may reschedule p.
 1608  * Returns: 0 for permitted, an errno value otherwise
 1609  * Locks: Sufficient locks to protect various components of td and p
 1610  *        must be held.  td must be curthread, and a lock must
 1611  *        be held for p.
 1612  * References: td and p must be valid for the lifetime of the call
 1613  */
 1614 int
 1615 p_cansched(struct thread *td, struct proc *p)
 1616 {
 1617         int error;
 1618 
 1619         KASSERT(td == curthread, ("%s: td not curthread", __func__));
 1620         PROC_LOCK_ASSERT(p, MA_OWNED);
 1621         if (td->td_proc == p)
 1622                 return (0);
 1623         if ((error = prison_check(td->td_ucred, p->p_ucred)))
 1624                 return (error);
 1625 #ifdef MAC
 1626         if ((error = mac_proc_check_sched(td->td_ucred, p)))
 1627                 return (error);
 1628 #endif
 1629         if ((error = cr_canseeotheruids(td->td_ucred, p->p_ucred)))
 1630                 return (error);
 1631         if ((error = cr_canseeothergids(td->td_ucred, p->p_ucred)))
 1632                 return (error);
 1633         if (td->td_ucred->cr_ruid != p->p_ucred->cr_ruid &&
 1634             td->td_ucred->cr_uid != p->p_ucred->cr_ruid) {
 1635                 error = priv_check(td, PRIV_SCHED_DIFFCRED);
 1636                 if (error)
 1637                         return (error);
 1638         }
 1639         return (0);
 1640 }
 1641 
 1642 /*
 1643  * Handle getting or setting the prison's unprivileged_proc_debug
 1644  * value.
 1645  */
 1646 static int
 1647 sysctl_unprivileged_proc_debug(SYSCTL_HANDLER_ARGS)
 1648 {
 1649         int error, val;
 1650 
 1651         val = prison_allow(req->td->td_ucred, PR_ALLOW_UNPRIV_DEBUG);
 1652         error = sysctl_handle_int(oidp, &val, 0, req);
 1653         if (error != 0 || req->newptr == NULL)
 1654                 return (error);
 1655         if (val != 0 && val != 1)
 1656                 return (EINVAL);
 1657         prison_set_allow(req->td->td_ucred, PR_ALLOW_UNPRIV_DEBUG, val);
 1658         return (0);
 1659 }
 1660 
 1661 /*
 1662  * The 'unprivileged_proc_debug' flag may be used to disable a variety of
 1663  * unprivileged inter-process debugging services, including some procfs
 1664  * functionality, ptrace(), and ktrace().  In the past, inter-process
 1665  * debugging has been involved in a variety of security problems, and sites
 1666  * not requiring the service might choose to disable it when hardening
 1667  * systems.
 1668  */
 1669 SYSCTL_PROC(_security_bsd, OID_AUTO, unprivileged_proc_debug,
 1670     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_SECURE |
 1671     CTLFLAG_MPSAFE, 0, 0, sysctl_unprivileged_proc_debug, "I",
 1672     "Unprivileged processes may use process debugging facilities");
 1673 
 1674 /*-
 1675  * Determine whether td may debug p.
 1676  * Returns: 0 for permitted, an errno value otherwise
 1677  * Locks: Sufficient locks to protect various components of td and p
 1678  *        must be held.  td must be curthread, and a lock must
 1679  *        be held for p.
 1680  * References: td and p must be valid for the lifetime of the call
 1681  */
 1682 int
 1683 p_candebug(struct thread *td, struct proc *p)
 1684 {
 1685         int credentialchanged, error, grpsubset, i, uidsubset;
 1686 
 1687         KASSERT(td == curthread, ("%s: td not curthread", __func__));
 1688         PROC_LOCK_ASSERT(p, MA_OWNED);
 1689         if (td->td_proc == p)
 1690                 return (0);
 1691         if ((error = priv_check(td, PRIV_DEBUG_UNPRIV)))
 1692                 return (error);
 1693         if ((error = prison_check(td->td_ucred, p->p_ucred)))
 1694                 return (error);
 1695 #ifdef MAC
 1696         if ((error = mac_proc_check_debug(td->td_ucred, p)))
 1697                 return (error);
 1698 #endif
 1699         if ((error = cr_canseeotheruids(td->td_ucred, p->p_ucred)))
 1700                 return (error);
 1701         if ((error = cr_canseeothergids(td->td_ucred, p->p_ucred)))
 1702                 return (error);
 1703 
 1704         /*
 1705          * Is p's group set a subset of td's effective group set?  This
 1706          * includes p's egid, group access list, rgid, and svgid.
 1707          */
 1708         grpsubset = 1;
 1709         for (i = 0; i < p->p_ucred->cr_ngroups; i++) {
 1710                 if (!groupmember(p->p_ucred->cr_groups[i], td->td_ucred)) {
 1711                         grpsubset = 0;
 1712                         break;
 1713                 }
 1714         }
 1715         grpsubset = grpsubset &&
 1716             groupmember(p->p_ucred->cr_rgid, td->td_ucred) &&
 1717             groupmember(p->p_ucred->cr_svgid, td->td_ucred);
 1718 
 1719         /*
 1720          * Are the uids present in p's credential equal to td's
 1721          * effective uid?  This includes p's euid, svuid, and ruid.
 1722          */
 1723         uidsubset = (td->td_ucred->cr_uid == p->p_ucred->cr_uid &&
 1724             td->td_ucred->cr_uid == p->p_ucred->cr_svuid &&
 1725             td->td_ucred->cr_uid == p->p_ucred->cr_ruid);
 1726 
 1727         /*
 1728          * Has the credential of the process changed since the last exec()?
 1729          */
 1730         credentialchanged = (p->p_flag & P_SUGID);
 1731 
 1732         /*
 1733          * If p's gids aren't a subset, or the uids aren't a subset,
 1734          * or the credential has changed, require appropriate privilege
 1735          * for td to debug p.
 1736          */
 1737         if (!grpsubset || !uidsubset) {
 1738                 error = priv_check(td, PRIV_DEBUG_DIFFCRED);
 1739                 if (error)
 1740                         return (error);
 1741         }
 1742 
 1743         if (credentialchanged) {
 1744                 error = priv_check(td, PRIV_DEBUG_SUGID);
 1745                 if (error)
 1746                         return (error);
 1747         }
 1748 
 1749         /* Can't trace init when securelevel > 0. */
 1750         if (p == initproc) {
 1751                 error = securelevel_gt(td->td_ucred, 0);
 1752                 if (error)
 1753                         return (error);
 1754         }
 1755 
 1756         /*
 1757          * Can't trace a process that's currently exec'ing.
 1758          *
 1759          * XXX: Note, this is not a security policy decision, it's a
 1760          * basic correctness/functionality decision.  Therefore, this check
 1761          * should be moved to the caller's of p_candebug().
 1762          */
 1763         if ((p->p_flag & P_INEXEC) != 0)
 1764                 return (EBUSY);
 1765 
 1766         /* Denied explicitly */
 1767         if ((p->p_flag2 & P2_NOTRACE) != 0) {
 1768                 error = priv_check(td, PRIV_DEBUG_DENIED);
 1769                 if (error != 0)
 1770                         return (error);
 1771         }
 1772 
 1773         return (0);
 1774 }
 1775 
 1776 /*-
 1777  * Determine whether the subject represented by cred can "see" a socket.
 1778  * Returns: 0 for permitted, ENOENT otherwise.
 1779  */
 1780 int
 1781 cr_canseesocket(struct ucred *cred, struct socket *so)
 1782 {
 1783         int error;
 1784 
 1785         error = prison_check(cred, so->so_cred);
 1786         if (error)
 1787                 return (ENOENT);
 1788 #ifdef MAC
 1789         error = mac_socket_check_visible(cred, so);
 1790         if (error)
 1791                 return (error);
 1792 #endif
 1793         if (cr_canseeotheruids(cred, so->so_cred))
 1794                 return (ENOENT);
 1795         if (cr_canseeothergids(cred, so->so_cred))
 1796                 return (ENOENT);
 1797 
 1798         return (0);
 1799 }
 1800 
 1801 /*-
 1802  * Determine whether td can wait for the exit of p.
 1803  * Returns: 0 for permitted, an errno value otherwise
 1804  * Locks: Sufficient locks to protect various components of td and p
 1805  *        must be held.  td must be curthread, and a lock must
 1806  *        be held for p.
 1807  * References: td and p must be valid for the lifetime of the call
 1808 
 1809  */
 1810 int
 1811 p_canwait(struct thread *td, struct proc *p)
 1812 {
 1813         int error;
 1814 
 1815         KASSERT(td == curthread, ("%s: td not curthread", __func__));
 1816         PROC_LOCK_ASSERT(p, MA_OWNED);
 1817         if ((error = prison_check(td->td_ucred, p->p_ucred)))
 1818                 return (error);
 1819 #ifdef MAC
 1820         if ((error = mac_proc_check_wait(td->td_ucred, p)))
 1821                 return (error);
 1822 #endif
 1823 #if 0
 1824         /* XXXMAC: This could have odd effects on some shells. */
 1825         if ((error = cr_canseeotheruids(td->td_ucred, p->p_ucred)))
 1826                 return (error);
 1827 #endif
 1828 
 1829         return (0);
 1830 }
 1831 
 1832 /*
 1833  * Credential management.
 1834  *
 1835  * struct ucred objects are rarely allocated but gain and lose references all
 1836  * the time (e.g., on struct file alloc/dealloc) turning refcount updates into
 1837  * a significant source of cache-line ping ponging. Common cases are worked
 1838  * around by modifying thread-local counter instead if the cred to operate on
 1839  * matches td_realucred.
 1840  *
 1841  * The counter is split into 2 parts:
 1842  * - cr_users -- total count of all struct proc and struct thread objects
 1843  *   which have given cred in p_ucred and td_ucred respectively
 1844  * - cr_ref -- the actual ref count, only valid if cr_users == 0
 1845  *
 1846  * If users == 0 then cr_ref behaves similarly to refcount(9), in particular if
 1847  * the count reaches 0 the object is freeable.
 1848  * If users > 0 and curthread->td_realucred == cred, then updates are performed
 1849  * against td_ucredref.
 1850  * In other cases updates are performed against cr_ref.
 1851  *
 1852  * Changing td_realucred into something else decrements cr_users and transfers
 1853  * accumulated updates.
 1854  */
 1855 struct ucred *
 1856 crcowget(struct ucred *cr)
 1857 {
 1858 
 1859         mtx_lock(&cr->cr_mtx);
 1860         KASSERT(cr->cr_users > 0, ("%s: users %d not > 0 on cred %p",
 1861             __func__, cr->cr_users, cr));
 1862         cr->cr_users++;
 1863         cr->cr_ref++;
 1864         mtx_unlock(&cr->cr_mtx);
 1865         return (cr);
 1866 }
 1867 
 1868 static struct ucred *
 1869 crunuse(struct thread *td)
 1870 {
 1871         struct ucred *cr, *crold;
 1872 
 1873         MPASS(td->td_realucred == td->td_ucred);
 1874         cr = td->td_realucred;
 1875         mtx_lock(&cr->cr_mtx);
 1876         cr->cr_ref += td->td_ucredref;
 1877         td->td_ucredref = 0;
 1878         KASSERT(cr->cr_users > 0, ("%s: users %d not > 0 on cred %p",
 1879             __func__, cr->cr_users, cr));
 1880         cr->cr_users--;
 1881         if (cr->cr_users == 0) {
 1882                 KASSERT(cr->cr_ref > 0, ("%s: ref %d not > 0 on cred %p",
 1883                     __func__, cr->cr_ref, cr));
 1884                 crold = cr;
 1885         } else {
 1886                 cr->cr_ref--;
 1887                 crold = NULL;
 1888         }
 1889         mtx_unlock(&cr->cr_mtx);
 1890         td->td_realucred = NULL;
 1891         return (crold);
 1892 }
 1893 
 1894 static void
 1895 crunusebatch(struct ucred *cr, int users, int ref)
 1896 {
 1897 
 1898         KASSERT(users > 0, ("%s: passed users %d not > 0 ; cred %p",
 1899             __func__, users, cr));
 1900         mtx_lock(&cr->cr_mtx);
 1901         KASSERT(cr->cr_users >= users, ("%s: users %d not > %d on cred %p",
 1902             __func__, cr->cr_users, users, cr));
 1903         cr->cr_users -= users;
 1904         cr->cr_ref += ref;
 1905         cr->cr_ref -= users;
 1906         if (cr->cr_users > 0) {
 1907                 mtx_unlock(&cr->cr_mtx);
 1908                 return;
 1909         }
 1910         KASSERT(cr->cr_ref >= 0, ("%s: ref %d not >= 0 on cred %p",
 1911             __func__, cr->cr_ref, cr));
 1912         if (cr->cr_ref > 0) {
 1913                 mtx_unlock(&cr->cr_mtx);
 1914                 return;
 1915         }
 1916         crfree_final(cr);
 1917 }
 1918 
 1919 void
 1920 crcowfree(struct thread *td)
 1921 {
 1922         struct ucred *cr;
 1923 
 1924         cr = crunuse(td);
 1925         if (cr != NULL)
 1926                 crfree(cr);
 1927 }
 1928 
 1929 struct ucred *
 1930 crcowsync(void)
 1931 {
 1932         struct thread *td;
 1933         struct proc *p;
 1934         struct ucred *crnew, *crold;
 1935 
 1936         td = curthread;
 1937         p = td->td_proc;
 1938         PROC_LOCK_ASSERT(p, MA_OWNED);
 1939 
 1940         MPASS(td->td_realucred == td->td_ucred);
 1941         if (td->td_realucred == p->p_ucred)
 1942                 return (NULL);
 1943 
 1944         crnew = crcowget(p->p_ucred);
 1945         crold = crunuse(td);
 1946         td->td_realucred = crnew;
 1947         td->td_ucred = td->td_realucred;
 1948         return (crold);
 1949 }
 1950 
 1951 /*
 1952  * Batching.
 1953  */
 1954 void
 1955 credbatch_add(struct credbatch *crb, struct thread *td)
 1956 {
 1957         struct ucred *cr;
 1958 
 1959         MPASS(td->td_realucred != NULL);
 1960         MPASS(td->td_realucred == td->td_ucred);
 1961         MPASS(td->td_state == TDS_INACTIVE);
 1962         cr = td->td_realucred;
 1963         KASSERT(cr->cr_users > 0, ("%s: users %d not > 0 on cred %p",
 1964             __func__, cr->cr_users, cr));
 1965         if (crb->cred != cr) {
 1966                 if (crb->users > 0) {
 1967                         MPASS(crb->cred != NULL);
 1968                         crunusebatch(crb->cred, crb->users, crb->ref);
 1969                         crb->users = 0;
 1970                         crb->ref = 0;
 1971                 }
 1972         }
 1973         crb->cred = cr;
 1974         crb->users++;
 1975         crb->ref += td->td_ucredref;
 1976         td->td_ucredref = 0;
 1977         td->td_realucred = NULL;
 1978 }
 1979 
 1980 void
 1981 credbatch_final(struct credbatch *crb)
 1982 {
 1983 
 1984         MPASS(crb->cred != NULL);
 1985         MPASS(crb->users > 0);
 1986         crunusebatch(crb->cred, crb->users, crb->ref);
 1987 }
 1988 
 1989 /*
 1990  * Allocate a zeroed cred structure.
 1991  */
 1992 struct ucred *
 1993 crget(void)
 1994 {
 1995         struct ucred *cr;
 1996 
 1997         cr = malloc(sizeof(*cr), M_CRED, M_WAITOK | M_ZERO);
 1998         mtx_init(&cr->cr_mtx, "cred", NULL, MTX_DEF);
 1999         cr->cr_ref = 1;
 2000 #ifdef AUDIT
 2001         audit_cred_init(cr);
 2002 #endif
 2003 #ifdef MAC
 2004         mac_cred_init(cr);
 2005 #endif
 2006         cr->cr_groups = cr->cr_smallgroups;
 2007         cr->cr_agroups =
 2008             sizeof(cr->cr_smallgroups) / sizeof(cr->cr_smallgroups[0]);
 2009         return (cr);
 2010 }
 2011 
 2012 /*
 2013  * Claim another reference to a ucred structure.
 2014  */
 2015 struct ucred *
 2016 crhold(struct ucred *cr)
 2017 {
 2018         struct thread *td;
 2019 
 2020         td = curthread;
 2021         if (__predict_true(td->td_realucred == cr)) {
 2022                 KASSERT(cr->cr_users > 0, ("%s: users %d not > 0 on cred %p",
 2023                     __func__, cr->cr_users, cr));
 2024                 td->td_ucredref++;
 2025                 return (cr);
 2026         }
 2027         mtx_lock(&cr->cr_mtx);
 2028         cr->cr_ref++;
 2029         mtx_unlock(&cr->cr_mtx);
 2030         return (cr);
 2031 }
 2032 
 2033 /*
 2034  * Free a cred structure.  Throws away space when ref count gets to 0.
 2035  */
 2036 void
 2037 crfree(struct ucred *cr)
 2038 {
 2039         struct thread *td;
 2040 
 2041         td = curthread;
 2042         if (__predict_true(td->td_realucred == cr)) {
 2043                 KASSERT(cr->cr_users > 0, ("%s: users %d not > 0 on cred %p",
 2044                     __func__, cr->cr_users, cr));
 2045                 td->td_ucredref--;
 2046                 return;
 2047         }
 2048         mtx_lock(&cr->cr_mtx);
 2049         KASSERT(cr->cr_users >= 0, ("%s: users %d not >= 0 on cred %p",
 2050             __func__, cr->cr_users, cr));
 2051         cr->cr_ref--;
 2052         if (cr->cr_users > 0) {
 2053                 mtx_unlock(&cr->cr_mtx);
 2054                 return;
 2055         }
 2056         KASSERT(cr->cr_ref >= 0, ("%s: ref %d not >= 0 on cred %p",
 2057             __func__, cr->cr_ref, cr));
 2058         if (cr->cr_ref > 0) {
 2059                 mtx_unlock(&cr->cr_mtx);
 2060                 return;
 2061         }
 2062         crfree_final(cr);
 2063 }
 2064 
 2065 static void
 2066 crfree_final(struct ucred *cr)
 2067 {
 2068 
 2069         KASSERT(cr->cr_users == 0, ("%s: users %d not == 0 on cred %p",
 2070             __func__, cr->cr_users, cr));
 2071         KASSERT(cr->cr_ref == 0, ("%s: ref %d not == 0 on cred %p",
 2072             __func__, cr->cr_ref, cr));
 2073 
 2074         /*
 2075          * Some callers of crget(), such as nfs_statfs(), allocate a temporary
 2076          * credential, but don't allocate a uidinfo structure.
 2077          */
 2078         if (cr->cr_uidinfo != NULL)
 2079                 uifree(cr->cr_uidinfo);
 2080         if (cr->cr_ruidinfo != NULL)
 2081                 uifree(cr->cr_ruidinfo);
 2082         if (cr->cr_prison != NULL)
 2083                 prison_free(cr->cr_prison);
 2084         if (cr->cr_loginclass != NULL)
 2085                 loginclass_free(cr->cr_loginclass);
 2086 #ifdef AUDIT
 2087         audit_cred_destroy(cr);
 2088 #endif
 2089 #ifdef MAC
 2090         mac_cred_destroy(cr);
 2091 #endif
 2092         mtx_destroy(&cr->cr_mtx);
 2093         if (cr->cr_groups != cr->cr_smallgroups)
 2094                 free(cr->cr_groups, M_CRED);
 2095         free(cr, M_CRED);
 2096 }
 2097 
 2098 /*
 2099  * Copy a ucred's contents from a template.  Does not block.
 2100  */
 2101 void
 2102 crcopy(struct ucred *dest, struct ucred *src)
 2103 {
 2104 
 2105         KASSERT(dest->cr_ref == 1, ("crcopy of shared ucred"));
 2106         bcopy(&src->cr_startcopy, &dest->cr_startcopy,
 2107             (unsigned)((caddr_t)&src->cr_endcopy -
 2108                 (caddr_t)&src->cr_startcopy));
 2109         crsetgroups(dest, src->cr_ngroups, src->cr_groups);
 2110         uihold(dest->cr_uidinfo);
 2111         uihold(dest->cr_ruidinfo);
 2112         prison_hold(dest->cr_prison);
 2113         loginclass_hold(dest->cr_loginclass);
 2114 #ifdef AUDIT
 2115         audit_cred_copy(src, dest);
 2116 #endif
 2117 #ifdef MAC
 2118         mac_cred_copy(src, dest);
 2119 #endif
 2120 }
 2121 
 2122 /*
 2123  * Dup cred struct to a new held one.
 2124  */
 2125 struct ucred *
 2126 crdup(struct ucred *cr)
 2127 {
 2128         struct ucred *newcr;
 2129 
 2130         newcr = crget();
 2131         crcopy(newcr, cr);
 2132         return (newcr);
 2133 }
 2134 
 2135 /*
 2136  * Fill in a struct xucred based on a struct ucred.
 2137  */
 2138 void
 2139 cru2x(struct ucred *cr, struct xucred *xcr)
 2140 {
 2141         int ngroups;
 2142 
 2143         bzero(xcr, sizeof(*xcr));
 2144         xcr->cr_version = XUCRED_VERSION;
 2145         xcr->cr_uid = cr->cr_uid;
 2146 
 2147         ngroups = MIN(cr->cr_ngroups, XU_NGROUPS);
 2148         xcr->cr_ngroups = ngroups;
 2149         bcopy(cr->cr_groups, xcr->cr_groups,
 2150             ngroups * sizeof(*cr->cr_groups));
 2151 }
 2152 
 2153 void
 2154 cru2xt(struct thread *td, struct xucred *xcr)
 2155 {
 2156 
 2157         cru2x(td->td_ucred, xcr);
 2158         xcr->cr_pid = td->td_proc->p_pid;
 2159 }
 2160 
 2161 /*
 2162  * Set initial process credentials.
 2163  * Callers are responsible for providing the reference for provided credentials.
 2164  */
 2165 void
 2166 proc_set_cred_init(struct proc *p, struct ucred *newcred)
 2167 {
 2168 
 2169         p->p_ucred = crcowget(newcred);
 2170 }
 2171 
 2172 /*
 2173  * Change process credentials.
 2174  * Callers are responsible for providing the reference for passed credentials
 2175  * and for freeing old ones.
 2176  *
 2177  * Process has to be locked except when it does not have credentials (as it
 2178  * should not be visible just yet) or when newcred is NULL (as this can be
 2179  * only used when the process is about to be freed, at which point it should
 2180  * not be visible anymore).
 2181  */
 2182 void
 2183 proc_set_cred(struct proc *p, struct ucred *newcred)
 2184 {
 2185         struct ucred *cr;
 2186 
 2187         cr = p->p_ucred;
 2188         MPASS(cr != NULL);
 2189         PROC_LOCK_ASSERT(p, MA_OWNED);
 2190         KASSERT(newcred->cr_users == 0, ("%s: users %d not 0 on cred %p",
 2191             __func__, newcred->cr_users, newcred));
 2192         mtx_lock(&cr->cr_mtx);
 2193         KASSERT(cr->cr_users > 0, ("%s: users %d not > 0 on cred %p",
 2194             __func__, cr->cr_users, cr));
 2195         cr->cr_users--;
 2196         mtx_unlock(&cr->cr_mtx);
 2197         p->p_ucred = newcred;
 2198         newcred->cr_users = 1;
 2199         PROC_UPDATE_COW(p);
 2200 }
 2201 
 2202 void
 2203 proc_unset_cred(struct proc *p)
 2204 {
 2205         struct ucred *cr;
 2206 
 2207         MPASS(p->p_state == PRS_ZOMBIE || p->p_state == PRS_NEW);
 2208         cr = p->p_ucred;
 2209         p->p_ucred = NULL;
 2210         KASSERT(cr->cr_users > 0, ("%s: users %d not > 0 on cred %p",
 2211             __func__, cr->cr_users, cr));
 2212         mtx_lock(&cr->cr_mtx);
 2213         cr->cr_users--;
 2214         if (cr->cr_users == 0)
 2215                 KASSERT(cr->cr_ref > 0, ("%s: ref %d not > 0 on cred %p",
 2216                     __func__, cr->cr_ref, cr));
 2217         mtx_unlock(&cr->cr_mtx);
 2218         crfree(cr);
 2219 }
 2220 
 2221 struct ucred *
 2222 crcopysafe(struct proc *p, struct ucred *cr)
 2223 {
 2224         struct ucred *oldcred;
 2225         int groups;
 2226 
 2227         PROC_LOCK_ASSERT(p, MA_OWNED);
 2228 
 2229         oldcred = p->p_ucred;
 2230         while (cr->cr_agroups < oldcred->cr_agroups) {
 2231                 groups = oldcred->cr_agroups;
 2232                 PROC_UNLOCK(p);
 2233                 crextend(cr, groups);
 2234                 PROC_LOCK(p);
 2235                 oldcred = p->p_ucred;
 2236         }
 2237         crcopy(cr, oldcred);
 2238 
 2239         return (oldcred);
 2240 }
 2241 
 2242 /*
 2243  * Extend the passed in credential to hold n items.
 2244  */
 2245 void
 2246 crextend(struct ucred *cr, int n)
 2247 {
 2248         int cnt;
 2249 
 2250         /* Truncate? */
 2251         if (n <= cr->cr_agroups)
 2252                 return;
 2253 
 2254         /*
 2255          * We extend by 2 each time since we're using a power of two
 2256          * allocator until we need enough groups to fill a page.
 2257          * Once we're allocating multiple pages, only allocate as many
 2258          * as we actually need.  The case of processes needing a
 2259          * non-power of two number of pages seems more likely than
 2260          * a real world process that adds thousands of groups one at a
 2261          * time.
 2262          */
 2263         if ( n < PAGE_SIZE / sizeof(gid_t) ) {
 2264                 if (cr->cr_agroups == 0)
 2265                         cnt = MAX(1, MINALLOCSIZE / sizeof(gid_t));
 2266                 else
 2267                         cnt = cr->cr_agroups * 2;
 2268 
 2269                 while (cnt < n)
 2270                         cnt *= 2;
 2271         } else
 2272                 cnt = roundup2(n, PAGE_SIZE / sizeof(gid_t));
 2273 
 2274         /* Free the old array. */
 2275         if (cr->cr_groups != cr->cr_smallgroups)
 2276                 free(cr->cr_groups, M_CRED);
 2277 
 2278         cr->cr_groups = malloc(cnt * sizeof(gid_t), M_CRED, M_WAITOK | M_ZERO);
 2279         cr->cr_agroups = cnt;
 2280 }
 2281 
 2282 /*
 2283  * Copy groups in to a credential, preserving any necessary invariants.
 2284  * Currently this includes the sorting of all supplemental gids.
 2285  * crextend() must have been called before hand to ensure sufficient
 2286  * space is available.
 2287  */
 2288 static void
 2289 crsetgroups_locked(struct ucred *cr, int ngrp, gid_t *groups)
 2290 {
 2291         int i;
 2292         int j;
 2293         gid_t g;
 2294 
 2295         KASSERT(cr->cr_agroups >= ngrp, ("cr_ngroups is too small"));
 2296 
 2297         bcopy(groups, cr->cr_groups, ngrp * sizeof(gid_t));
 2298         cr->cr_ngroups = ngrp;
 2299 
 2300         /*
 2301          * Sort all groups except cr_groups[0] to allow groupmember to
 2302          * perform a binary search.
 2303          *
 2304          * XXX: If large numbers of groups become common this should
 2305          * be replaced with shell sort like linux uses or possibly
 2306          * heap sort.
 2307          */
 2308         for (i = 2; i < ngrp; i++) {
 2309                 g = cr->cr_groups[i];
 2310                 for (j = i-1; j >= 1 && g < cr->cr_groups[j]; j--)
 2311                         cr->cr_groups[j + 1] = cr->cr_groups[j];
 2312                 cr->cr_groups[j + 1] = g;
 2313         }
 2314 }
 2315 
 2316 /*
 2317  * Copy groups in to a credential after expanding it if required.
 2318  * Truncate the list to (ngroups_max + 1) if it is too large.
 2319  */
 2320 void
 2321 crsetgroups(struct ucred *cr, int ngrp, gid_t *groups)
 2322 {
 2323 
 2324         if (ngrp > ngroups_max + 1)
 2325                 ngrp = ngroups_max + 1;
 2326 
 2327         crextend(cr, ngrp);
 2328         crsetgroups_locked(cr, ngrp, groups);
 2329 }
 2330 
 2331 /*
 2332  * Get login name, if available.
 2333  */
 2334 #ifndef _SYS_SYSPROTO_H_
 2335 struct getlogin_args {
 2336         char    *namebuf;
 2337         u_int   namelen;
 2338 };
 2339 #endif
 2340 /* ARGSUSED */
 2341 int
 2342 sys_getlogin(struct thread *td, struct getlogin_args *uap)
 2343 {
 2344         char login[MAXLOGNAME];
 2345         struct proc *p = td->td_proc;
 2346         size_t len;
 2347 
 2348         if (uap->namelen > MAXLOGNAME)
 2349                 uap->namelen = MAXLOGNAME;
 2350         PROC_LOCK(p);
 2351         SESS_LOCK(p->p_session);
 2352         len = strlcpy(login, p->p_session->s_login, uap->namelen) + 1;
 2353         SESS_UNLOCK(p->p_session);
 2354         PROC_UNLOCK(p);
 2355         if (len > uap->namelen)
 2356                 return (ERANGE);
 2357         return (copyout(login, uap->namebuf, len));
 2358 }
 2359 
 2360 /*
 2361  * Set login name.
 2362  */
 2363 #ifndef _SYS_SYSPROTO_H_
 2364 struct setlogin_args {
 2365         char    *namebuf;
 2366 };
 2367 #endif
 2368 /* ARGSUSED */
 2369 int
 2370 sys_setlogin(struct thread *td, struct setlogin_args *uap)
 2371 {
 2372         struct proc *p = td->td_proc;
 2373         int error;
 2374         char logintmp[MAXLOGNAME];
 2375 
 2376         CTASSERT(sizeof(p->p_session->s_login) >= sizeof(logintmp));
 2377 
 2378         error = priv_check(td, PRIV_PROC_SETLOGIN);
 2379         if (error)
 2380                 return (error);
 2381         error = copyinstr(uap->namebuf, logintmp, sizeof(logintmp), NULL);
 2382         if (error != 0) {
 2383                 if (error == ENAMETOOLONG)
 2384                         error = EINVAL;
 2385                 return (error);
 2386         }
 2387         AUDIT_ARG_LOGIN(logintmp);
 2388         PROC_LOCK(p);
 2389         SESS_LOCK(p->p_session);
 2390         strcpy(p->p_session->s_login, logintmp);
 2391         SESS_UNLOCK(p->p_session);
 2392         PROC_UNLOCK(p);
 2393         return (0);
 2394 }
 2395 
 2396 void
 2397 setsugid(struct proc *p)
 2398 {
 2399 
 2400         PROC_LOCK_ASSERT(p, MA_OWNED);
 2401         p->p_flag |= P_SUGID;
 2402 }
 2403 
 2404 /*-
 2405  * Change a process's effective uid.
 2406  * Side effects: newcred->cr_uid and newcred->cr_uidinfo will be modified.
 2407  * References: newcred must be an exclusive credential reference for the
 2408  *             duration of the call.
 2409  */
 2410 void
 2411 change_euid(struct ucred *newcred, struct uidinfo *euip)
 2412 {
 2413 
 2414         newcred->cr_uid = euip->ui_uid;
 2415         uihold(euip);
 2416         uifree(newcred->cr_uidinfo);
 2417         newcred->cr_uidinfo = euip;
 2418 }
 2419 
 2420 /*-
 2421  * Change a process's effective gid.
 2422  * Side effects: newcred->cr_gid will be modified.
 2423  * References: newcred must be an exclusive credential reference for the
 2424  *             duration of the call.
 2425  */
 2426 void
 2427 change_egid(struct ucred *newcred, gid_t egid)
 2428 {
 2429 
 2430         newcred->cr_groups[0] = egid;
 2431 }
 2432 
 2433 /*-
 2434  * Change a process's real uid.
 2435  * Side effects: newcred->cr_ruid will be updated, newcred->cr_ruidinfo
 2436  *               will be updated, and the old and new cr_ruidinfo proc
 2437  *               counts will be updated.
 2438  * References: newcred must be an exclusive credential reference for the
 2439  *             duration of the call.
 2440  */
 2441 void
 2442 change_ruid(struct ucred *newcred, struct uidinfo *ruip)
 2443 {
 2444 
 2445         (void)chgproccnt(newcred->cr_ruidinfo, -1, 0);
 2446         newcred->cr_ruid = ruip->ui_uid;
 2447         uihold(ruip);
 2448         uifree(newcred->cr_ruidinfo);
 2449         newcred->cr_ruidinfo = ruip;
 2450         (void)chgproccnt(newcred->cr_ruidinfo, 1, 0);
 2451 }
 2452 
 2453 /*-
 2454  * Change a process's real gid.
 2455  * Side effects: newcred->cr_rgid will be updated.
 2456  * References: newcred must be an exclusive credential reference for the
 2457  *             duration of the call.
 2458  */
 2459 void
 2460 change_rgid(struct ucred *newcred, gid_t rgid)
 2461 {
 2462 
 2463         newcred->cr_rgid = rgid;
 2464 }
 2465 
 2466 /*-
 2467  * Change a process's saved uid.
 2468  * Side effects: newcred->cr_svuid will be updated.
 2469  * References: newcred must be an exclusive credential reference for the
 2470  *             duration of the call.
 2471  */
 2472 void
 2473 change_svuid(struct ucred *newcred, uid_t svuid)
 2474 {
 2475 
 2476         newcred->cr_svuid = svuid;
 2477 }
 2478 
 2479 /*-
 2480  * Change a process's saved gid.
 2481  * Side effects: newcred->cr_svgid will be updated.
 2482  * References: newcred must be an exclusive credential reference for the
 2483  *             duration of the call.
 2484  */
 2485 void
 2486 change_svgid(struct ucred *newcred, gid_t svgid)
 2487 {
 2488 
 2489         newcred->cr_svgid = svgid;
 2490 }
 2491 
 2492 bool allow_ptrace = true;
 2493 SYSCTL_BOOL(_security_bsd, OID_AUTO, allow_ptrace, CTLFLAG_RWTUN,
 2494     &allow_ptrace, 0,
 2495     "Deny ptrace(2) use by returning ENOSYS");

Cache object: ed7eea9e8f6f8e8c95109f057504851c


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.