diff options
-rw-r--r-- | sys/i386/ibcs2/ibcs2_misc.c | 67 | ||||
-rw-r--r-- | sys/i386/ibcs2/syscalls.xenix | 4 | ||||
-rw-r--r-- | sys/kern/kern_prot.c | 67 | ||||
-rw-r--r-- | sys/sys/syscallsubr.h | 2 |
4 files changed, 71 insertions, 69 deletions
diff --git a/sys/i386/ibcs2/ibcs2_misc.c b/sys/i386/ibcs2/ibcs2_misc.c index c4efc02..c875075 100644 --- a/sys/i386/ibcs2/ibcs2_misc.c +++ b/sys/i386/ibcs2/ibcs2_misc.c @@ -651,35 +651,25 @@ ibcs2_getgroups(td, uap) struct thread *td; struct ibcs2_getgroups_args *uap; { - int error, i; - ibcs2_gid_t *iset = NULL; - struct getgroups_args sa; - gid_t *gp; - caddr_t sg = stackgap_init(); + ibcs2_gid_t iset[NGROUPS_MAX]; + gid_t gp[NGROUPS_MAX]; + u_int i, ngrp; + int error; if (uap->gidsetsize < 0) return (EINVAL); - if (uap->gidsetsize > NGROUPS_MAX) - uap->gidsetsize = NGROUPS_MAX; - sa.gidsetsize = uap->gidsetsize; - if (uap->gidsetsize) { - sa.gidset = stackgap_alloc(&sg, NGROUPS_MAX * - sizeof(gid_t *)); - iset = stackgap_alloc(&sg, uap->gidsetsize * - sizeof(ibcs2_gid_t)); + ngrp = MIN(uap->gidsetsize, NGROUPS_MAX); + error = kern_getgroups(td, &ngrp, gp); + if (error) + return (error); + 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 = getgroups(td, &sa)) != 0) - return error; - if (uap->gidsetsize == 0) - return 0; - - for (i = 0, gp = sa.gidset; i < td->td_retval[0]; i++) - iset[i] = (ibcs2_gid_t)*gp++; - if (td->td_retval[0] && (error = copyout((caddr_t)iset, - (caddr_t)uap->gidset, - sizeof(ibcs2_gid_t) * td->td_retval[0]))) - return error; - return 0; + if (error == 0) + td->td_retval[0] = ngrp; + return (error); } int @@ -687,28 +677,21 @@ ibcs2_setgroups(td, uap) 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 diff --git a/sys/i386/ibcs2/syscalls.xenix b/sys/i386/ibcs2/syscalls.xenix index ae8be83..8b9b84a 100644 --- a/sys/i386/ibcs2/syscalls.xenix +++ b/sys/i386/ibcs2/syscalls.xenix @@ -56,9 +56,9 @@ ibcs2_sigset_t *oset); } 41 AUE_NULL MSTD { int ibcs2_sigpending(ibcs2_sigset_t *mask); } 42 AUE_NULL MSTD { int ibcs2_sigsuspend(ibcs2_sigset_t *mask); } -43 AUE_GETGROUPS STD { int ibcs2_getgroups(int gidsetsize, \ +43 AUE_GETGROUPS MSTD { int ibcs2_getgroups(int gidsetsize, \ ibcs2_gid_t *gidset); } -44 AUE_SETGROUPS STD { int ibcs2_setgroups(int gidsetsize, \ +44 AUE_SETGROUPS MSTD { int ibcs2_setgroups(int gidsetsize, \ ibcs2_gid_t *gidset); } 45 AUE_NULL MSTD { int ibcs2_sysconf(int name); } 46 AUE_PATHCONF MSTD { int ibcs2_pathconf(char *path, int name); } diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 469659a..2943939 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$"); #include <sys/resourcevar.h> #include <sys/socket.h> #include <sys/socketvar.h> +#include <sys/syscallsubr.h> #include <sys/sysctl.h> #include <security/audit/audit.h> @@ -297,22 +298,36 @@ struct getgroups_args { int getgroups(struct thread *td, register struct getgroups_args *uap) { - struct ucred *cred; + gid_t groups[NGROUPS]; u_int ngrp; int error; + 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 *ngrp, gid_t *groups) +{ + struct ucred *cred; + cred = td->td_ucred; - if ((ngrp = uap->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; - error = copyout(cred->cr_groups, uap->gidset, ngrp * sizeof(gid_t)); - if (error == 0) - td->td_retval[0] = ngrp; - return (error); + *ngrp = cred->cr_ngroups; + bcopy(cred->cr_groups, groups, *ngrp * sizeof(gid_t)); + return (0); } #ifndef _SYS_SYSPROTO_H_ @@ -815,28 +830,33 @@ struct setgroups_args { 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 @@ -859,21 +879,18 @@ setgroups(struct thread *td, struct setgroups_args *uap) */ 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); } diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index d4f818b..c7a0cd5 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -81,6 +81,7 @@ int kern_futimes(struct thread *td, int fd, struct timeval *tptr, 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 *ngrp, gid_t *groups); int kern_getitimer(struct thread *, u_int, struct itimerval *); int kern_getrusage(struct thread *td, int who, struct rusage *rup); int kern_getsockopt(struct thread *td, int s, int level, int name, @@ -132,6 +133,7 @@ int kern_sendfile(struct thread *td, struct sendfile_args *uap, 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 *); |