Add a flags parameter to kauth_cred_get/setgroups() so that sys_set/setgroups

can copy directly to/from userspace.
Avoids exposing the implementation of the group list as an array to code
outside kern_auth.c.
compat code and man page need updating.
This commit is contained in:
dsl 2007-06-30 13:32:14 +00:00
parent 5092d42715
commit 04c196a642
4 changed files with 55 additions and 69 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: init_sysctl.c,v 1.101 2007/05/17 14:51:38 yamt Exp $ */
/* $NetBSD: init_sysctl.c,v 1.102 2007/06/30 13:32:14 dsl Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.101 2007/05/17 14:51:38 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.102 2007/06/30 13:32:14 dsl Exp $");
#include "opt_sysv.h"
#include "opt_multiprocessor.h"
@ -2732,7 +2732,8 @@ fill_kproc2(struct proc *p, struct kinfo_proc2 *ki)
ki->p_ngroups = kauth_cred_ngroups(p->p_cred);
kauth_cred_getgroups(p->p_cred, ki->p_groups,
min(ki->p_ngroups, sizeof(ki->p_groups) / sizeof(ki->p_groups[0])));
min(ki->p_ngroups, sizeof(ki->p_groups) / sizeof(ki->p_groups[0])),
UIO_SYSSPACE);
ki->p_jobc = p->p_pgrp->pg_jobc;
if ((p->p_lflag & PL_CONTROLT) && (tp = p->p_session->s_ttyp)) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_auth.c,v 1.48 2007/06/23 09:02:12 dsl Exp $ */
/* $NetBSD: kern_auth.c,v 1.49 2007/06/30 13:32:14 dsl Exp $ */
/*-
* Copyright (c) 2005, 2006 Elad Efrat <elad@NetBSD.org>
@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_auth.c,v 1.48 2007/06/23 09:02:12 dsl Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_auth.c,v 1.49 2007/06/30 13:32:14 dsl Exp $");
#include <sys/types.h>
#include <sys/param.h>
@ -164,13 +164,7 @@ kauth_cred_free(kauth_cred_t cred)
}
}
void
kauth_cred_clone(kauth_cred_t from, kauth_cred_t to)
{
kauth_cred_clone1(from, to, true);
}
void
static void
kauth_cred_clone1(kauth_cred_t from, kauth_cred_t to, bool copy_groups)
{
KASSERT(from != NULL);
@ -191,6 +185,12 @@ kauth_cred_clone1(kauth_cred_t from, kauth_cred_t to, bool copy_groups)
kauth_cred_hook(from, KAUTH_CRED_COPY, to, NULL);
}
void
kauth_cred_clone(kauth_cred_t from, kauth_cred_t to)
{
kauth_cred_clone1(from, to, true);
}
/*
* Duplicate cred and return a new kauth_cred_t.
*/
@ -392,35 +392,37 @@ kauth_cred_group(kauth_cred_t cred, u_int idx)
/* XXX elad: gmuid is unused for now. */
int
kauth_cred_setgroups(kauth_cred_t cred, gid_t *grbuf, size_t len, uid_t gmuid)
kauth_cred_setgroups(kauth_cred_t cred, const gid_t *grbuf, size_t len,
uid_t gmuid, unsigned int flags)
{
int error = 0;
KASSERT(cred != NULL);
KASSERT(cred->cr_refcnt == 1);
KASSERT(len <= sizeof(cred->cr_groups) / sizeof(cred->cr_groups[0]));
if (len)
memcpy(cred->cr_groups, grbuf, len * sizeof(cred->cr_groups[0]));
if (len > sizeof(cred->cr_groups) / sizeof(cred->cr_groups[0]))
return EINVAL;
if (len) {
if ((flags & (UIO_USERSPACE | UIO_SYSSPACE)) == UIO_USERSPACE)
memcpy(cred->cr_groups, grbuf,
len * sizeof(cred->cr_groups[0]));
else {
error = copyin(grbuf, cred->cr_groups,
len * sizeof(cred->cr_groups[0]));
if (error != 0)
len = 0;
}
}
memset(cred->cr_groups + len, 0xff,
sizeof(cred->cr_groups) - (len * sizeof(cred->cr_groups[0])));
cred->cr_ngroups = len;
return (0);
return error;
}
/* This is the first half of sys_setgroups ... */
gid_t *
kauth_cred_setngroups(kauth_cred_t cred, int ngrp)
{
if (cred->cr_refcnt != 1)
return NULL;
if ((unsigned int)ngrp > NGROUPS)
return NULL;
cred->cr_ngroups = ngrp;
return cred->cr_groups;
}
/* ... and this is the second */
/* This supports sys_setgroups() */
int
kauth_proc_setgroups(struct lwp *l, kauth_cred_t ncred)
{
@ -451,23 +453,19 @@ kauth_proc_setgroups(struct lwp *l, kauth_cred_t ncred)
}
int
kauth_cred_getgroups(kauth_cred_t cred, gid_t *grbuf, size_t len)
kauth_cred_getgroups(kauth_cred_t cred, gid_t *grbuf, size_t len,
unsigned int flags)
{
KASSERT(cred != NULL);
KASSERT(len <= cred->cr_ngroups);
memset(grbuf, 0xff, sizeof(*grbuf) * len);
if (len > cred->cr_ngroups)
return EINVAL;
if ((flags & (UIO_USERSPACE | UIO_SYSSPACE)) == UIO_SYSSPACE)
return copyout(cred->cr_groups, grbuf, sizeof(*grbuf) * len);
memcpy(grbuf, cred->cr_groups, sizeof(*grbuf) * len);
return (0);
}
const gid_t *
kauth_cred_getgrlist(kauth_cred_t cred, int ngrp)
{
if (cred->cr_ngroups > ngrp)
return NULL;
return cred->cr_groups;
return 0;
}
int
@ -567,7 +565,7 @@ kauth_uucred_to_cred(kauth_cred_t cred, const struct uucred *uuc)
cred->cr_svgid = uuc->cr_gid;
cred->cr_ngroups = min(uuc->cr_ngroups, NGROUPS);
kauth_cred_setgroups(cred, __UNCONST(uuc->cr_groups),
cred->cr_ngroups, -1);
cred->cr_ngroups, -1, UIO_SYSSPACE);
}
/*
@ -585,7 +583,7 @@ kauth_cred_to_uucred(struct uucred *uuc, const kauth_cred_t cred)
uuc->cr_uid = cred->cr_euid;
uuc->cr_gid = cred->cr_egid;
uuc->cr_ngroups = ng;
kauth_cred_getgroups(cred, uuc->cr_groups, ng);
kauth_cred_getgroups(cred, uuc->cr_groups, ng, UIO_SYSSPACE);
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_prot.c,v 1.102 2007/06/23 09:08:37 dsl Exp $ */
/* $NetBSD: kern_prot.c,v 1.103 2007/06/30 13:32:14 dsl Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_prot.c,v 1.102 2007/06/23 09:08:37 dsl Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_prot.c,v 1.103 2007/06/30 13:32:14 dsl Exp $");
#include "opt_compat_43.h"
@ -61,8 +61,6 @@ __KERNEL_RCSID(0, "$NetBSD: kern_prot.c,v 1.102 2007/06/23 09:08:37 dsl Exp $");
#include <sys/mount.h>
#include <sys/syscallargs.h>
#include <sys/malloc.h>
int sys_getpid(struct lwp *, void *, register_t *);
int sys_getpid_with_ppid(struct lwp *, void *, register_t *);
int sys_getuid(struct lwp *, void *, register_t *);
@ -233,17 +231,15 @@ sys_getgroups(struct lwp *l, void *v, register_t *retval)
syscallarg(int) gidsetsize;
syscallarg(gid_t *) gidset;
} */ *uap = v;
const gid_t *grbuf;
*retval = kauth_cred_ngroups(l->l_cred);
if (SCARG(uap, gidsetsize) == 0)
return 0;
grbuf = kauth_cred_getgrlist(l->l_cred, SCARG(uap, gidsetsize));
if (grbuf == NULL)
if (SCARG(uap, gidsetsize) > *retval)
return EINVAL;
return copyout(grbuf, SCARG(uap, gidset), *retval * sizeof(gid_t));
return kauth_cred_getgroups(l->l_cred, SCARG(uap, gidset), *retval,
UIO_USERSPACE);
}
/* ARGSUSED */
@ -565,17 +561,10 @@ sys_setgroups(struct lwp *l, void *v, register_t *retval)
} */ *uap = v;
kauth_cred_t ncred;
int error;
gid_t *grbuf;
ncred = kauth_cred_alloc();
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));
}
error = kauth_cred_setgroups(ncred, SCARG(uap, gidset),
SCARG(uap, gidsetsize), -1, UIO_USERSPACE);
if (error != 0) {
kauth_cred_free(ncred);
return error;

View File

@ -1,4 +1,4 @@
/* $NetBSD: kauth.h,v 1.38 2007/06/23 09:02:12 dsl Exp $ */
/* $NetBSD: kauth.h,v 1.39 2007/06/30 13:32:14 dsl Exp $ */
/*-
* Copyright (c) 2005, 2006 Elad Efrat <elad@NetBSD.org>
@ -276,7 +276,6 @@ int kauth_authorize_device_passthru(kauth_cred_t, dev_t, u_long, void *);
kauth_cred_t kauth_cred_alloc(void);
void kauth_cred_free(kauth_cred_t);
void kauth_cred_clone(kauth_cred_t, kauth_cred_t);
void kauth_cred_clone1(kauth_cred_t, kauth_cred_t, bool);
kauth_cred_t kauth_cred_dup(kauth_cred_t);
kauth_cred_t kauth_cred_copy(kauth_cred_t);
@ -300,12 +299,11 @@ void kauth_cred_setsvgid(kauth_cred_t, gid_t);
void kauth_cred_hold(kauth_cred_t);
u_int kauth_cred_getrefcnt(kauth_cred_t);
int kauth_cred_setgroups(kauth_cred_t, gid_t *, size_t, uid_t);
int kauth_cred_getgroups(kauth_cred_t, gid_t *, size_t);
const gid_t *kauth_cred_getgrlist(kauth_cred_t, int);
int kauth_cred_setgroups(kauth_cred_t, const gid_t *, size_t, uid_t,
unsigned int);
int kauth_cred_getgroups(kauth_cred_t, gid_t *, size_t, unsigned int);
/* These 2 are for sys_setgroups() */
gid_t *kauth_cred_setngroups(kauth_cred_t, int);
/* This is for sys_setgroups() */
int kauth_proc_setgroups(struct lwp *, kauth_cred_t);
int kauth_register_key(const char *, kauth_key_t *);