PERFORCE change 100235 for review

John Baldwin jhb at FreeBSD.org
Wed Jun 28 21:57:10 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=100235

Change 100235 by jhb at jhb_mutex on 2006/06/28 21:25:03

	- Stick group arrays on the stack, they are tiny.
	- Add a kern_setgroups() for ibcs2.  This actually removes a gross
	  hack from setgroups() where we used to allocate an entire credential
	  just to borrow its groups array.  Now we copy the groups array into
	  an array on the stack and just pass it to kern_setgroups().

Affected files ...

.. //depot/projects/smpng/sys/i386/ibcs2/ibcs2_misc.c#24 edit
.. //depot/projects/smpng/sys/kern/kern_prot.c#93 edit
.. //depot/projects/smpng/sys/sys/syscallsubr.h#37 edit

Differences ...

==== //depot/projects/smpng/sys/i386/ibcs2/ibcs2_misc.c#24 (text+ko) ====

@@ -651,31 +651,23 @@
 	struct thread *td;
 	struct ibcs2_getgroups_args *uap;
 {
-	ibcs2_gid_t *iset;
-	gid_t *gp;
+	ibcs2_gid_t iset[NGROUPS_MAX];
+	gid_t gp[NGROUPS_MAX];
 	int error, i;
 
 	if (uap->gidsetsize < 0)
 		return (EINVAL);
 	if (uap->gidsetsize > NGROUPS_MAX)
 		uap->gidsetsize = NGROUPS_MAX;
-	if (uap->gidsetsize)
-		gp = malloc(uap->gidsetsize * sizeof(gid_t), M_TEMP, M_WAITOK);
-	else
-		gp = NULL;
 
 	error = kern_getgroups(td, uap->gidsetsize, gp, UIO_SYSSPACE);
-	if (error == 0 && gp != NULL && td->td_retval[0] > 0) {
-		iset = malloc(td->td_retval[0] * sizeof(ibcs2_gid_t), M_TEMP,
-		    M_WAITOK);
-		for (i = 0; i < td->td_retval[0]; i++)
-			iset[i] = (ibcs2_gid_t)gp[i];
-		error = copyout(iset, uap->gidset, td->td_retval[0] *
-		    sizeof(ibcs2_gid_t));
-		free(iset, M_TEMP);
-	}
-	free(gp, M_TEMP);
-	return (error);
+	if (error || uap->gidsetsize == 0 || td->td_retval[0] == 0)
+		return (error);
+
+	for (i = 0; i < td->td_retval[0]; i++)
+		iset[i] = (ibcs2_gid_t)gp[i];
+	return (copyout(iset, uap->gidset, td->td_retval[0] *
+	    sizeof(ibcs2_gid_t)));
 }
 
 int
@@ -683,28 +675,21 @@
 	struct thread *td;
 	struct ibcs2_setgroups_args *uap;
 {
+	ibcs2_gid_t iset[NGROUPS_MAX];
+	gid_t gp[NGROUPS_MAX];
 	int error, i;
-	ibcs2_gid_t *iset;
-	struct setgroups_args sa;
-	gid_t *gp;
-	caddr_t sg = stackgap_init();
 
 	if (uap->gidsetsize < 0 || uap->gidsetsize > NGROUPS_MAX)
 		return (EINVAL);
-	sa.gidsetsize = uap->gidsetsize;
-	sa.gidset = stackgap_alloc(&sg, sa.gidsetsize *
-					    sizeof(gid_t *));
-	iset = stackgap_alloc(&sg, sa.gidsetsize *
-			      sizeof(ibcs2_gid_t *));
-	if (sa.gidsetsize) {
-		if ((error = copyin((caddr_t)uap->gidset, (caddr_t)iset, 
-				   sizeof(ibcs2_gid_t *) *
-				   uap->gidsetsize)) != 0)
-			return error;
+	if (uap->gidsetsize && uap->gidset) {
+		error = copyin(uap->gidset, iset, sizeof(ibcs2_gid_t) *
+		    uap->gidsetsize);
+		if (error)
+			return (error);
+		for (i = 0; i < uap->gidsetsize; i++)
+			gp[i] = (gid_t)iset[i];
 	}
-	for (i = 0, gp = sa.gidset; i < sa.gidsetsize; i++)
-		*gp++ = (gid_t)iset[i];
-	return setgroups(td, &sa);
+	return (kern_setgroups(td, uap->gidsetsize, gp));
 }
 
 int

==== //depot/projects/smpng/sys/kern/kern_prot.c#93 (text+ko) ====

@@ -830,28 +830,33 @@
 int
 setgroups(struct thread *td, struct setgroups_args *uap)
 {
+	gid_t groups[NGROUPS];
+	int error;
+
+	if (uap->gidsetsize > NGROUPS)
+		return (EINVAL);
+	error = copyin(uap->gidset, groups, uap->gidsetsize * sizeof(gid_t));
+	if (error)
+		return (error);
+	return (kern_setgroups(td, uap->gidsetsize, groups));
+}
+
+int
+kern_setgroups(struct thread *td, u_int ngrp, gid_t *groups)
+{
 	struct proc *p = td->td_proc;
-	struct ucred *newcred, *tempcred, *oldcred;
-	u_int ngrp;
+	struct ucred *newcred, *oldcred;
 	int error;
 
-	ngrp = uap->gidsetsize;
 	if (ngrp > NGROUPS)
 		return (EINVAL);
-	tempcred = crget();
-	error = copyin(uap->gidset, tempcred->cr_groups, ngrp * sizeof(gid_t));
-	if (error != 0) {
-		crfree(tempcred);
-		return (error);
-	}
-	AUDIT_ARG(groupset, tempcred->cr_groups, ngrp);
+	AUDIT_ARG(groupset, groups, ngrp);
 	newcred = crget();
 	PROC_LOCK(p);
 	oldcred = p->p_ucred;
 
 #ifdef MAC
-	error = mac_check_proc_setgroups(p, oldcred, ngrp,
-	    tempcred->cr_groups);
+	error = mac_check_proc_setgroups(p, oldcred, ngrp, groups);
 	if (error)
 		goto fail;
 #endif
@@ -874,21 +879,18 @@
 		 */
 		newcred->cr_ngroups = 1;
 	} else {
-		bcopy(tempcred->cr_groups, newcred->cr_groups,
-		    ngrp * sizeof(gid_t));
+		bcopy(groups, newcred->cr_groups, ngrp * sizeof(gid_t));
 		newcred->cr_ngroups = ngrp;
 	}
 	setsugid(p);
 	p->p_ucred = newcred;
 	PROC_UNLOCK(p);
-	crfree(tempcred);
 	crfree(oldcred);
 	return (0);
 
 fail:
 	PROC_UNLOCK(p);
 	crfree(newcred);
-	crfree(tempcred);
 	return (error);
 }
 

==== //depot/projects/smpng/sys/sys/syscallsubr.h#37 (text+ko) ====

@@ -141,6 +141,7 @@
 	    struct uio *hdr_uio, struct uio *trl_uio, int compat);
 int	kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
 	    struct mbuf *control, enum uio_seg segflg);
+int	kern_setgroups(struct thread *td, u_int ngrp, gid_t *groups);
 int	kern_setitimer(struct thread *, u_int, struct itimerval *,
 	    struct itimerval *);
 int	kern_setrlimit(struct thread *, u_int, struct rlimit *);


More information about the p4-projects mailing list