View | Details | Raw Unified | Return to bug 213527 | Differences between
and this patch

Collapse All | Expand All

(-)share/man/man9/ucred.9 (-6 / +51 lines)
Lines 32-51 Link Here
32
.Sh NAME
32
.Sh NAME
33
.Nm ucred ,
33
.Nm ucred ,
34
.Nm crget ,
34
.Nm crget ,
35
.Nm ncrget ,
36
.Nm crextend ,
35
.Nm crhold ,
37
.Nm crhold ,
36
.Nm crfree ,
38
.Nm crfree ,
37
.Nm crshared ,
39
.Nm crshared ,
38
.Nm crcopy ,
40
.Nm crcopy ,
41
.Nm crcopysafe ,
39
.Nm crdup ,
42
.Nm crdup ,
43
.Nm crsetgroups ,
44
.Nm crsetgroups_s ,
40
.Nm cru2x ,
45
.Nm cru2x ,
41
.Nm cred_update_thread
46
.Nm cred_update_thread ,
42
.Nd "functions related to user credentials"
47
.Nd "functions related to user credentials"
43
.Sh SYNOPSIS
48
.Sh SYNOPSIS
44
.In sys/param.h
49
.In sys/param.h
45
.In sys/ucred.h
50
.In sys/ucred.h
46
.Ft "struct ucred *"
51
.Ft "struct ucred *"
47
.Fn crget void
52
.Fn crget "void"
48
.Ft "struct ucred *"
53
.Ft "struct ucred *"
54
.Fn ncrget "int n"
55
.Ft void
56
.Fn crextend "struct ucred *cr, int n"
57
.Ft "struct ucred *"
49
.Fn crhold "struct ucred *cr"
58
.Fn crhold "struct ucred *cr"
50
.Ft void
59
.Ft void
51
.Fn crfree "struct ucred *cr"
60
.Fn crfree "struct ucred *cr"
Lines 60-65 Link Here
60
.Ft void
69
.Ft void
61
.Fn crsetgroups "struct ucred *cr" "int ngrp" "gid_t *groups"
70
.Fn crsetgroups "struct ucred *cr" "int ngrp" "gid_t *groups"
62
.Ft void
71
.Ft void
72
.Fn crsetgroups_s "struct ucred *cr" "int ngrp" "gid_t *groups" "crgrp_order srt"
73
.Ft void
63
.Fn cru2x "struct ucred *cr" "struct xucred *xcr"
74
.Fn cru2x "struct ucred *cr" "struct xucred *xcr"
64
.Ft void
75
.Ft void
65
.Fn cred_update_thread "struct thread *td"
76
.Fn cred_update_thread "struct thread *td"
Lines 72-82 Link Here
72
.Pp
83
.Pp
73
The
84
The
74
.Fn crget
85
.Fn crget
75
function allocates memory
86
function is a wrapper around the
76
for a new structure, sets its reference count to 1, and
87
.Fn ncrget
77
initializes its lock.
88
function.  Use this when you don't know how many groups you will need
89
storage for.  This will call
90
.Fn ncrget
91
asking for the default storage size to be allocated for groups.
78
.Pp
92
.Pp
79
The
93
The
94
.Fn ncrget
95
function allocates memory for a new structure, sets its reference
96
count to 1 and initializes it's lock.  A buffer is allocated
97
for storing groups and it is sized to hold
98
.Fa n
99
items.
100
Values less than 16 result in the minimum group buffer size
101
being allocated.
102
.Pp
103
The
104
.Fn crextend
105
function increases the buffer size for holding groups to to
106
.Vt n
107
items.  Previously stored groups will be lost after this operation.
108
.Pp
109
The
80
.Fn crhold
110
.Fn crhold
81
function increases the reference count on the credential.
111
function increases the reference count on the credential.
82
.Pp
112
.Pp
Lines 124-129 Link Here
124
.Pp
154
.Pp
125
The
155
The
126
.Fn crsetgroups
156
.Fn crsetgroups
157
function is a wrapper for calling the
158
.Fn crsetgroups_s
159
function. Calling this function always ensures that the copied groups are sorted.
160
.Pp
161
The
162
.Fn crsetgroups_s
127
function sets the
163
function sets the
128
.Va cr_groups
164
.Va cr_groups
129
and
165
and
Lines 130-136 Link Here
130
.Va cr_ngroups
166
.Va cr_ngroups
131
variables and allocates space as needed.
167
variables and allocates space as needed.
132
It also truncates the group list to the current maximum number of
168
It also truncates the group list to the current maximum number of
133
groups.
169
groups.  The
170
.Fa srt
171
parameter indicates whether the supplied groups are sorted or not - it takes the following
172
values:
173
.Va CRGRP_UNSORTED
174
and
175
.Va CRGRP_SORTED .
176
Using a value of
177
.Va CRGRP_UNSORTED
178
will ensure that the groups are sorted as they are copied.
134
No other mechanism should be used to modify the
179
No other mechanism should be used to modify the
135
.Va cr_groups
180
.Va cr_groups
136
array except for updating the primary group via assignment to
181
array except for updating the primary group via assignment to
(-)sys/compat/linux/linux_misc.c (-2 / +1 lines)
Lines 1316-1323 Link Here
1316
	error = copyin(args->grouplist, linux_gidset, ngrp * sizeof(l_gid_t));
1316
	error = copyin(args->grouplist, linux_gidset, ngrp * sizeof(l_gid_t));
1317
	if (error)
1317
	if (error)
1318
		goto out;
1318
		goto out;
1319
	newcred = crget();
1319
	newcred = ncrget(ngrp + 1);
1320
	crextend(newcred, ngrp + 1);
1321
	p = td->td_proc;
1320
	p = td->td_proc;
1322
	PROC_LOCK(p);
1321
	PROC_LOCK(p);
1323
	oldcred = p->p_ucred;
1322
	oldcred = p->p_ucred;
(-)sys/compat/linux/linux_uid16.c (-1 / +1 lines)
Lines 179-186 Link Here
179
		free(linux_gidset, M_LINUX);
179
		free(linux_gidset, M_LINUX);
180
		return (error);
180
		return (error);
181
	}
181
	}
182
	newcred = crget();
183
	p = td->td_proc;
182
	p = td->td_proc;
183
	newcred = ncrget(td->td_ucred->cr_agroups);
184
	PROC_LOCK(p);
184
	PROC_LOCK(p);
185
	oldcred = crcopysafe(p, newcred);
185
	oldcred = crcopysafe(p, newcred);
186
186
(-)sys/fs/nfs/nfs_commonport.c (-1 / +1 lines)
Lines 243-249 Link Here
243
	KASSERT(nfscr->nfsc_ngroups >= 0,
243
	KASSERT(nfscr->nfsc_ngroups >= 0,
244
	    ("newnfs_copycred: negative nfsc_ngroups"));
244
	    ("newnfs_copycred: negative nfsc_ngroups"));
245
	cr->cr_uid = nfscr->nfsc_uid;
245
	cr->cr_uid = nfscr->nfsc_uid;
246
	crsetgroups(cr, nfscr->nfsc_ngroups, nfscr->nfsc_groups);
246
	crsetgroups_s(cr, nfscr->nfsc_ngroups, nfscr->nfsc_groups, CRGRP_UNSORTED);
247
}
247
}
248
248
249
/*
249
/*
(-)sys/fs/nfs/nfs_commonsubs.c (-2 / +2 lines)
Lines 3290-3298 Link Here
3290
			 * Create a credential just like svc_getcred(),
3290
			 * Create a credential just like svc_getcred(),
3291
			 * but using the group list provided.
3291
			 * but using the group list provided.
3292
			 */
3292
			 */
3293
			cr = crget();
3293
			cr = ncrget(nidp->nid_ngroup);
3294
			cr->cr_uid = cr->cr_ruid = cr->cr_svuid = nidp->nid_uid;
3294
			cr->cr_uid = cr->cr_ruid = cr->cr_svuid = nidp->nid_uid;
3295
			crsetgroups(cr, nidp->nid_ngroup, grps);
3295
			crsetgroups_s(cr, nidp->nid_ngroup, grps, CRGRP_UNSORTED);
3296
			cr->cr_rgid = cr->cr_svgid = cr->cr_groups[0];
3296
			cr->cr_rgid = cr->cr_svgid = cr->cr_groups[0];
3297
			cr->cr_prison = &prison0;
3297
			cr->cr_prison = &prison0;
3298
			prison_hold(cr->cr_prison);
3298
			prison_hold(cr->cr_prison);
(-)sys/fs/nfsserver/nfs_nfsdport.c (-2 / +2 lines)
Lines 2670-2677 Link Here
2670
		     (nd->nd_flag & ND_AUTHNONE) != 0) {
2670
		     (nd->nd_flag & ND_AUTHNONE) != 0) {
2671
			nd->nd_cred->cr_uid = credanon->cr_uid;
2671
			nd->nd_cred->cr_uid = credanon->cr_uid;
2672
			nd->nd_cred->cr_gid = credanon->cr_gid;
2672
			nd->nd_cred->cr_gid = credanon->cr_gid;
2673
			crsetgroups(nd->nd_cred, credanon->cr_ngroups,
2673
			crsetgroups_s(nd->nd_cred, credanon->cr_ngroups,
2674
			    credanon->cr_groups);
2674
			    credanon->cr_groups, CRGRP_SORTED);
2675
		} else if ((nd->nd_flag & ND_GSS) == 0) {
2675
		} else if ((nd->nd_flag & ND_GSS) == 0) {
2676
			/*
2676
			/*
2677
			 * If using AUTH_SYS, call nfsrv_getgrpscred() to see
2677
			 * If using AUTH_SYS, call nfsrv_getgrpscred() to see
(-)sys/kern/init_main.c (-2 / +6 lines)
Lines 517-523 Link Here
517
	callout_init(&td->td_slpcallout, 1);
517
	callout_init(&td->td_slpcallout, 1);
518
518
519
	/* Create credentials. */
519
	/* Create credentials. */
520
	newcred = crget();
520
	newcred = ncrget(1);
521
	newcred->cr_ngroups = 1;	/* group 0 */
521
	newcred->cr_ngroups = 1;	/* group 0 */
522
	newcred->cr_uidinfo = uifind(0);
522
	newcred->cr_uidinfo = uifind(0);
523
	newcred->cr_ruidinfo = uifind(0);
523
	newcred->cr_ruidinfo = uifind(0);
Lines 832-837 Link Here
832
	struct ucred *newcred, *oldcred;
832
	struct ucred *newcred, *oldcred;
833
	struct thread *td;
833
	struct thread *td;
834
	int error;
834
	int error;
835
	int ng;
835
836
836
	bzero(&fr, sizeof(fr));
837
	bzero(&fr, sizeof(fr));
837
	fr.fr_flags = RFFDG | RFPROC | RFSTOPPED;
838
	fr.fr_flags = RFFDG | RFPROC | RFSTOPPED;
Lines 841-847 Link Here
841
		panic("cannot fork init: %d\n", error);
842
		panic("cannot fork init: %d\n", error);
842
	KASSERT(initproc->p_pid == 1, ("create_init: initproc->p_pid != 1"));
843
	KASSERT(initproc->p_pid == 1, ("create_init: initproc->p_pid != 1"));
843
	/* divorce init's credentials from the kernel's */
844
	/* divorce init's credentials from the kernel's */
844
	newcred = crget();
845
	PROC_LOCK(initproc);
846
	ng = initproc->p_ucred->cr_agroups;
847
	PROC_UNLOCK(initproc);
848
	newcred = ncrget(ng);
845
	sx_xlock(&proctree_lock);
849
	sx_xlock(&proctree_lock);
846
	PROC_LOCK(initproc);
850
	PROC_LOCK(initproc);
847
	initproc->p_flag |= P_SYSTEM | P_INMEM;
851
	initproc->p_flag |= P_SYSTEM | P_INMEM;
(-)sys/kern/kern_jail.c (-1 / +1 lines)
Lines 2403-2409 Link Here
2403
	if ((error = pwd_chroot(td, pr->pr_root)))
2403
	if ((error = pwd_chroot(td, pr->pr_root)))
2404
		goto e_revert_osd;
2404
		goto e_revert_osd;
2405
2405
2406
	newcred = crget();
2406
	newcred = ncrget(td->td_ucred->cr_agroups);
2407
	PROC_LOCK(p);
2407
	PROC_LOCK(p);
2408
	oldcred = crcopysafe(p, newcred);
2408
	oldcred = crcopysafe(p, newcred);
2409
	newcred->cr_prison = pr;
2409
	newcred->cr_prison = pr;
(-)sys/kern/kern_loginclass.c (-1 / +1 lines)
Lines 216-222 Link Here
216
	newlc = loginclass_find(lcname);
216
	newlc = loginclass_find(lcname);
217
	if (newlc == NULL)
217
	if (newlc == NULL)
218
		return (EINVAL);
218
		return (EINVAL);
219
	newcred = crget();
219
	newcred = ncrget(td->td_ucred->cr_agroups);
220
220
221
	PROC_LOCK(p);
221
	PROC_LOCK(p);
222
	oldcred = crcopysafe(p, newcred);
222
	oldcred = crcopysafe(p, newcred);
(-)sys/kern/kern_prot.c (-29 / +58 lines)
Lines 84-90 Link Here
84
SYSCTL_NODE(_security, OID_AUTO, bsd, CTLFLAG_RW, 0, "BSD security policy");
84
SYSCTL_NODE(_security, OID_AUTO, bsd, CTLFLAG_RW, 0, "BSD security policy");
85
85
86
static void crsetgroups_locked(struct ucred *cr, int ngrp,
86
static void crsetgroups_locked(struct ucred *cr, int ngrp,
87
    gid_t *groups);
87
    gid_t *groups, crgrp_order srt);
88
88
89
#ifndef _SYS_SYSPROTO_H_
89
#ifndef _SYS_SYSPROTO_H_
90
struct getpid_args {
90
struct getpid_args {
Lines 492-498 Link Here
492
492
493
	uid = uap->uid;
493
	uid = uap->uid;
494
	AUDIT_ARG_UID(uid);
494
	AUDIT_ARG_UID(uid);
495
	newcred = crget();
495
	newcred = ncrget(td->td_ucred->cr_agroups);
496
	uip = uifind(uid);
496
	uip = uifind(uid);
497
	PROC_LOCK(p);
497
	PROC_LOCK(p);
498
	/*
498
	/*
Lines 606-612 Link Here
606
606
607
	euid = uap->euid;
607
	euid = uap->euid;
608
	AUDIT_ARG_EUID(euid);
608
	AUDIT_ARG_EUID(euid);
609
	newcred = crget();
609
	newcred = ncrget(td->td_ucred->cr_agroups);
610
	euip = uifind(euid);
610
	euip = uifind(euid);
611
	PROC_LOCK(p);
611
	PROC_LOCK(p);
612
	/*
612
	/*
Lines 661-667 Link Here
661
661
662
	gid = uap->gid;
662
	gid = uap->gid;
663
	AUDIT_ARG_GID(gid);
663
	AUDIT_ARG_GID(gid);
664
	newcred = crget();
664
	newcred = ncrget(td->td_ucred->cr_agroups);
665
	PROC_LOCK(p);
665
	PROC_LOCK(p);
666
	oldcred = crcopysafe(p, newcred);
666
	oldcred = crcopysafe(p, newcred);
667
667
Lines 759-765 Link Here
759
759
760
	egid = uap->egid;
760
	egid = uap->egid;
761
	AUDIT_ARG_EGID(egid);
761
	AUDIT_ARG_EGID(egid);
762
	newcred = crget();
762
	newcred = ncrget(td->td_ucred->cr_agroups);
763
	PROC_LOCK(p);
763
	PROC_LOCK(p);
764
	oldcred = crcopysafe(p, newcred);
764
	oldcred = crcopysafe(p, newcred);
765
765
Lines 831-838 Link Here
831
831
832
	MPASS(ngrp <= ngroups_max + 1);
832
	MPASS(ngrp <= ngroups_max + 1);
833
	AUDIT_ARG_GROUPSET(groups, ngrp);
833
	AUDIT_ARG_GROUPSET(groups, ngrp);
834
	newcred = crget();
834
	newcred = ncrget(ngrp);
835
	crextend(newcred, ngrp);
836
	PROC_LOCK(p);
835
	PROC_LOCK(p);
837
	oldcred = crcopysafe(p, newcred);
836
	oldcred = crcopysafe(p, newcred);
838
837
Lines 855-861 Link Here
855
		 */
854
		 */
856
		newcred->cr_ngroups = 1;
855
		newcred->cr_ngroups = 1;
857
	} else {
856
	} else {
858
		crsetgroups_locked(newcred, ngrp, groups);
857
		crsetgroups_locked(newcred, ngrp, groups, CRGRP_UNSORTED);
859
	}
858
	}
860
	setsugid(p);
859
	setsugid(p);
861
	proc_set_cred(p, newcred);
860
	proc_set_cred(p, newcred);
Lines 889-895 Link Here
889
	ruid = uap->ruid;
888
	ruid = uap->ruid;
890
	AUDIT_ARG_EUID(euid);
889
	AUDIT_ARG_EUID(euid);
891
	AUDIT_ARG_RUID(ruid);
890
	AUDIT_ARG_RUID(ruid);
892
	newcred = crget();
891
	newcred = ncrget(td->td_ucred->cr_agroups);
893
	euip = uifind(euid);
892
	euip = uifind(euid);
894
	ruip = uifind(ruid);
893
	ruip = uifind(ruid);
895
	PROC_LOCK(p);
894
	PROC_LOCK(p);
Lines 958-964 Link Here
958
	rgid = uap->rgid;
957
	rgid = uap->rgid;
959
	AUDIT_ARG_EGID(egid);
958
	AUDIT_ARG_EGID(egid);
960
	AUDIT_ARG_RGID(rgid);
959
	AUDIT_ARG_RGID(rgid);
961
	newcred = crget();
960
	newcred = ncrget(td->td_ucred->cr_agroups);
962
	PROC_LOCK(p);
961
	PROC_LOCK(p);
963
	oldcred = crcopysafe(p, newcred);
962
	oldcred = crcopysafe(p, newcred);
964
963
Lines 1026-1032 Link Here
1026
	AUDIT_ARG_EUID(euid);
1025
	AUDIT_ARG_EUID(euid);
1027
	AUDIT_ARG_RUID(ruid);
1026
	AUDIT_ARG_RUID(ruid);
1028
	AUDIT_ARG_SUID(suid);
1027
	AUDIT_ARG_SUID(suid);
1029
	newcred = crget();
1028
	newcred = ncrget(td->td_ucred->cr_agroups);
1030
	euip = uifind(euid);
1029
	euip = uifind(euid);
1031
	ruip = uifind(ruid);
1030
	ruip = uifind(ruid);
1032
	PROC_LOCK(p);
1031
	PROC_LOCK(p);
Lines 1107-1113 Link Here
1107
	AUDIT_ARG_EGID(egid);
1106
	AUDIT_ARG_EGID(egid);
1108
	AUDIT_ARG_RGID(rgid);
1107
	AUDIT_ARG_RGID(rgid);
1109
	AUDIT_ARG_SGID(sgid);
1108
	AUDIT_ARG_SGID(sgid);
1110
	newcred = crget();
1109
	newcred = ncrget(td->td_ucred->cr_agroups);
1111
	PROC_LOCK(p);
1110
	PROC_LOCK(p);
1112
	oldcred = crcopysafe(p, newcred);
1111
	oldcred = crcopysafe(p, newcred);
1113
1112
Lines 1775-1785 Link Here
1775
}
1774
}
1776
1775
1777
/*
1776
/*
1778
 * Allocate a zeroed cred structure.
1777
 * Wrapper around ncrget(int).
1778
 * Use this function when you don't know how many groups to reserve space for
1779
 * and just want to receive the default - smallgroups.
1779
 */
1780
 */
1780
struct ucred *
1781
struct ucred *
1781
crget(void)
1782
crget(void)
1782
{
1783
{
1784
    	/* Any value <= XU_NGROUPS is equivalent here. */
1785
	return (ncrget(1));
1786
}
1787
1788
/*
1789
 * Allocate a zeroed cred structure.
1790
 * If ngroups > cr_smallgroups, use it to extend the group buffer.
1791
 */
1792
struct ucred *
1793
ncrget(int n)
1794
{
1783
	register struct ucred *cr;
1795
	register struct ucred *cr;
1784
1796
1785
	cr = malloc(sizeof(*cr), M_CRED, M_WAITOK | M_ZERO);
1797
	cr = malloc(sizeof(*cr), M_CRED, M_WAITOK | M_ZERO);
Lines 1790-1798 Link Here
1790
#ifdef MAC
1802
#ifdef MAC
1791
	mac_cred_init(cr);
1803
	mac_cred_init(cr);
1792
#endif
1804
#endif
1793
	cr->cr_groups = cr->cr_smallgroups;
1805
	if (n > sizeof (cr->cr_smallgroups) / sizeof (cr->cr_smallgroups[0]))
1794
	cr->cr_agroups =
1806
	    crextend (cr, n);
1795
	    sizeof(cr->cr_smallgroups) / sizeof(cr->cr_smallgroups[0]);
1807
	else {
1808
	    cr->cr_groups = cr->cr_smallgroups;
1809
	    cr->cr_agroups = sizeof(cr->cr_smallgroups) / sizeof(cr->cr_smallgroups[0]);
1810
	}
1796
	return (cr);
1811
	return (cr);
1797
}
1812
}
1798
1813
Lines 1818-1824 Link Here
1818
	KASSERT(cr->cr_ref != 0xdeadc0de, ("dangling reference to ucred"));
1833
	KASSERT(cr->cr_ref != 0xdeadc0de, ("dangling reference to ucred"));
1819
	if (refcount_release(&cr->cr_ref)) {
1834
	if (refcount_release(&cr->cr_ref)) {
1820
		/*
1835
		/*
1821
		 * Some callers of crget(), such as nfs_statfs(),
1836
		 * Some callers of ncrget(), such as nfs_statfs(),
1822
		 * allocate a temporary credential, but don't
1837
		 * allocate a temporary credential, but don't
1823
		 * allocate a uidinfo structure.
1838
		 * allocate a uidinfo structure.
1824
		 */
1839
		 */
Lines 1856-1862 Link Here
1856
	bcopy(&src->cr_startcopy, &dest->cr_startcopy,
1871
	bcopy(&src->cr_startcopy, &dest->cr_startcopy,
1857
	    (unsigned)((caddr_t)&src->cr_endcopy -
1872
	    (unsigned)((caddr_t)&src->cr_endcopy -
1858
		(caddr_t)&src->cr_startcopy));
1873
		(caddr_t)&src->cr_startcopy));
1859
	crsetgroups(dest, src->cr_ngroups, src->cr_groups);
1874
	crsetgroups_s(dest, src->cr_ngroups, src->cr_groups, CRGRP_SORTED);
1860
	uihold(dest->cr_uidinfo);
1875
	uihold(dest->cr_uidinfo);
1861
	uihold(dest->cr_ruidinfo);
1876
	uihold(dest->cr_ruidinfo);
1862
	prison_hold(dest->cr_prison);
1877
	prison_hold(dest->cr_prison);
Lines 1877-1883 Link Here
1877
{
1892
{
1878
	struct ucred *newcr;
1893
	struct ucred *newcr;
1879
1894
1880
	newcr = crget();
1895
	newcr = ncrget(cr->cr_agroups);
1881
	crcopy(newcr, cr);
1896
	crcopy(newcr, cr);
1882
	return (newcr);
1897
	return (newcr);
1883
}
1898
}
Lines 1971-1976 Link Here
1971
	/* Truncate? */
1986
	/* Truncate? */
1972
	if (n <= cr->cr_agroups)
1987
	if (n <= cr->cr_agroups)
1973
		return;
1988
		return;
1989
    /* No need to allocate more than we are willing to use? */
1990
	if (n > ngroups_max + 1)
1991
		n = ngroups_max + 1;
1974
1992
1975
	/*
1993
	/*
1976
	 * We extend by 2 each time since we're using a power of two
1994
	 * We extend by 2 each time since we're using a power of two
Lines 2007-2013 Link Here
2007
 * space is available.
2025
 * space is available.
2008
 */
2026
 */
2009
static void
2027
static void
2010
crsetgroups_locked(struct ucred *cr, int ngrp, gid_t *groups)
2028
crsetgroups_locked(struct ucred *cr, int ngrp, gid_t *groups, crgrp_order srt)
2011
{
2029
{
2012
	int i;
2030
	int i;
2013
	int j;
2031
	int j;
Lines 2026-2052 Link Here
2026
	 * be replaced with shell sort like linux uses or possibly
2044
	 * be replaced with shell sort like linux uses or possibly
2027
	 * heap sort.
2045
	 * heap sort.
2028
	 */
2046
	 */
2029
	for (i = 2; i < ngrp; i++) {
2047
	if (srt == CRGRP_UNSORTED)
2030
		g = cr->cr_groups[i];
2048
	    for (i = 2; i < ngrp; i++) {
2031
		for (j = i-1; j >= 1 && g < cr->cr_groups[j]; j--)
2049
		    g = cr->cr_groups[i];
2032
			cr->cr_groups[j + 1] = cr->cr_groups[j];
2050
			for (j = i-1; j >= 1 && g < cr->cr_groups[j]; j--)
2033
		cr->cr_groups[j + 1] = g;
2051
			    cr->cr_groups[j + 1] = cr->cr_groups[j];
2034
	}
2052
		    cr->cr_groups[j + 1] = g;
2053
	    }
2035
}
2054
}
2036
2055
2037
/*
2056
/*
2038
 * Copy groups in to a credential after expanding it if required.
2057
 * A wrapper around crsetgroups_s which adds an srt enum so that the 
2039
 * Truncate the list to (ngroups_max + 1) if it is too large.
2058
 * sort algorithm in crsetgroups_locked can be avoided when the "groups" 
2059
 * parameter is taken from a struct ucred - that means it must already be
2060
 * pre-sorted, right ?
2040
 */
2061
 */
2041
void
2062
void
2042
crsetgroups(struct ucred *cr, int ngrp, gid_t *groups)
2063
crsetgroups(struct ucred *cr, int ngrp, gid_t *groups)
2043
{
2064
{
2065
    	crsetgroups_s (cr, ngrp, groups, CRGRP_UNSORTED);
2066
}
2044
2067
2068
/*
2069
 * Copy groups in to a credential after expanding it if required.
2070
 * Truncate the list to (ngroups_max + 1) if it is too large.
2071
 */
2072
void crsetgroups_s(struct ucred *cr, int ngrp, gid_t *groups, crgrp_order srt)
2073
{
2045
	if (ngrp > ngroups_max + 1)
2074
	if (ngrp > ngroups_max + 1)
2046
		ngrp = ngroups_max + 1;
2075
		ngrp = ngroups_max + 1;
2047
2076
2048
	crextend(cr, ngrp);
2077
	crextend(cr, ngrp);
2049
	crsetgroups_locked(cr, ngrp, groups);
2078
	crsetgroups_locked(cr, ngrp, groups, srt);
2050
}
2079
}
2051
2080
2052
/*
2081
/*
(-)sys/kern/sys_capability.c (-1 / +1 lines)
Lines 103-110 Link Here
103
	if (IN_CAPABILITY_MODE(td))
103
	if (IN_CAPABILITY_MODE(td))
104
		return (0);
104
		return (0);
105
105
106
	newcred = crget();
107
	p = td->td_proc;
106
	p = td->td_proc;
107
	newcred = ncrget(td->td_ucred->cr_agroups);
108
	PROC_LOCK(p);
108
	PROC_LOCK(p);
109
	oldcred = crcopysafe(p, newcred);
109
	oldcred = crcopysafe(p, newcred);
110
	newcred->cr_flags |= CRED_FLAG_CAPMODE;
110
	newcred->cr_flags |= CRED_FLAG_CAPMODE;
(-)sys/kern/vfs_export.c (-6 / +6 lines)
Lines 129-138 Link Here
129
		}
129
		}
130
		np = &nep->ne_defexported;
130
		np = &nep->ne_defexported;
131
		np->netc_exflags = argp->ex_flags;
131
		np->netc_exflags = argp->ex_flags;
132
		np->netc_anon = crget();
132
		np->netc_anon = ncrget(argp->ex_anon.cr_ngroups);
133
		np->netc_anon->cr_uid = argp->ex_anon.cr_uid;
133
		np->netc_anon->cr_uid = argp->ex_anon.cr_uid;
134
		crsetgroups(np->netc_anon, argp->ex_anon.cr_ngroups,
134
		crsetgroups_s(np->netc_anon, argp->ex_anon.cr_ngroups,
135
		    argp->ex_anon.cr_groups);
135
		    argp->ex_anon.cr_groups, CRGRP_SORTED);
136
		np->netc_anon->cr_prison = &prison0;
136
		np->netc_anon->cr_prison = &prison0;
137
		prison_hold(np->netc_anon->cr_prison);
137
		prison_hold(np->netc_anon->cr_prison);
138
		np->netc_numsecflavors = argp->ex_numsecflavors;
138
		np->netc_numsecflavors = argp->ex_numsecflavors;
Lines 208-217 Link Here
208
		goto out;
208
		goto out;
209
	}
209
	}
210
	np->netc_exflags = argp->ex_flags;
210
	np->netc_exflags = argp->ex_flags;
211
	np->netc_anon = crget();
211
	np->netc_anon = ncrget(argp->ex_anon.cr_ngroups);
212
	np->netc_anon->cr_uid = argp->ex_anon.cr_uid;
212
	np->netc_anon->cr_uid = argp->ex_anon.cr_uid;
213
	crsetgroups(np->netc_anon, argp->ex_anon.cr_ngroups,
213
	crsetgroups_s(np->netc_anon, argp->ex_anon.cr_ngroups,
214
	    argp->ex_anon.cr_groups);
214
	    argp->ex_anon.cr_groups, CRGRP_SORTED);
215
	np->netc_anon->cr_prison = &prison0;
215
	np->netc_anon->cr_prison = &prison0;
216
	prison_hold(np->netc_anon->cr_prison);
216
	prison_hold(np->netc_anon->cr_prison);
217
	np->netc_numsecflavors = argp->ex_numsecflavors;
217
	np->netc_numsecflavors = argp->ex_numsecflavors;
(-)sys/rpc/rpcsec_gss/svc_rpcsec_gss.c (-2 / +2 lines)
Lines 445-454 Link Here
445
	}
445
	}
446
446
447
	uc = &client->cl_ucred;
447
	uc = &client->cl_ucred;
448
	cr = client->cl_cred = crget();
448
	cr = client->cl_cred = ncrget(uc->gidlen);
449
	cr->cr_uid = cr->cr_ruid = cr->cr_svuid = uc->uid;
449
	cr->cr_uid = cr->cr_ruid = cr->cr_svuid = uc->uid;
450
	cr->cr_rgid = cr->cr_svgid = uc->gid;
450
	cr->cr_rgid = cr->cr_svgid = uc->gid;
451
	crsetgroups(cr, uc->gidlen, uc->gidlist);
451
	crsetgroups_s(cr, uc->gidlen, uc->gidlist, CRGRP_UNSORTED);
452
	cr->cr_prison = &prison0;
452
	cr->cr_prison = &prison0;
453
	prison_hold(cr->cr_prison);
453
	prison_hold(cr->cr_prison);
454
	*crp = crhold(cr);
454
	*crp = crhold(cr);
(-)sys/rpc/svc_auth.c (-2 / +2 lines)
Lines 175-183 Link Here
175
	switch (flavor) {
175
	switch (flavor) {
176
	case AUTH_UNIX:
176
	case AUTH_UNIX:
177
		xcr = (struct xucred *) rqst->rq_clntcred;
177
		xcr = (struct xucred *) rqst->rq_clntcred;
178
		cr = crget();
178
		cr = ncrget(xcr->cr_ngroups);
179
		cr->cr_uid = cr->cr_ruid = cr->cr_svuid = xcr->cr_uid;
179
		cr->cr_uid = cr->cr_ruid = cr->cr_svuid = xcr->cr_uid;
180
		crsetgroups(cr, xcr->cr_ngroups, xcr->cr_groups);
180
		crsetgroups_s(cr, xcr->cr_ngroups, xcr->cr_groups, CRGRP_UNSORTED);
181
		cr->cr_rgid = cr->cr_svgid = cr->cr_groups[0];
181
		cr->cr_rgid = cr->cr_svgid = cr->cr_groups[0];
182
		cr->cr_prison = &prison0;
182
		cr->cr_prison = &prison0;
183
		prison_hold(cr->cr_prison);
183
		prison_hold(cr->cr_prison);
(-)sys/security/audit/audit_syscalls.c (-7 / +5 lines)
Lines 445-455 Link Here
445
			return (EINVAL);
445
			return (EINVAL);
446
		if (udata.au_aupinfo.ap_pid < 1)
446
		if (udata.au_aupinfo.ap_pid < 1)
447
			return (ESRCH);
447
			return (ESRCH);
448
		newcred = crget();
448
		if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL)
449
		if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL) {
450
			crfree(newcred);
451
			return (ESRCH);
449
			return (ESRCH);
452
		}
450
		newcred = ncrget(td->td_ucred->cr_agroups);
453
		if ((error = p_cansee(td, tp)) != 0) {
451
		if ((error = p_cansee(td, tp)) != 0) {
454
			PROC_UNLOCK(tp);
452
			PROC_UNLOCK(tp);
455
			crfree(newcred);
453
			crfree(newcred);
Lines 587-593 Link Here
587
	if (error)
585
	if (error)
588
		return (error);
586
		return (error);
589
	audit_arg_auid(id);
587
	audit_arg_auid(id);
590
	newcred = crget();
588
	newcred = ncrget(td->td_ucred->cr_agroups);
591
	PROC_LOCK(td->td_proc);
589
	PROC_LOCK(td->td_proc);
592
	oldcred = td->td_proc->p_ucred;
590
	oldcred = td->td_proc->p_ucred;
593
	crcopy(newcred, oldcred);
591
	crcopy(newcred, oldcred);
Lines 652-658 Link Here
652
	if (error)
650
	if (error)
653
		return (error);
651
		return (error);
654
	audit_arg_auditinfo(&ai);
652
	audit_arg_auditinfo(&ai);
655
	newcred = crget();
653
	newcred = ncrget(td->td_ucred->cr_agroups);
656
	PROC_LOCK(td->td_proc);
654
	PROC_LOCK(td->td_proc);
657
	oldcred = td->td_proc->p_ucred;
655
	oldcred = td->td_proc->p_ucred;
658
	crcopy(newcred, oldcred);
656
	crcopy(newcred, oldcred);
Lines 715-721 Link Here
715
	if (aia.ai_termid.at_type != AU_IPv6 &&
713
	if (aia.ai_termid.at_type != AU_IPv6 &&
716
	    aia.ai_termid.at_type != AU_IPv4)
714
	    aia.ai_termid.at_type != AU_IPv4)
717
		return (EINVAL);
715
		return (EINVAL);
718
	newcred = crget();
716
	newcred = ncrget(td->td_ucred->cr_agroups);
719
	PROC_LOCK(td->td_proc);	
717
	PROC_LOCK(td->td_proc);	
720
	oldcred = td->td_proc->p_ucred;
718
	oldcred = td->td_proc->p_ucred;
721
	crcopy(newcred, oldcred);
719
	crcopy(newcred, oldcred);
(-)sys/security/mac/mac_syscalls.c (-2 / +1 lines)
Lines 192-200 Link Here
192
	if (error)
192
	if (error)
193
		goto out;
193
		goto out;
194
194
195
	newcred = crget();
196
197
	p = td->td_proc;
195
	p = td->td_proc;
196
	newcred = ncrget(td->td_ucred->cr_agroups);
198
	PROC_LOCK(p);
197
	PROC_LOCK(p);
199
	oldcred = p->p_ucred;
198
	oldcred = p->p_ucred;
200
199
(-)sys/security/mac_lomac/mac_lomac.c (-1 / +1 lines)
Lines 2235-2241 Link Here
2235
	if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) {
2235
	if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) {
2236
		dodrop = 0;
2236
		dodrop = 0;
2237
		mtx_unlock(&subj->mtx);
2237
		mtx_unlock(&subj->mtx);
2238
		newcred = crget();
2238
		newcred = ncrget(td->td_ucred->cr_agroups);
2239
		/*
2239
		/*
2240
		 * Prevent a lock order reversal in mac_proc_vm_revoke;
2240
		 * Prevent a lock order reversal in mac_proc_vm_revoke;
2241
		 * ideally, the other user of subj->mtx wouldn't be holding
2241
		 * ideally, the other user of subj->mtx wouldn't be holding
(-)sys/sys/ucred.h (+7 lines)
Lines 96-101 Link Here
96
struct proc;
96
struct proc;
97
struct thread;
97
struct thread;
98
98
99
typedef enum {
100
    CRGRP_UNSORTED = 0,
101
    CRGRP_SORTED = 1
102
} crgrp_order;
103
99
void	change_egid(struct ucred *newcred, gid_t egid);
104
void	change_egid(struct ucred *newcred, gid_t egid);
100
void	change_euid(struct ucred *newcred, struct uidinfo *euip);
105
void	change_euid(struct ucred *newcred, struct uidinfo *euip);
101
void	change_rgid(struct ucred *newcred, gid_t rgid);
106
void	change_rgid(struct ucred *newcred, gid_t rgid);
Lines 110-118 Link Here
110
struct ucred	*proc_set_cred(struct proc *p, struct ucred *cr);
115
struct ucred	*proc_set_cred(struct proc *p, struct ucred *cr);
111
void	crfree(struct ucred *cr);
116
void	crfree(struct ucred *cr);
112
struct ucred	*crget(void);
117
struct ucred	*crget(void);
118
struct ucred	*ncrget(int n);
113
struct ucred	*crhold(struct ucred *cr);
119
struct ucred	*crhold(struct ucred *cr);
114
void	cru2x(struct ucred *cr, struct xucred *xcr);
120
void	cru2x(struct ucred *cr, struct xucred *xcr);
115
void	crsetgroups(struct ucred *cr, int n, gid_t *groups);
121
void	crsetgroups(struct ucred *cr, int n, gid_t *groups);
122
void	crsetgroups_s(struct ucred *cr, int n, gid_t *groups, crgrp_order srt);
116
int	groupmember(gid_t gid, struct ucred *cred);
123
int	groupmember(gid_t gid, struct ucred *cred);
117
#endif /* _KERNEL */
124
#endif /* _KERNEL */
118
125

Return to bug 213527