summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormjg <mjg@FreeBSD.org>2014-10-21 23:08:46 +0000
committermjg <mjg@FreeBSD.org>2014-10-21 23:08:46 +0000
commit4386bf043d1b3107a4a480ad90128e1246fdb07c (patch)
tree806954c654a0a29f158c5e1a3760529fba986938
parentaf449b2b721af52b6671674857bca812e30f3f8a (diff)
downloadFreeBSD-src-4386bf043d1b3107a4a480ad90128e1246fdb07c.zip
FreeBSD-src-4386bf043d1b3107a4a480ad90128e1246fdb07c.tar.gz
Eliminate unnecessary memory allocation in sys_getgroups and its ibcs2 counterpart.
-rw-r--r--sys/i386/ibcs2/ibcs2_misc.c35
-rw-r--r--sys/kern/kern_prot.c45
-rw-r--r--sys/sys/syscallsubr.h1
3 files changed, 27 insertions, 54 deletions
diff --git a/sys/i386/ibcs2/ibcs2_misc.c b/sys/i386/ibcs2/ibcs2_misc.c
index 0eeb6de..42bc4b7 100644
--- a/sys/i386/ibcs2/ibcs2_misc.c
+++ b/sys/i386/ibcs2/ibcs2_misc.c
@@ -659,33 +659,28 @@ ibcs2_getgroups(td, uap)
struct thread *td;
struct ibcs2_getgroups_args *uap;
{
+ struct ucred *cred;
ibcs2_gid_t *iset;
- gid_t *gp;
u_int i, ngrp;
int error;
- if (uap->gidsetsize < td->td_ucred->cr_ngroups) {
- if (uap->gidsetsize == 0)
- ngrp = 0;
- else
- return (EINVAL);
- } else
- ngrp = td->td_ucred->cr_ngroups;
- gp = malloc(ngrp * sizeof(*gp), M_TEMP, M_WAITOK);
- error = kern_getgroups(td, &ngrp, gp);
- if (error)
+ cred = td->td_ucred;
+ ngrp = cred->cr_ngroups;
+
+ if (uap->gidsetsize == 0) {
+ error = 0;
goto out;
- if (uap->gidsetsize > 0) {
- iset = malloc(ngrp * sizeof(*iset), M_TEMP, M_WAITOK);
- for (i = 0; i < ngrp; i++)
- iset[i] = (ibcs2_gid_t)gp[i];
- error = copyout(iset, uap->gidset, ngrp * sizeof(ibcs2_gid_t));
- free(iset, M_TEMP);
}
- if (error == 0)
- td->td_retval[0] = ngrp;
+ if (uap->gidsetsize < ngrp)
+ return (EINVAL);
+
+ iset = malloc(ngrp * sizeof(*iset), M_TEMP, M_WAITOK);
+ for (i = 0; i < ngrp; i++)
+ iset[i] = (ibcs2_gid_t)cred->cr_groups[i];
+ error = copyout(iset, uap->gidset, ngrp * sizeof(ibcs2_gid_t));
+ free(iset, M_TEMP);
out:
- free(gp, M_TEMP);
+ td->td_retval[0] = ngrp;
return (error);
}
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index fd2b7f4..f12468d 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -303,45 +303,24 @@ struct getgroups_args {
int
sys_getgroups(struct thread *td, register struct getgroups_args *uap)
{
- gid_t *groups;
+ struct ucred *cred;
u_int ngrp;
int error;
- if (uap->gidsetsize < td->td_ucred->cr_ngroups) {
- if (uap->gidsetsize == 0)
- ngrp = 0;
- else
- return (EINVAL);
- } else
- ngrp = td->td_ucred->cr_ngroups;
- groups = malloc(ngrp * sizeof(*groups), M_TEMP, M_WAITOK);
- error = kern_getgroups(td, &ngrp, groups);
- if (error)
- goto out;
- if (uap->gidsetsize > 0)
- error = copyout(groups, uap->gidset, ngrp * sizeof(gid_t));
- if (error == 0)
- td->td_retval[0] = ngrp;
-out:
- free(groups, M_TEMP);
- return (error);
-}
-
-int
-kern_getgroups(struct thread *td, u_int *ngrp, gid_t *groups)
-{
- struct ucred *cred;
-
cred = td->td_ucred;
- if (*ngrp == 0) {
- *ngrp = cred->cr_ngroups;
- return (0);
+ ngrp = cred->cr_ngroups;
+
+ if (uap->gidsetsize == 0) {
+ error = 0;
+ goto out;
}
- if (*ngrp < cred->cr_ngroups)
+ if (uap->gidsetsize < ngrp)
return (EINVAL);
- *ngrp = cred->cr_ngroups;
- bcopy(cred->cr_groups, groups, *ngrp * sizeof(gid_t));
- return (0);
+
+ error = copyout(cred->cr_groups, uap->gidset, ngrp * sizeof(gid_t));
+out:
+ td->td_retval[0] = ngrp;
+ return (error);
}
#ifndef _SYS_SYSPROTO_H_
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
index 05e9be8..7098c43 100644
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -109,7 +109,6 @@ int kern_getdirentries(struct thread *td, int fd, char *buf, u_int count,
long *basep, ssize_t *residp, enum uio_seg bufseg);
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 *ngrp, gid_t *groups);
int kern_getitimer(struct thread *, u_int, struct itimerval *);
int kern_getppid(struct thread *);
int kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
OpenPOWER on IntegriCloud