Deleted Added
full compact
kern_prot.c (193511) kern_prot.c (194498)
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

--- 28 unchanged lines hidden (view full) ---

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

--- 28 unchanged lines hidden (view full) ---

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: head/sys/kern/kern_prot.c 193511 2009-06-05 14:55:22Z rwatson $");
45__FBSDID("$FreeBSD: head/sys/kern/kern_prot.c 194498 2009-06-19 17:10:35Z brooks $");
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>

--- 23 unchanged lines hidden (view full) ---

77
78#include <security/audit/audit.h>
79#include <security/mac/mac_framework.h>
80
81static MALLOC_DEFINE(M_CRED, "cred", "credentials");
82
83SYSCTL_NODE(_security, OID_AUTO, bsd, CTLFLAG_RW, 0, "BSD security policy");
84
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>

--- 23 unchanged lines hidden (view full) ---

77
78#include <security/audit/audit.h>
79#include <security/mac/mac_framework.h>
80
81static MALLOC_DEFINE(M_CRED, "cred", "credentials");
82
83SYSCTL_NODE(_security, OID_AUTO, bsd, CTLFLAG_RW, 0, "BSD security policy");
84
85static void crextend(struct ucred *cr, int n);
86static void crsetgroups_locked(struct ucred *cr, int ngrp,
87 gid_t *groups);
88
89
85#ifndef _SYS_SYSPROTO_H_
86struct getpid_args {
87 int dummy;
88};
89#endif
90/* ARGSUSED */
91int
92getpid(struct thread *td, struct getpid_args *uap)

--- 178 unchanged lines hidden (view full) ---

271struct getgroups_args {
272 u_int gidsetsize;
273 gid_t *gidset;
274};
275#endif
276int
277getgroups(struct thread *td, register struct getgroups_args *uap)
278{
90#ifndef _SYS_SYSPROTO_H_
91struct getpid_args {
92 int dummy;
93};
94#endif
95/* ARGSUSED */
96int
97getpid(struct thread *td, struct getpid_args *uap)

--- 178 unchanged lines hidden (view full) ---

276struct getgroups_args {
277 u_int gidsetsize;
278 gid_t *gidset;
279};
280#endif
281int
282getgroups(struct thread *td, register struct getgroups_args *uap)
283{
279 gid_t groups[NGROUPS];
284 gid_t *groups;
280 u_int ngrp;
281 int error;
282
283 ngrp = MIN(uap->gidsetsize, NGROUPS);
285 u_int ngrp;
286 int error;
287
288 ngrp = MIN(uap->gidsetsize, NGROUPS);
289 groups = malloc(ngrp * sizeof(*groups), M_TEMP, M_WAITOK);
284 error = kern_getgroups(td, &ngrp, groups);
285 if (error)
290 error = kern_getgroups(td, &ngrp, groups);
291 if (error)
286 return (error);
292 goto out;
287 if (uap->gidsetsize > 0)
288 error = copyout(groups, uap->gidset, ngrp * sizeof(gid_t));
289 if (error == 0)
290 td->td_retval[0] = ngrp;
293 if (uap->gidsetsize > 0)
294 error = copyout(groups, uap->gidset, ngrp * sizeof(gid_t));
295 if (error == 0)
296 td->td_retval[0] = ngrp;
297out:
298 free(groups, M_TEMP);
291 return (error);
292}
293
294int
295kern_getgroups(struct thread *td, u_int *ngrp, gid_t *groups)
296{
297 struct ucred *cred;
298

--- 182 unchanged lines hidden (view full) ---

481 struct uidinfo *uip;
482 int error;
483
484 uid = uap->uid;
485 AUDIT_ARG(uid, uid);
486 newcred = crget();
487 uip = uifind(uid);
488 PROC_LOCK(p);
299 return (error);
300}
301
302int
303kern_getgroups(struct thread *td, u_int *ngrp, gid_t *groups)
304{
305 struct ucred *cred;
306

--- 182 unchanged lines hidden (view full) ---

489 struct uidinfo *uip;
490 int error;
491
492 uid = uap->uid;
493 AUDIT_ARG(uid, uid);
494 newcred = crget();
495 uip = uifind(uid);
496 PROC_LOCK(p);
489 oldcred = p->p_ucred;
497 /*
498 * Copy credentials so other references do not see our changes.
499 */
500 oldcred = crcopysafe(p, newcred);
490
491#ifdef MAC
492 error = mac_cred_check_setuid(oldcred, uid);
493 if (error)
494 goto fail;
495#endif
496
497 /*

--- 18 unchanged lines hidden (view full) ---

516 uid != oldcred->cr_svuid && /* allow setuid(saved gid) */
517#endif
518#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */
519 uid != oldcred->cr_uid && /* allow setuid(geteuid()) */
520#endif
521 (error = priv_check_cred(oldcred, PRIV_CRED_SETUID, 0)) != 0)
522 goto fail;
523
501
502#ifdef MAC
503 error = mac_cred_check_setuid(oldcred, uid);
504 if (error)
505 goto fail;
506#endif
507
508 /*

--- 18 unchanged lines hidden (view full) ---

527 uid != oldcred->cr_svuid && /* allow setuid(saved gid) */
528#endif
529#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */
530 uid != oldcred->cr_uid && /* allow setuid(geteuid()) */
531#endif
532 (error = priv_check_cred(oldcred, PRIV_CRED_SETUID, 0)) != 0)
533 goto fail;
534
524 /*
525 * Copy credentials so other references do not see our changes.
526 */
527 crcopy(newcred, oldcred);
528#ifdef _POSIX_SAVED_IDS
529 /*
530 * Do we have "appropriate privileges" (are we root or uid == euid)
531 * If so, we are changing the real uid and/or saved uid.
532 */
533 if (
534#ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */
535 uid == oldcred->cr_uid ||

--- 57 unchanged lines hidden (view full) ---

593 struct uidinfo *euip;
594 int error;
595
596 euid = uap->euid;
597 AUDIT_ARG(euid, euid);
598 newcred = crget();
599 euip = uifind(euid);
600 PROC_LOCK(p);
535#ifdef _POSIX_SAVED_IDS
536 /*
537 * Do we have "appropriate privileges" (are we root or uid == euid)
538 * If so, we are changing the real uid and/or saved uid.
539 */
540 if (
541#ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */
542 uid == oldcred->cr_uid ||

--- 57 unchanged lines hidden (view full) ---

600 struct uidinfo *euip;
601 int error;
602
603 euid = uap->euid;
604 AUDIT_ARG(euid, euid);
605 newcred = crget();
606 euip = uifind(euid);
607 PROC_LOCK(p);
601 oldcred = p->p_ucred;
608 /*
609 * Copy credentials so other references do not see our changes.
610 */
611 oldcred = crcopysafe(p, newcred);
602
603#ifdef MAC
604 error = mac_cred_check_seteuid(oldcred, euid);
605 if (error)
606 goto fail;
607#endif
608
609 if (euid != oldcred->cr_ruid && /* allow seteuid(getuid()) */
610 euid != oldcred->cr_svuid && /* allow seteuid(saved uid) */
611 (error = priv_check_cred(oldcred, PRIV_CRED_SETEUID, 0)) != 0)
612 goto fail;
613
614 /*
612
613#ifdef MAC
614 error = mac_cred_check_seteuid(oldcred, euid);
615 if (error)
616 goto fail;
617#endif
618
619 if (euid != oldcred->cr_ruid && /* allow seteuid(getuid()) */
620 euid != oldcred->cr_svuid && /* allow seteuid(saved uid) */
621 (error = priv_check_cred(oldcred, PRIV_CRED_SETEUID, 0)) != 0)
622 goto fail;
623
624 /*
615 * Everything's okay, do it. Copy credentials so other references do
616 * not see our changes.
625 * Everything's okay, do it.
617 */
618 crcopy(newcred, oldcred);
619 if (oldcred->cr_uid != euid) {
620 change_euid(newcred, euip);
621 setsugid(p);
622 }
623 p->p_ucred = newcred;
624 PROC_UNLOCK(p);

--- 21 unchanged lines hidden (view full) ---

646 struct ucred *newcred, *oldcred;
647 gid_t gid;
648 int error;
649
650 gid = uap->gid;
651 AUDIT_ARG(gid, gid);
652 newcred = crget();
653 PROC_LOCK(p);
626 */
627 crcopy(newcred, oldcred);
628 if (oldcred->cr_uid != euid) {
629 change_euid(newcred, euip);
630 setsugid(p);
631 }
632 p->p_ucred = newcred;
633 PROC_UNLOCK(p);

--- 21 unchanged lines hidden (view full) ---

655 struct ucred *newcred, *oldcred;
656 gid_t gid;
657 int error;
658
659 gid = uap->gid;
660 AUDIT_ARG(gid, gid);
661 newcred = crget();
662 PROC_LOCK(p);
654 oldcred = p->p_ucred;
663 oldcred = crcopysafe(p, newcred);
655
656#ifdef MAC
657 error = mac_cred_check_setgid(oldcred, gid);
658 if (error)
659 goto fail;
660#endif
661
662 /*

--- 12 unchanged lines hidden (view full) ---

675 gid != oldcred->cr_svgid && /* allow setgid(saved gid) */
676#endif
677#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */
678 gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */
679#endif
680 (error = priv_check_cred(oldcred, PRIV_CRED_SETGID, 0)) != 0)
681 goto fail;
682
664
665#ifdef MAC
666 error = mac_cred_check_setgid(oldcred, gid);
667 if (error)
668 goto fail;
669#endif
670
671 /*

--- 12 unchanged lines hidden (view full) ---

684 gid != oldcred->cr_svgid && /* allow setgid(saved gid) */
685#endif
686#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */
687 gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */
688#endif
689 (error = priv_check_cred(oldcred, PRIV_CRED_SETGID, 0)) != 0)
690 goto fail;
691
683 crcopy(newcred, oldcred);
684#ifdef _POSIX_SAVED_IDS
685 /*
686 * Do we have "appropriate privileges" (are we root or gid == egid)
687 * If so, we are changing the real uid and saved gid.
688 */
689 if (
690#ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */
691 gid == oldcred->cr_groups[0] ||

--- 53 unchanged lines hidden (view full) ---

745 struct ucred *newcred, *oldcred;
746 gid_t egid;
747 int error;
748
749 egid = uap->egid;
750 AUDIT_ARG(egid, egid);
751 newcred = crget();
752 PROC_LOCK(p);
692#ifdef _POSIX_SAVED_IDS
693 /*
694 * Do we have "appropriate privileges" (are we root or gid == egid)
695 * If so, we are changing the real uid and saved gid.
696 */
697 if (
698#ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */
699 gid == oldcred->cr_groups[0] ||

--- 53 unchanged lines hidden (view full) ---

753 struct ucred *newcred, *oldcred;
754 gid_t egid;
755 int error;
756
757 egid = uap->egid;
758 AUDIT_ARG(egid, egid);
759 newcred = crget();
760 PROC_LOCK(p);
753 oldcred = p->p_ucred;
761 oldcred = crcopysafe(p, newcred);
754
755#ifdef MAC
756 error = mac_cred_check_setegid(oldcred, egid);
757 if (error)
758 goto fail;
759#endif
760
761 if (egid != oldcred->cr_rgid && /* allow setegid(getgid()) */
762 egid != oldcred->cr_svgid && /* allow setegid(saved gid) */
763 (error = priv_check_cred(oldcred, PRIV_CRED_SETEGID, 0)) != 0)
764 goto fail;
765
762
763#ifdef MAC
764 error = mac_cred_check_setegid(oldcred, egid);
765 if (error)
766 goto fail;
767#endif
768
769 if (egid != oldcred->cr_rgid && /* allow setegid(getgid()) */
770 egid != oldcred->cr_svgid && /* allow setegid(saved gid) */
771 (error = priv_check_cred(oldcred, PRIV_CRED_SETEGID, 0)) != 0)
772 goto fail;
773
766 crcopy(newcred, oldcred);
767 if (oldcred->cr_groups[0] != egid) {
768 change_egid(newcred, egid);
769 setsugid(p);
770 }
771 p->p_ucred = newcred;
772 PROC_UNLOCK(p);
773 crfree(oldcred);
774 return (0);

--- 9 unchanged lines hidden (view full) ---

784 u_int gidsetsize;
785 gid_t *gidset;
786};
787#endif
788/* ARGSUSED */
789int
790setgroups(struct thread *td, struct setgroups_args *uap)
791{
774 if (oldcred->cr_groups[0] != egid) {
775 change_egid(newcred, egid);
776 setsugid(p);
777 }
778 p->p_ucred = newcred;
779 PROC_UNLOCK(p);
780 crfree(oldcred);
781 return (0);

--- 9 unchanged lines hidden (view full) ---

791 u_int gidsetsize;
792 gid_t *gidset;
793};
794#endif
795/* ARGSUSED */
796int
797setgroups(struct thread *td, struct setgroups_args *uap)
798{
792 gid_t groups[NGROUPS];
799 gid_t *groups = NULL;
793 int error;
794
795 if (uap->gidsetsize > NGROUPS)
796 return (EINVAL);
800 int error;
801
802 if (uap->gidsetsize > NGROUPS)
803 return (EINVAL);
804 groups = malloc(uap->gidsetsize * sizeof(gid_t), M_TEMP, M_WAITOK);
797 error = copyin(uap->gidset, groups, uap->gidsetsize * sizeof(gid_t));
798 if (error)
805 error = copyin(uap->gidset, groups, uap->gidsetsize * sizeof(gid_t));
806 if (error)
799 return (error);
800 return (kern_setgroups(td, uap->gidsetsize, groups));
807 goto out;
808 error = kern_setgroups(td, uap->gidsetsize, groups);
809out:
810 free(groups, M_TEMP);
811 return (error);
801}
802
803int
804kern_setgroups(struct thread *td, u_int ngrp, gid_t *groups)
805{
806 struct proc *p = td->td_proc;
807 struct ucred *newcred, *oldcred;
808 int error;
809
810 if (ngrp > NGROUPS)
811 return (EINVAL);
812 AUDIT_ARG(groupset, groups, ngrp);
813 newcred = crget();
812}
813
814int
815kern_setgroups(struct thread *td, u_int ngrp, gid_t *groups)
816{
817 struct proc *p = td->td_proc;
818 struct ucred *newcred, *oldcred;
819 int error;
820
821 if (ngrp > NGROUPS)
822 return (EINVAL);
823 AUDIT_ARG(groupset, groups, ngrp);
824 newcred = crget();
825 crextend(newcred, ngrp);
814 PROC_LOCK(p);
826 PROC_LOCK(p);
815 oldcred = p->p_ucred;
827 oldcred = crcopysafe(p, newcred);
816
817#ifdef MAC
818 error = mac_cred_check_setgroups(oldcred, ngrp, groups);
819 if (error)
820 goto fail;
821#endif
822
823 error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, 0);
824 if (error)
825 goto fail;
826
828
829#ifdef MAC
830 error = mac_cred_check_setgroups(oldcred, ngrp, groups);
831 if (error)
832 goto fail;
833#endif
834
835 error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, 0);
836 if (error)
837 goto fail;
838
827 /*
828 * XXX A little bit lazy here. We could test if anything has
829 * changed before crcopy() and setting P_SUGID.
830 */
831 crcopy(newcred, oldcred);
832 if (ngrp < 1) {
833 /*
834 * setgroups(0, NULL) is a legitimate way of clearing the
835 * groups vector on non-BSD systems (which generally do not
836 * have the egid in the groups[0]). We risk security holes
837 * when running non-BSD software if we do not do the same.
838 */
839 newcred->cr_ngroups = 1;
840 } else {
839 if (ngrp < 1) {
840 /*
841 * setgroups(0, NULL) is a legitimate way of clearing the
842 * groups vector on non-BSD systems (which generally do not
843 * have the egid in the groups[0]). We risk security holes
844 * when running non-BSD software if we do not do the same.
845 */
846 newcred->cr_ngroups = 1;
847 } else {
841 bcopy(groups, newcred->cr_groups, ngrp * sizeof(gid_t));
842 newcred->cr_ngroups = ngrp;
848 crsetgroups_locked(newcred, ngrp, groups);
843 }
844 setsugid(p);
845 p->p_ucred = newcred;
846 PROC_UNLOCK(p);
847 crfree(oldcred);
848 return (0);
849
850fail:

--- 21 unchanged lines hidden (view full) ---

872 euid = uap->euid;
873 ruid = uap->ruid;
874 AUDIT_ARG(euid, euid);
875 AUDIT_ARG(ruid, ruid);
876 newcred = crget();
877 euip = uifind(euid);
878 ruip = uifind(ruid);
879 PROC_LOCK(p);
849 }
850 setsugid(p);
851 p->p_ucred = newcred;
852 PROC_UNLOCK(p);
853 crfree(oldcred);
854 return (0);
855
856fail:

--- 21 unchanged lines hidden (view full) ---

878 euid = uap->euid;
879 ruid = uap->ruid;
880 AUDIT_ARG(euid, euid);
881 AUDIT_ARG(ruid, ruid);
882 newcred = crget();
883 euip = uifind(euid);
884 ruip = uifind(ruid);
885 PROC_LOCK(p);
880 oldcred = p->p_ucred;
886 oldcred = crcopysafe(p, newcred);
881
882#ifdef MAC
883 error = mac_cred_check_setreuid(oldcred, ruid, euid);
884 if (error)
885 goto fail;
886#endif
887
888 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid &&
889 ruid != oldcred->cr_svuid) ||
890 (euid != (uid_t)-1 && euid != oldcred->cr_uid &&
891 euid != oldcred->cr_ruid && euid != oldcred->cr_svuid)) &&
892 (error = priv_check_cred(oldcred, PRIV_CRED_SETREUID, 0)) != 0)
893 goto fail;
894
887
888#ifdef MAC
889 error = mac_cred_check_setreuid(oldcred, ruid, euid);
890 if (error)
891 goto fail;
892#endif
893
894 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid &&
895 ruid != oldcred->cr_svuid) ||
896 (euid != (uid_t)-1 && euid != oldcred->cr_uid &&
897 euid != oldcred->cr_ruid && euid != oldcred->cr_svuid)) &&
898 (error = priv_check_cred(oldcred, PRIV_CRED_SETREUID, 0)) != 0)
899 goto fail;
900
895 crcopy(newcred, oldcred);
896 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) {
897 change_euid(newcred, euip);
898 setsugid(p);
899 }
900 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) {
901 change_ruid(newcred, ruip);
902 setsugid(p);
903 }

--- 33 unchanged lines hidden (view full) ---

937 int error;
938
939 egid = uap->egid;
940 rgid = uap->rgid;
941 AUDIT_ARG(egid, egid);
942 AUDIT_ARG(rgid, rgid);
943 newcred = crget();
944 PROC_LOCK(p);
901 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) {
902 change_euid(newcred, euip);
903 setsugid(p);
904 }
905 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) {
906 change_ruid(newcred, ruip);
907 setsugid(p);
908 }

--- 33 unchanged lines hidden (view full) ---

942 int error;
943
944 egid = uap->egid;
945 rgid = uap->rgid;
946 AUDIT_ARG(egid, egid);
947 AUDIT_ARG(rgid, rgid);
948 newcred = crget();
949 PROC_LOCK(p);
945 oldcred = p->p_ucred;
950 oldcred = crcopysafe(p, newcred);
946
947#ifdef MAC
948 error = mac_cred_check_setregid(oldcred, rgid, egid);
949 if (error)
950 goto fail;
951#endif
952
953 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid &&
954 rgid != oldcred->cr_svgid) ||
955 (egid != (gid_t)-1 && egid != oldcred->cr_groups[0] &&
956 egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) &&
957 (error = priv_check_cred(oldcred, PRIV_CRED_SETREGID, 0)) != 0)
958 goto fail;
959
951
952#ifdef MAC
953 error = mac_cred_check_setregid(oldcred, rgid, egid);
954 if (error)
955 goto fail;
956#endif
957
958 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid &&
959 rgid != oldcred->cr_svgid) ||
960 (egid != (gid_t)-1 && egid != oldcred->cr_groups[0] &&
961 egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) &&
962 (error = priv_check_cred(oldcred, PRIV_CRED_SETREGID, 0)) != 0)
963 goto fail;
964
960 crcopy(newcred, oldcred);
961 if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) {
962 change_egid(newcred, egid);
963 setsugid(p);
964 }
965 if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) {
966 change_rgid(newcred, rgid);
967 setsugid(p);
968 }

--- 39 unchanged lines hidden (view full) ---

1008 suid = uap->suid;
1009 AUDIT_ARG(euid, euid);
1010 AUDIT_ARG(ruid, ruid);
1011 AUDIT_ARG(suid, suid);
1012 newcred = crget();
1013 euip = uifind(euid);
1014 ruip = uifind(ruid);
1015 PROC_LOCK(p);
965 if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) {
966 change_egid(newcred, egid);
967 setsugid(p);
968 }
969 if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) {
970 change_rgid(newcred, rgid);
971 setsugid(p);
972 }

--- 39 unchanged lines hidden (view full) ---

1012 suid = uap->suid;
1013 AUDIT_ARG(euid, euid);
1014 AUDIT_ARG(ruid, ruid);
1015 AUDIT_ARG(suid, suid);
1016 newcred = crget();
1017 euip = uifind(euid);
1018 ruip = uifind(ruid);
1019 PROC_LOCK(p);
1016 oldcred = p->p_ucred;
1020 oldcred = crcopysafe(p, newcred);
1017
1018#ifdef MAC
1019 error = mac_cred_check_setresuid(oldcred, ruid, euid, suid);
1020 if (error)
1021 goto fail;
1022#endif
1023
1024 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid &&
1025 ruid != oldcred->cr_svuid &&
1026 ruid != oldcred->cr_uid) ||
1027 (euid != (uid_t)-1 && euid != oldcred->cr_ruid &&
1028 euid != oldcred->cr_svuid &&
1029 euid != oldcred->cr_uid) ||
1030 (suid != (uid_t)-1 && suid != oldcred->cr_ruid &&
1031 suid != oldcred->cr_svuid &&
1032 suid != oldcred->cr_uid)) &&
1033 (error = priv_check_cred(oldcred, PRIV_CRED_SETRESUID, 0)) != 0)
1034 goto fail;
1035
1021
1022#ifdef MAC
1023 error = mac_cred_check_setresuid(oldcred, ruid, euid, suid);
1024 if (error)
1025 goto fail;
1026#endif
1027
1028 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid &&
1029 ruid != oldcred->cr_svuid &&
1030 ruid != oldcred->cr_uid) ||
1031 (euid != (uid_t)-1 && euid != oldcred->cr_ruid &&
1032 euid != oldcred->cr_svuid &&
1033 euid != oldcred->cr_uid) ||
1034 (suid != (uid_t)-1 && suid != oldcred->cr_ruid &&
1035 suid != oldcred->cr_svuid &&
1036 suid != oldcred->cr_uid)) &&
1037 (error = priv_check_cred(oldcred, PRIV_CRED_SETRESUID, 0)) != 0)
1038 goto fail;
1039
1036 crcopy(newcred, oldcred);
1037 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) {
1038 change_euid(newcred, euip);
1039 setsugid(p);
1040 }
1041 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) {
1042 change_ruid(newcred, ruip);
1043 setsugid(p);
1044 }

--- 40 unchanged lines hidden (view full) ---

1085 egid = uap->egid;
1086 rgid = uap->rgid;
1087 sgid = uap->sgid;
1088 AUDIT_ARG(egid, egid);
1089 AUDIT_ARG(rgid, rgid);
1090 AUDIT_ARG(sgid, sgid);
1091 newcred = crget();
1092 PROC_LOCK(p);
1040 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) {
1041 change_euid(newcred, euip);
1042 setsugid(p);
1043 }
1044 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) {
1045 change_ruid(newcred, ruip);
1046 setsugid(p);
1047 }

--- 40 unchanged lines hidden (view full) ---

1088 egid = uap->egid;
1089 rgid = uap->rgid;
1090 sgid = uap->sgid;
1091 AUDIT_ARG(egid, egid);
1092 AUDIT_ARG(rgid, rgid);
1093 AUDIT_ARG(sgid, sgid);
1094 newcred = crget();
1095 PROC_LOCK(p);
1093 oldcred = p->p_ucred;
1096 oldcred = crcopysafe(p, newcred);
1094
1095#ifdef MAC
1096 error = mac_cred_check_setresgid(oldcred, rgid, egid, sgid);
1097 if (error)
1098 goto fail;
1099#endif
1100
1101 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid &&
1102 rgid != oldcred->cr_svgid &&
1103 rgid != oldcred->cr_groups[0]) ||
1104 (egid != (gid_t)-1 && egid != oldcred->cr_rgid &&
1105 egid != oldcred->cr_svgid &&
1106 egid != oldcred->cr_groups[0]) ||
1107 (sgid != (gid_t)-1 && sgid != oldcred->cr_rgid &&
1108 sgid != oldcred->cr_svgid &&
1109 sgid != oldcred->cr_groups[0])) &&
1110 (error = priv_check_cred(oldcred, PRIV_CRED_SETRESGID, 0)) != 0)
1111 goto fail;
1112
1097
1098#ifdef MAC
1099 error = mac_cred_check_setresgid(oldcred, rgid, egid, sgid);
1100 if (error)
1101 goto fail;
1102#endif
1103
1104 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid &&
1105 rgid != oldcred->cr_svgid &&
1106 rgid != oldcred->cr_groups[0]) ||
1107 (egid != (gid_t)-1 && egid != oldcred->cr_rgid &&
1108 egid != oldcred->cr_svgid &&
1109 egid != oldcred->cr_groups[0]) ||
1110 (sgid != (gid_t)-1 && sgid != oldcred->cr_rgid &&
1111 sgid != oldcred->cr_svgid &&
1112 sgid != oldcred->cr_groups[0])) &&
1113 (error = priv_check_cred(oldcred, PRIV_CRED_SETRESGID, 0)) != 0)
1114 goto fail;
1115
1113 crcopy(newcred, oldcred);
1114 if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) {
1115 change_egid(newcred, egid);
1116 setsugid(p);
1117 }
1118 if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) {
1119 change_rgid(newcred, rgid);
1120 setsugid(p);
1121 }

--- 653 unchanged lines hidden (view full) ---

1775 cr = malloc(sizeof(*cr), M_CRED, M_WAITOK | M_ZERO);
1776 refcount_init(&cr->cr_ref, 1);
1777#ifdef AUDIT
1778 audit_cred_init(cr);
1779#endif
1780#ifdef MAC
1781 mac_cred_init(cr);
1782#endif
1116 if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) {
1117 change_egid(newcred, egid);
1118 setsugid(p);
1119 }
1120 if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) {
1121 change_rgid(newcred, rgid);
1122 setsugid(p);
1123 }

--- 653 unchanged lines hidden (view full) ---

1777 cr = malloc(sizeof(*cr), M_CRED, M_WAITOK | M_ZERO);
1778 refcount_init(&cr->cr_ref, 1);
1779#ifdef AUDIT
1780 audit_cred_init(cr);
1781#endif
1782#ifdef MAC
1783 mac_cred_init(cr);
1784#endif
1785 crextend(cr, XU_NGROUPS);
1783 return (cr);
1784}
1785
1786/*
1787 * Claim another reference to a ucred structure.
1788 */
1789struct ucred *
1790crhold(struct ucred *cr)

--- 33 unchanged lines hidden (view full) ---

1824 refcount_release(&cr->cr_vimage->vi_ucredrefc);
1825#endif
1826#ifdef AUDIT
1827 audit_cred_destroy(cr);
1828#endif
1829#ifdef MAC
1830 mac_cred_destroy(cr);
1831#endif
1786 return (cr);
1787}
1788
1789/*
1790 * Claim another reference to a ucred structure.
1791 */
1792struct ucred *
1793crhold(struct ucred *cr)

--- 33 unchanged lines hidden (view full) ---

1827 refcount_release(&cr->cr_vimage->vi_ucredrefc);
1828#endif
1829#ifdef AUDIT
1830 audit_cred_destroy(cr);
1831#endif
1832#ifdef MAC
1833 mac_cred_destroy(cr);
1834#endif
1835 free(cr->cr_groups, M_CRED);
1832 free(cr, M_CRED);
1833 }
1834}
1835
1836/*
1837 * Check to see if this ucred is shared.
1838 */
1839int

--- 9 unchanged lines hidden (view full) ---

1849void
1850crcopy(struct ucred *dest, struct ucred *src)
1851{
1852
1853 KASSERT(crshared(dest) == 0, ("crcopy of shared ucred"));
1854 bcopy(&src->cr_startcopy, &dest->cr_startcopy,
1855 (unsigned)((caddr_t)&src->cr_endcopy -
1856 (caddr_t)&src->cr_startcopy));
1836 free(cr, M_CRED);
1837 }
1838}
1839
1840/*
1841 * Check to see if this ucred is shared.
1842 */
1843int

--- 9 unchanged lines hidden (view full) ---

1853void
1854crcopy(struct ucred *dest, struct ucred *src)
1855{
1856
1857 KASSERT(crshared(dest) == 0, ("crcopy of shared ucred"));
1858 bcopy(&src->cr_startcopy, &dest->cr_startcopy,
1859 (unsigned)((caddr_t)&src->cr_endcopy -
1860 (caddr_t)&src->cr_startcopy));
1861 crsetgroups(dest, src->cr_ngroups, src->cr_groups);
1857 uihold(dest->cr_uidinfo);
1858 uihold(dest->cr_ruidinfo);
1859 prison_hold(dest->cr_prison);
1860#ifdef VIMAGE
1861 KASSERT(src->cr_vimage != NULL, ("cr_vimage == NULL"));
1862 refcount_acquire(&dest->cr_vimage->vi_ucredrefc);
1863#endif
1864#ifdef AUDIT

--- 18 unchanged lines hidden (view full) ---

1883}
1884
1885/*
1886 * Fill in a struct xucred based on a struct ucred.
1887 */
1888void
1889cru2x(struct ucred *cr, struct xucred *xcr)
1890{
1862 uihold(dest->cr_uidinfo);
1863 uihold(dest->cr_ruidinfo);
1864 prison_hold(dest->cr_prison);
1865#ifdef VIMAGE
1866 KASSERT(src->cr_vimage != NULL, ("cr_vimage == NULL"));
1867 refcount_acquire(&dest->cr_vimage->vi_ucredrefc);
1868#endif
1869#ifdef AUDIT

--- 18 unchanged lines hidden (view full) ---

1888}
1889
1890/*
1891 * Fill in a struct xucred based on a struct ucred.
1892 */
1893void
1894cru2x(struct ucred *cr, struct xucred *xcr)
1895{
1896 int ngroups;
1891
1892 bzero(xcr, sizeof(*xcr));
1893 xcr->cr_version = XUCRED_VERSION;
1894 xcr->cr_uid = cr->cr_uid;
1897
1898 bzero(xcr, sizeof(*xcr));
1899 xcr->cr_version = XUCRED_VERSION;
1900 xcr->cr_uid = cr->cr_uid;
1895 xcr->cr_ngroups = cr->cr_ngroups;
1896 bcopy(cr->cr_groups, xcr->cr_groups, sizeof(cr->cr_groups));
1901
1902 ngroups = MIN(cr->cr_ngroups, XU_NGROUPS);
1903 xcr->cr_ngroups = ngroups;
1904 bcopy(cr->cr_groups, xcr->cr_groups,
1905 ngroups * sizeof(*cr->cr_groups));
1897}
1898
1899/*
1900 * small routine to swap a thread's current ucred for the correct one taken
1901 * from the process.
1902 */
1903void
1904cred_update_thread(struct thread *td)

--- 5 unchanged lines hidden (view full) ---

1910 cred = td->td_ucred;
1911 PROC_LOCK(p);
1912 td->td_ucred = crhold(p->p_ucred);
1913 PROC_UNLOCK(p);
1914 if (cred != NULL)
1915 crfree(cred);
1916}
1917
1906}
1907
1908/*
1909 * small routine to swap a thread's current ucred for the correct one taken
1910 * from the process.
1911 */
1912void
1913cred_update_thread(struct thread *td)

--- 5 unchanged lines hidden (view full) ---

1919 cred = td->td_ucred;
1920 PROC_LOCK(p);
1921 td->td_ucred = crhold(p->p_ucred);
1922 PROC_UNLOCK(p);
1923 if (cred != NULL)
1924 crfree(cred);
1925}
1926
1927struct ucred *
1928crcopysafe(struct proc *p, struct ucred *cr)
1929{
1930 struct ucred *oldcred;
1931 int groups;
1932
1933 PROC_LOCK_ASSERT(p, MA_OWNED);
1934
1935 oldcred = p->p_ucred;
1936 while (cr->cr_agroups < oldcred->cr_agroups) {
1937 groups = oldcred->cr_agroups;
1938 PROC_UNLOCK(p);
1939 crextend(cr, groups);
1940 PROC_LOCK(p);
1941 oldcred = p->p_ucred;
1942 }
1943 crcopy(cr, oldcred);
1944
1945 return (oldcred);
1946}
1947
1918/*
1948/*
1949 * Extend the passed in credential to hold n items.
1950 */
1951static void
1952crextend(struct ucred *cr, int n)
1953{
1954 int cnt;
1955
1956 /* Truncate? */
1957 if (n <= cr->cr_agroups)
1958 return;
1959
1960 /*
1961 * We extend by 2 each time since we're using a power of two
1962 * allocator until we need enough groups to fill a page.
1963 * Once we're allocating multiple pages, only allocate as many
1964 * as we actually need. The case of processes needing a
1965 * non-power of two number of pages seems more likely than
1966 * a real world process that adds thousands of groups one at a
1967 * time.
1968 */
1969 if ( n < PAGE_SIZE / sizeof(gid_t) ) {
1970 if (cr->cr_agroups == 0)
1971 cnt = MINALLOCSIZE / sizeof(gid_t);
1972 else
1973 cnt = cr->cr_agroups * 2;
1974
1975 while (cnt < n)
1976 cnt *= 2;
1977 } else
1978 cnt = roundup2(n, PAGE_SIZE / sizeof(gid_t));
1979
1980 /* Free the old array. */
1981 if (cr->cr_groups)
1982 free(cr->cr_groups, M_CRED);
1983
1984 cr->cr_groups = malloc(cnt * sizeof(gid_t), M_CRED, M_WAITOK | M_ZERO);
1985 cr->cr_agroups = cnt;
1986}
1987
1988/*
1989 * Copy groups in to a credential, preserving any necessicary invariants
1990 * (i.e. sorting in the future). crextend() must have been called
1991 * before hand to ensure sufficient space is available. If
1992 */
1993static void
1994crsetgroups_locked(struct ucred *cr, int ngrp, gid_t *groups)
1995{
1996
1997 KASSERT(cr->cr_agroups >= ngrp, ("cr_ngroups is too small"));
1998
1999 bcopy(groups, cr->cr_groups, ngrp * sizeof(gid_t));
2000 cr->cr_ngroups = ngrp;
2001}
2002
2003/*
2004 * Copy groups in to a credential after expanding it if required.
2005 * Truncate the list to NGROUPS if it is too large.
2006 */
2007void
2008crsetgroups(struct ucred *cr, int ngrp, gid_t *groups)
2009{
2010
2011 if (ngrp > NGROUPS)
2012 ngrp = NGROUPS;
2013
2014 crextend(cr, ngrp);
2015 crsetgroups_locked(cr, ngrp, groups);
2016}
2017
2018/*
1919 * Get login name, if available.
1920 */
1921#ifndef _SYS_SYSPROTO_H_
1922struct getlogin_args {
1923 char *namebuf;
1924 u_int namelen;
1925};
1926#endif

--- 149 unchanged lines hidden ---
2019 * Get login name, if available.
2020 */
2021#ifndef _SYS_SYSPROTO_H_
2022struct getlogin_args {
2023 char *namebuf;
2024 u_int namelen;
2025};
2026#endif

--- 149 unchanged lines hidden ---