Page MenuHomeFreeBSD

D60028.id187695.diff
No OneTemporary

D60028.id187695.diff

diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -1219,9 +1219,7 @@
/*
* Before FreeBSD 15.0, we allow one more group to be supplied to
- * account for the egid appearing before the supplementary groups. This
- * may technically allow one more supplementary group for systems that
- * did use the default NGROUPS_MAX if we round it back up to 1024.
+ * account for the egid appearing before the supplementary groups.
*/
gidsetsize = uap->gidsetsize;
if (gidsetsize > ngroups_max + 1 || gidsetsize < 0)
@@ -1234,11 +1232,9 @@
error = copyin(uap->gidset, groups, gidsetsize * sizeof(gid_t));
if (error == 0) {
- int ngroups = gidsetsize > 0 ? gidsetsize - 1 /* egid */ : 0;
+ int ngroups = gidsetsize;
- error = kern_setgroups(td, &ngroups, groups + 1);
- if (error == 0 && gidsetsize > 0)
- td->td_proc->p_ucred->cr_gid = groups[0];
+ error = kern_setgroups(td, &ngroups, groups + 1, true);
}
if (groups != smallgroups)
@@ -1281,7 +1277,7 @@
error = copyin(uap->gidset, groups, gidsetsize * sizeof(gid_t));
if (error == 0)
- error = kern_setgroups(td, &gidsetsize, groups);
+ error = kern_setgroups(td, &gidsetsize, groups, false);
if (groups != smallgroups)
free(groups, M_TEMP);
@@ -1293,21 +1289,39 @@
* of '*ngrpp' as a consequence.
*/
int
-kern_setgroups(struct thread *td, int *ngrpp, gid_t *groups)
+kern_setgroups(struct thread *td, int *ngrpp, gid_t *groups, bool includes_egid)
{
struct proc *p = td->td_proc;
struct ucred *newcred, *oldcred;
+ gid_t egid;
int ngrp, error;
ngrp = *ngrpp;
/* Sanity check size. */
- if (ngrp < 0 || ngrp > ngroups_max)
+ if (ngrp < 0 || ngrp > (includes_egid ? ngroups_max + 1 : ngroups_max))
return (EINVAL);
+ if (includes_egid) {
+ if (ngrp > 0) {
+ egid = groups[0];
+ groups++;
+ ngrp--;
+ } else
+ /*
+ * Semantics in this case is to remove all supplementary
+ * groups from the current process and leave the
+ * effective GID untouched. See setgroups(2) for
+ * details.
+ */
+ includes_egid = false;
+ }
+
AUDIT_ARG_GROUPSET(groups, ngrp);
+ if (includes_egid)
+ AUDIT_ARG_EGID(egid);
groups_normalize(&ngrp, groups);
- *ngrpp = ngrp;
+ *ngrpp = includes_egid ? ngrp + 1 : ngrp;
newcred = crget();
crextend(newcred, ngrp);
@@ -1324,15 +1338,29 @@
*/
error = mac_cred_check_setgroups(oldcred, ngrp,
ngrp == 0 ? NULL : groups);
- if (error)
+ if (error != 0)
goto fail;
+
+ if (includes_egid) {
+ error = mac_cred_check_setegid(oldcred, egid);
+ if (error != 0)
+ goto fail;
+ }
#endif
error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS);
- if (error)
+ if (error != 0)
goto fail;
+ if (includes_egid) {
+ error = priv_check_cred(oldcred, PRIV_CRED_SETEGID);
+ if (error != 0)
+ goto fail;
+ }
+
crsetgroups_internal(newcred, ngrp, groups);
+ if (includes_egid)
+ change_egid(newcred, egid);
setsugid(p);
proc_set_cred(p, newcred);
PROC_UNLOCK(p);
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -358,7 +358,8 @@
struct mbuf *control, enum uio_seg segflg);
int kern_setcred(struct thread *const td, const u_int flags,
struct setcred *const wcred);
-int kern_setgroups(struct thread *td, int *ngrpp, gid_t *groups);
+int kern_setgroups(struct thread *td, int *ngrpp, gid_t *groups,
+ bool includes_egid);
int kern_setitimer(struct thread *, u_int, struct itimerval *,
struct itimerval *);
int kern_setpriority(struct thread *td, int which, int who, int prio);

File Metadata

Mime Type
text/plain
Expires
Sun, Sep 27, 5:20 AM (6 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39682027
Default Alt Text
D60028.id187695.diff (3 KB)

Event Timeline