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

Cache object: b0eff671ebb01ee05b1ed388fe030dde


[ 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.