PERFORCE change 100288 for review
John Baldwin
jhb at FreeBSD.org
Thu Jun 29 14:41:00 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=100288
Change 100288 by jhb at jhb_mutex on 2006/06/29 14:16:06
Make kern_getgroups() saner by pusing the copyout() to the caller
and assuming UIO_SYSSPACE. Also, the caller now has to set
td->td_retval[0]. I think this should be a general rule that
kern_*() should not be setting td->td_retval. Will need to audit
that eventually.
Affected files ...
.. //depot/projects/smpng/sys/i386/ibcs2/ibcs2_misc.c#25 edit
.. //depot/projects/smpng/sys/kern/kern_prot.c#94 edit
.. //depot/projects/smpng/sys/sys/syscallsubr.h#38 edit
Differences ...
==== //depot/projects/smpng/sys/i386/ibcs2/ibcs2_misc.c#25 (text+ko) ====
@@ -653,21 +653,22 @@
{
ibcs2_gid_t iset[NGROUPS_MAX];
gid_t gp[NGROUPS_MAX];
- int error, i;
+ int error, i, ngrp;
if (uap->gidsetsize < 0)
return (EINVAL);
- if (uap->gidsetsize > NGROUPS_MAX)
- uap->gidsetsize = NGROUPS_MAX;
-
- error = kern_getgroups(td, uap->gidsetsize, gp, UIO_SYSSPACE);
- if (error || uap->gidsetsize == 0 || td->td_retval[0] == 0)
+ ngrp = MIN(uap->gidsetsize, NGROUPS_MAX);
+ error = kern_getgroups(td, &ngrp, gp);
+ if (error)
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)));
+ if (uap->gidsetsize > 0) {
+ for (i = 0; i < ngrp; i++)
+ iset[i] = (ibcs2_gid_t)gp[i];
+ error = copyout(iset, uap->gidset, ngrp * sizeof(ibcs2_gid_t));
+ }
+ if (error == 0)
+ td->td_retval[0] = ngrp;
+ return (error);
}
int
==== //depot/projects/smpng/sys/kern/kern_prot.c#94 (text+ko) ====
@@ -299,35 +299,36 @@
int
getgroups(struct thread *td, register struct getgroups_args *uap)
{
- return (kern_getgroups(td, uap->gidsetsize, uap->gidset,
- UIO_USERSPACE));
+ gid_t groups[NGROUPS];
+ int error, ngrp;
+
+ ngrp = MIN(uap->gidsetsize, NGROUPS);
+ error = kern_getgroups(td, &ngrp, groups);
+ if (error)
+ return (error);
+ if (uap->gidsetsize > 0)
+ error = copyout(groups, uap->gidset, ngrp * sizeof(gid_t));
+ if (error == 0)
+ td->td_retval[0] = ngrp;
+ return (error);
}
int
-kern_getgroups(struct thread *td, u_int gidsetsize, gid_t *gidset,
- enum uio_seg gidsetseg)
+kern_getgroups(struct thread *td, u_int *ngrp, gid_t *groups)
{
struct ucred *cred;
- u_int ngrp;
int error;
cred = td->td_ucred;
- if ((ngrp = gidsetsize) == 0) {
- td->td_retval[0] = cred->cr_ngroups;
+ if (*ngrp == 0) {
+ *ngrp = cred->cr_ngroups;
return (0);
}
- if (ngrp < cred->cr_ngroups)
+ if (*ngrp < cred->cr_ngroups)
return (EINVAL);
- ngrp = cred->cr_ngroups;
- if (gidsetseg == UIO_USERSPACE)
- error = copyout(cred->cr_groups, gidset, ngrp * sizeof(gid_t));
- else {
- bcopy(cred->cr_groups, gidset, ngrp * sizeof(gid_t));
- error = 0;
- }
- if (error == 0)
- td->td_retval[0] = ngrp;
- return (error);
+ *ngrp = cred->cr_ngroups;
+ bcopy(cred->cr_groups, gidset, ngrp * sizeof(gid_t));
+ return (0);
}
#ifndef _SYS_SYSPROTO_H_
==== //depot/projects/smpng/sys/sys/syscallsubr.h#38 (text+ko) ====
@@ -83,8 +83,7 @@
enum uio_seg tptrseg);
int kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
enum uio_seg bufseg, int flags);
-int kern_getgroups(struct thread *td, u_int gidsetsize, gid_t *gidset,
- enum uio_seg gidsetseg);
+int kern_getgroups(struct thread *td, u_int *ngrp, gid_t *groups);
int kern_getitimer(struct thread *, u_int, struct itimerval *);
int kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
socklen_t *alen);
More information about the p4-projects
mailing list