Page MenuHomeFreeBSD

D31888.1789342387.diff
No OneTemporary

Size
3 KB
Referenced Files
None
Subscribers
None

D31888.1789342387.diff

Index: sys/kern/kern_prot.c
===================================================================
--- sys/kern/kern_prot.c
+++ sys/kern/kern_prot.c
@@ -89,6 +89,8 @@
static void crfree_final(struct ucred *cr);
static void crsetgroups_locked(struct ucred *cr, int ngrp,
gid_t *groups);
+static void crsortgroups(struct ucred *cr);
+static void crcopy_withoutgroups(struct ucred *dest, struct ucred *src);
#ifndef _SYS_SYSPROTO_H_
struct getpid_args {
@@ -832,7 +834,8 @@
newcred = crget();
crextend(newcred, ngrp);
PROC_LOCK(p);
- oldcred = crcopysafe(p, newcred);
+ oldcred = p->p_ucred;
+ crcopy_withoutgroups(newcred, oldcred);
#ifdef MAC
error = mac_cred_check_setgroups(oldcred, ngrp, groups);
@@ -854,6 +857,7 @@
newcred->cr_ngroups = 1;
} else {
crsetgroups_locked(newcred, ngrp, groups);
+ crsortgroups(newcred);
}
setsugid(p);
proc_set_cred(p, newcred);
@@ -2095,17 +2099,31 @@
*/
void
crcopy(struct ucred *dest, struct ucred *src)
+{
+
+ KASSERT(dest->cr_ref == 1, ("crcopy of shared ucred"));
+ crextend(dest, src->cr_ngroups);
+ crcopy_withoutgroups(dest, src);
+ crsetgroups_locked(dest, src->cr_ngroups, src->cr_groups);
+}
+
+static void
+crcopy_withoutgroups(struct ucred *dest, struct ucred *src)
{
KASSERT(dest->cr_ref == 1, ("crcopy of shared ucred"));
bcopy(&src->cr_startcopy, &dest->cr_startcopy,
(unsigned)((caddr_t)&src->cr_endcopy -
(caddr_t)&src->cr_startcopy));
- crsetgroups(dest, src->cr_ngroups, src->cr_groups);
uihold(dest->cr_uidinfo);
uihold(dest->cr_ruidinfo);
prison_hold(dest->cr_prison);
loginclass_hold(dest->cr_loginclass);
+ /*
+ * Preserve the egid
+ */
+ dest->cr_ngroups = 1;
+ dest->cr_groups[0] = src->cr_groups[0];
#ifdef AUDIT
audit_cred_copy(src, dest);
#endif
@@ -2275,32 +2293,36 @@
}
/*
- * Copy groups in to a credential, preserving any necessary invariants.
- * Currently this includes the sorting of all supplemental gids.
+ * Copy groups in to a credential, _does_not_ sort groups.
* crextend() must have been called before hand to ensure sufficient
* space is available.
*/
static void
crsetgroups_locked(struct ucred *cr, int ngrp, gid_t *groups)
{
- int i;
- int j;
- gid_t g;
-
KASSERT(cr->cr_agroups >= ngrp, ("cr_ngroups is too small"));
bcopy(groups, cr->cr_groups, ngrp * sizeof(gid_t));
cr->cr_ngroups = ngrp;
+}
+
+/*
+ * Sort all groups except cr_groups[0] to allow groupmember to
+ * perform a binary search.
+ */
+static void
+crsortgroups(struct ucred *cr)
+{
+ int i;
+ int j;
+ gid_t g;
/*
- * Sort all groups except cr_groups[0] to allow groupmember to
- * perform a binary search.
- *
* XXX: If large numbers of groups become common this should
* be replaced with shell sort like linux uses or possibly
* heap sort.
*/
- for (i = 2; i < ngrp; i++) {
+ for (i = 2; i < cr->cr_ngroups; i++) {
g = cr->cr_groups[i];
for (j = i-1; j >= 1 && g < cr->cr_groups[j]; j--)
cr->cr_groups[j + 1] = cr->cr_groups[j];
@@ -2309,7 +2331,9 @@
}
/*
- * Copy groups in to a credential after expanding it if required.
+ * Copy groups in to a credential after expanding it if required,
+ * preserving any necessary invariants.
+ * Currently this includes the sorting of all supplemental gids.
* Truncate the list to (ngroups_max + 1) if it is too large.
*/
void
@@ -2321,6 +2345,7 @@
crextend(cr, ngrp);
crsetgroups_locked(cr, ngrp, groups);
+ crsortgroups(cr);
}
/*

File Metadata

Mime Type
text/plain
Expires
Sun, Sep 13, 11:33 PM (2 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29583333
Default Alt Text
D31888.1789342387.diff (3 KB)

Event Timeline