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