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:
parent
5092d42715
commit
04c196a642
@ -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)) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
|
@ -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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user