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