From a72d93045f9b40df94db5bc0c24772f42bb129df Mon Sep 17 00:00:00 2001 From: dsl Date: Sat, 23 Jun 2007 09:08:37 +0000 Subject: [PATCH] Make sys_getgroups() and sys_setgroups() use the newly added functions in kern_prot.c in order to simplify the code paths. NB: the grouplist is not longer sorted - I don't think anything relies on this (any more) and nfs will use truncated lists where the order of the entries is important. Move the external defns for public functios in kern_prot.c into a new header sys/prot.h (from sys/ucred.h which contains a compat defn that is exposed to userspace). --- sys/kern/kern_prot.c | 121 ++++++++++--------------------------------- sys/sys/mount.h | 4 +- sys/sys/prot.h | 59 +++++++++++++++++++++ sys/sys/ucred.h | 27 +--------- 4 files changed, 88 insertions(+), 123 deletions(-) create mode 100644 sys/sys/prot.h diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index b37cad3babe2..b95f782d0e91 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_prot.c,v 1.101 2007/03/09 14:11:25 ad Exp $ */ +/* $NetBSD: kern_prot.c,v 1.102 2007/06/23 09:08:37 dsl Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993 @@ -41,7 +41,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kern_prot.c,v 1.101 2007/03/09 14:11:25 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_prot.c,v 1.102 2007/06/23 09:08:37 dsl Exp $"); #include "opt_compat_43.h" @@ -53,6 +53,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_prot.c,v 1.101 2007/03/09 14:11:25 ad Exp $"); #include #include #include +#include #include #include #include @@ -69,8 +70,6 @@ int sys_getuid_with_euid(struct lwp *, void *, register_t *); int sys_getgid(struct lwp *, void *, register_t *); int sys_getgid_with_egid(struct lwp *, void *, register_t *); -static int grsortu(gid_t *, int); - /* ARGSUSED */ int sys_getpid(struct lwp *l, void *v, register_t *retval) @@ -234,30 +233,17 @@ sys_getgroups(struct lwp *l, void *v, register_t *retval) syscallarg(int) gidsetsize; syscallarg(gid_t *) gidset; } */ *uap = v; - kauth_cred_t cred = l->l_cred; - u_int ngrp; - int error; - gid_t *grbuf; + const gid_t *grbuf; - if (SCARG(uap, gidsetsize) == 0) { - *retval = kauth_cred_ngroups(cred); - return (0); - } else if (SCARG(uap, gidsetsize) < 0) - return (EINVAL); - ngrp = SCARG(uap, gidsetsize); - if (ngrp < kauth_cred_ngroups(cred)) - return (EINVAL); - ngrp = kauth_cred_ngroups(cred); + *retval = kauth_cred_ngroups(l->l_cred); + if (SCARG(uap, gidsetsize) == 0) + return 0; - grbuf = malloc(ngrp * sizeof(*grbuf), M_TEMP, M_WAITOK); - kauth_cred_getgroups(cred, grbuf, ngrp); - error = copyout(grbuf, (void *)SCARG(uap, gidset), - ngrp * sizeof(gid_t)); - free(grbuf, M_TEMP); - if (error) - return (error); - *retval = ngrp; - return (0); + grbuf = kauth_cred_getgrlist(l->l_cred, SCARG(uap, gidsetsize)); + if (grbuf == NULL) + return EINVAL; + + return copyout(grbuf, SCARG(uap, gidset), *retval * sizeof(gid_t)); } /* ARGSUSED */ @@ -569,45 +555,6 @@ sys_issetugid(struct lwp *l, void *v, register_t *retval) return (0); } -/* - * sort -u for groups. - */ -static int -grsortu(gid_t *grp, int ngrp) -{ - const gid_t *src, *end; - gid_t *dst; - gid_t group; - int i, j; - - /* bubble sort */ - for (i = 0; i < ngrp; i++) - for (j = i + 1; j < ngrp; j++) - if (grp[i] > grp[j]) { - gid_t tmp = grp[i]; - grp[i] = grp[j]; - grp[j] = tmp; - } - - /* uniq */ - end = grp + ngrp; - src = grp; - dst = grp; - while (src < end) { - group = *src++; - while (src < end && *src == group) - src++; - *dst++ = group; - } - -#ifdef DIAGNOSTIC - /* zero out the rest of the array */ - (void)memset(dst, 0, sizeof(*grp) * (end - dst)); -#endif - - return dst - grp; -} - /* ARGSUSED */ int sys_setgroups(struct lwp *l, void *v, register_t *retval) @@ -616,41 +563,25 @@ sys_setgroups(struct lwp *l, void *v, register_t *retval) syscallarg(int) gidsetsize; syscallarg(const gid_t *) gidset; } */ *uap = v; - kauth_cred_t cred, ncred; - struct proc *p = l->l_proc; - int ngrp; + kauth_cred_t ncred; int error; - gid_t grp[NGROUPS]; - size_t grsize; - - ngrp = SCARG(uap, gidsetsize); - if ((u_int)ngrp > NGROUPS) - return EINVAL; - - grsize = ngrp * sizeof(gid_t); - error = copyin(SCARG(uap, gidset), grp, grsize); - if (error) - return error; + gid_t *grbuf; ncred = kauth_cred_alloc(); - proc_crmod_enter(); - cred = p->p_cred; - if ((error = kauth_authorize_process(cred, KAUTH_PROCESS_SETID, - p, NULL, NULL, NULL)) != 0) - goto bad; + grbuf = kauth_cred_setngroups(ncred, SCARG(uap, gidsetsize)); + if (grbuf == NULL) + error = EINVAL; + else { + error = copyin(SCARG(uap, gidset), grbuf, + SCARG(uap, gidsetsize) * sizeof(gid_t)); + } + if (error != 0) { + kauth_cred_free(ncred); + return error; + } - ngrp = grsortu(grp, ngrp); - kauth_cred_clone(cred, ncred); - kauth_cred_setgroups(ncred, grp, ngrp, -1); - - /* Broadcast our credentials to the process and other LWPs. */ - proc_crmod_leave(ncred, cred, true); - - return (0); - bad: - proc_crmod_leave(cred, ncred, false); - return (error); + return kauth_proc_setgroups(l, ncred); } /* diff --git a/sys/sys/mount.h b/sys/sys/mount.h index d31a011eefc7..a566f7d58dcc 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -1,4 +1,4 @@ -/* $NetBSD: mount.h,v 1.157 2007/04/11 21:06:32 pooka Exp $ */ +/* $NetBSD: mount.h,v 1.158 2007/06/23 09:08:37 dsl Exp $ */ /* * Copyright (c) 1989, 1991, 1993 @@ -36,11 +36,11 @@ #ifndef _KERNEL #include -#include #if defined(_NETBSD_SOURCE) #include #endif /* _NETBSD_SOURCE */ #endif +#include #include #include #include diff --git a/sys/sys/prot.h b/sys/sys/prot.h new file mode 100644 index 000000000000..02254a860069 --- /dev/null +++ b/sys/sys/prot.h @@ -0,0 +1,59 @@ +/* $NetBSD: prot.h,v 1.1 2007/06/23 09:08:38 dsl Exp $ */ + +/*- + * Copyright (c) 2007 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by David Laight. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_PROT_H_ +#define _SYS_PROT_H_ + +/* + * flags that control when do_setres{u,g}id will do anything + * + * ID_XXX_EQ_YYY means + * "allow modifying XXX uid to the given value if the new value of + * XXX uid (or gid) equals the current value of YYY uid (or gid)." + */ + +#define ID_E_EQ_E 0x001 /* effective equals effective */ +#define ID_E_EQ_R 0x002 /* effective equals real */ +#define ID_E_EQ_S 0x004 /* effective equals saved */ +#define ID_R_EQ_E 0x010 /* real equals effective */ +#define ID_R_EQ_R 0x020 /* real equals real */ +#define ID_R_EQ_S 0x040 /* real equals saved */ +#define ID_S_EQ_E 0x100 /* saved equals effective */ +#define ID_S_EQ_R 0x200 /* saved equals real */ +#define ID_S_EQ_S 0x400 /* saved equals saved */ + +int do_setresuid(struct lwp *, uid_t, uid_t, uid_t, u_int); +int do_setresgid(struct lwp *, gid_t, gid_t, gid_t, u_int); + +#endif /* !_SYS_PROT_H_ */ diff --git a/sys/sys/ucred.h b/sys/sys/ucred.h index e29286a23ef3..03b2b4e35418 100644 --- a/sys/sys/ucred.h +++ b/sys/sys/ucred.h @@ -1,4 +1,4 @@ -/* $NetBSD: ucred.h,v 1.32 2007/02/18 15:20:34 dsl Exp $ */ +/* $NetBSD: ucred.h,v 1.33 2007/06/23 09:08:38 dsl Exp $ */ /* * Copyright (c) 1989, 1993 @@ -49,29 +49,4 @@ struct uucred { gid_t cr_groups[NGROUPS]; /* groups */ }; -#ifdef _KERNEL - -/* - * flags that control when do_setres{u,g}id will do anything - * - * ID_XXX_EQ_YYY means - * "allow modifying XXX uid to the given value if the new value of - * XXX uid (or gid) equals the current value of YYY uid (or gid)." - */ - -#define ID_E_EQ_E 0x001 /* effective equals effective */ -#define ID_E_EQ_R 0x002 /* effective equals real */ -#define ID_E_EQ_S 0x004 /* effective equals saved */ -#define ID_R_EQ_E 0x010 /* real equals effective */ -#define ID_R_EQ_R 0x020 /* real equals real */ -#define ID_R_EQ_S 0x040 /* real equals saved */ -#define ID_S_EQ_E 0x100 /* saved equals effective */ -#define ID_S_EQ_R 0x200 /* saved equals real */ -#define ID_S_EQ_S 0x400 /* saved equals saved */ - -int do_setresuid(struct lwp *, uid_t, uid_t, uid_t, u_int); -int do_setresgid(struct lwp *, gid_t, gid_t, gid_t, u_int); - -#endif /* _KERNEL */ - #endif /* !_SYS_UCRED_H_ */