Make mount(2) and unmount(2) use kauth(9) for security policy.
Okay yamt@.
This commit is contained in:
parent
6047a69a6e
commit
a13160f423
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: secmodel_example.c,v 1.10 2006/12/26 10:43:43 elad Exp $ */
|
||||
/* $NetBSD: secmodel_example.c,v 1.11 2007/01/02 10:47:29 elad Exp $ */
|
||||
|
||||
/*
|
||||
* This file is placed in the public domain.
|
||||
@ -13,7 +13,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: secmodel_example.c,v 1.10 2006/12/26 10:43:43 elad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: secmodel_example.c,v 1.11 2007/01/02 10:47:29 elad Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
@ -138,6 +138,18 @@ secmodel_example_system_cb(kauth_cred_t cred, kauth_action_t action,
|
||||
req = (enum kauth_system_req)arg0;
|
||||
|
||||
switch (action) {
|
||||
case KAUTH_SYSTEM_MOUNT:
|
||||
switch (req) {
|
||||
case KAUTH_REQ_SYSTEM_MOUNT_GET:
|
||||
case KAUTH_REQ_SYSTEM_MOUNT_NEW:
|
||||
case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT:
|
||||
case KAUTH_REQ_SYSTEM_MOUNT_UPDATE:
|
||||
default:
|
||||
result = KAUTH_RESULT_DEFER;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case KAUTH_SYSTEM_TIME:
|
||||
switch (req) {
|
||||
case KAUTH_REQ_SYSTEM_TIME_ADJTIME:
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: kauth.9,v 1.44 2007/01/01 23:33:03 elad Exp $
|
||||
.\" $NetBSD: kauth.9,v 1.45 2007/01/02 10:47:29 elad Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2005, 2006 Elad Efrat <elad@NetBSD.org>
|
||||
.\" All rights reserved.
|
||||
@ -28,7 +28,7 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd January 1, 2007
|
||||
.Dd January 2, 2007
|
||||
.Dt KAUTH 9
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -194,6 +194,60 @@ Check if an LKM request is allowed.
|
||||
is the command.
|
||||
.It Dv KAUTH_SYSTEM_MKNOD
|
||||
Check if creating devices is allowed.
|
||||
.It Dv KAUTH_SYSTEM_MOUNT
|
||||
Check if mount-related operations are allowed.
|
||||
.Pp
|
||||
.Ar req
|
||||
can be any of the following:
|
||||
.Bl -tag
|
||||
.It Dv KAUTH_REQ_SYSTEM_MOUNT_GET
|
||||
Check if retrieving information about a mount is allowed.
|
||||
.Ar arg1
|
||||
is a
|
||||
.Ft struct mount *
|
||||
with the mount structure in question,
|
||||
.Ar arg2
|
||||
is a
|
||||
.Ft void *
|
||||
with file-system specific data, if any.
|
||||
.It Dv KAUTH_REQ_SYSTEM_MOUNT_NEW
|
||||
Check if mounting a new file-system is allowed.
|
||||
.Pp
|
||||
.Ar arg1
|
||||
is the
|
||||
.Ft struct vnode *
|
||||
on which the file-system is to be mounted,
|
||||
.Ar arg2
|
||||
is an
|
||||
.Ft int
|
||||
with the mount flags, and
|
||||
.Ar arg3
|
||||
is a
|
||||
.Ft void *
|
||||
with file-system specific data, if any.
|
||||
.It Dv KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT
|
||||
Checks if unmounting a file-system is allowed.
|
||||
.Pp
|
||||
.Ar arg1
|
||||
is a
|
||||
.Ft struct mount *
|
||||
with the mount in question.
|
||||
.It Dv KAUTH_REQ_SYSTEM_MOUNT_UPDATE
|
||||
Checks if updating an existing mount is allowed.
|
||||
.Pp
|
||||
.Ar arg1
|
||||
is the
|
||||
.Ft struct mount *
|
||||
of the existing mount,
|
||||
.Ar arg2
|
||||
is an
|
||||
.Ft int
|
||||
with the new mount flags, and
|
||||
.Ar arg3
|
||||
is a
|
||||
.Ft void *
|
||||
with file-system specific data, if any.
|
||||
.El
|
||||
.It Dv KAUTH_SYSTEM_REBOOT
|
||||
Check if rebooting is allowed.
|
||||
.It Dv KAUTH_SYSTEM_SETIDCORE
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: vfs_syscalls.c,v 1.291 2007/01/01 22:00:16 pooka Exp $ */
|
||||
/* $NetBSD: vfs_syscalls.c,v 1.292 2007/01/02 10:47:29 elad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.291 2007/01/01 22:00:16 pooka Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.292 2007/01/02 10:47:29 elad Exp $");
|
||||
|
||||
#include "opt_compat_netbsd.h"
|
||||
#include "opt_compat_43.h"
|
||||
@ -170,39 +170,12 @@ mount_update(struct lwp *l, struct vnode *vp, const char *path, int flags,
|
||||
error = EOPNOTSUPP; /* Needs translation */
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* In "highly secure" mode, don't let the caller do anything
|
||||
* but downgrade a filesystem from read-write to read-only.
|
||||
*/
|
||||
if (securelevel >= 2 &&
|
||||
flags !=
|
||||
(mp->mnt_flag | MNT_RDONLY | MNT_RELOAD | MNT_FORCE | MNT_UPDATE)) {
|
||||
error = EPERM;
|
||||
|
||||
error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_MOUNT,
|
||||
KAUTH_REQ_SYSTEM_MOUNT_UPDATE, mp, KAUTH_ARG(flags), data);
|
||||
if (error)
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* Only root, or the user that did the original mount is
|
||||
* permitted to update it.
|
||||
*/
|
||||
if (mp->mnt_stat.f_owner != kauth_cred_geteuid(l->l_cred) &&
|
||||
(error = kauth_authorize_generic(l->l_cred,
|
||||
KAUTH_GENERIC_ISSUSER, NULL)) != 0) {
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* Do not allow NFS export by non-root users. For non-root
|
||||
* users, silently enforce MNT_NOSUID and MNT_NODEV, and
|
||||
* MNT_NOEXEC if mount point is already MNT_NOEXEC.
|
||||
*/
|
||||
if (kauth_cred_geteuid(l->l_cred) != 0) {
|
||||
if (flags & MNT_EXPORTED) {
|
||||
error = EPERM;
|
||||
goto out;
|
||||
}
|
||||
flags |= MNT_NOSUID | MNT_NODEV;
|
||||
if (saved_flags & MNT_NOEXEC)
|
||||
flags |= MNT_NOEXEC;
|
||||
}
|
||||
|
||||
if (vfs_busy(mp, LK_NOWAIT, 0)) {
|
||||
error = EPERM;
|
||||
goto out;
|
||||
@ -273,9 +246,9 @@ mount_domount(struct lwp *l, struct vnode *vp, const char *fstype,
|
||||
char fstypename[MFSNAMELEN];
|
||||
int error;
|
||||
|
||||
/* XXX secmodel stuff. */
|
||||
if (securelevel >= 2) {
|
||||
error = EPERM;
|
||||
error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_MOUNT,
|
||||
KAUTH_REQ_SYSTEM_MOUNT_NEW, vp, KAUTH_ARG(flags), data);
|
||||
if (error) {
|
||||
vput(vp);
|
||||
goto out;
|
||||
}
|
||||
@ -305,16 +278,6 @@ mount_domount(struct lwp *l, struct vnode *vp, const char *fstype,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* For non-root users, silently enforce MNT_NOSUID and MNT_NODEV.
|
||||
* Also propagate MNT_NOEXEC.
|
||||
*/
|
||||
if (kauth_cred_geteuid(l->l_cred) != 0) {
|
||||
flags |= MNT_NOSUID | MNT_NODEV;
|
||||
if (vp->v_mount->mnt_flag & MNT_NOEXEC)
|
||||
flags |= MNT_NOEXEC;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy file-system type from userspace.
|
||||
*/
|
||||
@ -442,6 +405,12 @@ mount_getargs(struct lwp *l, struct vnode *vp, const char *path, int flags,
|
||||
|
||||
mp = vp->v_mount;
|
||||
|
||||
/* XXX: probably some notion of "can see" here if we want isolation. */
|
||||
error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_MOUNT,
|
||||
KAUTH_REQ_SYSTEM_MOUNT_GET, mp, data, NULL);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
if ((vp->v_flag & VROOT) == 0) {
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
@ -476,12 +445,6 @@ sys_mount(struct lwp *l, void *v, register_t *retval)
|
||||
struct nameidata nd;
|
||||
int error;
|
||||
|
||||
/* XXX secmodel stuff. */
|
||||
if (dovfsusermount == 0 && (SCARG(uap, flags) & MNT_GETARGS) == 0 &&
|
||||
(error = kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER,
|
||||
&l->l_acflag)))
|
||||
return (error);
|
||||
|
||||
/*
|
||||
* Get vnode to be covered
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: secmodel_bsd44_securelevel.c,v 1.21 2006/12/31 10:38:18 elad Exp $ */
|
||||
/* $NetBSD: secmodel_bsd44_securelevel.c,v 1.22 2007/01/02 10:47:29 elad Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
|
||||
* All rights reserved.
|
||||
@ -38,7 +38,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: secmodel_bsd44_securelevel.c,v 1.21 2006/12/31 10:38:18 elad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: secmodel_bsd44_securelevel.c,v 1.22 2007/01/02 10:47:29 elad Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_insecure.h"
|
||||
@ -170,6 +170,37 @@ secmodel_bsd44_securelevel_system_cb(kauth_cred_t cred,
|
||||
result = KAUTH_RESULT_ALLOW;
|
||||
break;
|
||||
|
||||
case KAUTH_SYSTEM_MOUNT:
|
||||
switch (req) {
|
||||
case KAUTH_REQ_SYSTEM_MOUNT_NEW:
|
||||
if (securelevel > 1)
|
||||
break;
|
||||
|
||||
result = KAUTH_RESULT_ALLOW;
|
||||
break;
|
||||
|
||||
case KAUTH_REQ_SYSTEM_MOUNT_UPDATE:
|
||||
if (securelevel > 1) {
|
||||
struct mount *mp = arg1;
|
||||
u_long flags = (u_long)arg2;
|
||||
|
||||
/* Can only degrade from read/write to read-only. */
|
||||
if (flags != (mp->mnt_flag | MNT_RDONLY | MNT_RELOAD |
|
||||
MNT_FORCE | MNT_UPDATE))
|
||||
break;
|
||||
}
|
||||
|
||||
result = KAUTH_RESULT_ALLOW;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
result = KAUTH_RESULT_DEFER;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case KAUTH_SYSTEM_SYSCTL:
|
||||
switch (req) {
|
||||
case KAUTH_REQ_SYSTEM_SYSCTL_ADD:
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: secmodel_bsd44_suser.c,v 1.23 2006/12/27 10:02:46 elad Exp $ */
|
||||
/* $NetBSD: secmodel_bsd44_suser.c,v 1.24 2007/01/02 10:47:29 elad Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
|
||||
* All rights reserved.
|
||||
@ -41,7 +41,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: secmodel_bsd44_suser.c,v 1.23 2006/12/27 10:02:46 elad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: secmodel_bsd44_suser.c,v 1.24 2007/01/02 10:47:29 elad Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
@ -60,6 +60,8 @@ __KERNEL_RCSID(0, "$NetBSD: secmodel_bsd44_suser.c,v 1.23 2006/12/27 10:02:46 el
|
||||
|
||||
#include <secmodel/bsd44/suser.h>
|
||||
|
||||
extern int dovfsusermount;
|
||||
|
||||
void
|
||||
secmodel_bsd44_suser_start(void)
|
||||
{
|
||||
@ -138,6 +140,83 @@ secmodel_bsd44_suser_system_cb(kauth_cred_t cred, kauth_action_t action,
|
||||
req = (enum kauth_system_req)arg0;
|
||||
|
||||
switch (action) {
|
||||
case KAUTH_SYSTEM_MOUNT:
|
||||
switch (req) {
|
||||
case KAUTH_REQ_SYSTEM_MOUNT_GET:
|
||||
result = KAUTH_RESULT_ALLOW;
|
||||
break;
|
||||
|
||||
case KAUTH_REQ_SYSTEM_MOUNT_NEW:
|
||||
if (isroot)
|
||||
result = KAUTH_RESULT_ALLOW;
|
||||
else if (dovfsusermount) {
|
||||
struct vnode *vp = arg1;
|
||||
u_long flags = (u_long)arg2;
|
||||
|
||||
if (!(flags & MNT_NODEV) ||
|
||||
!(flags & MNT_NOSUID))
|
||||
break;
|
||||
|
||||
if ((vp->v_mount->mnt_flag & MNT_NOEXEC) &&
|
||||
!(flags & MNT_NOEXEC))
|
||||
break;
|
||||
|
||||
result = KAUTH_RESULT_ALLOW;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT:
|
||||
if (isroot)
|
||||
result = KAUTH_RESULT_ALLOW;
|
||||
else {
|
||||
struct mount *mp = arg1;
|
||||
|
||||
if (mp->mnt_stat.f_owner ==
|
||||
kauth_cred_geteuid(cred))
|
||||
result = KAUTH_RESULT_ALLOW;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case KAUTH_REQ_SYSTEM_MOUNT_UPDATE:
|
||||
if (isroot)
|
||||
result = KAUTH_RESULT_ALLOW;
|
||||
else if (dovfsusermount) {
|
||||
struct mount *mp = arg1;
|
||||
u_long flags = (u_long)arg2;
|
||||
|
||||
/* No exporting for non-root. */
|
||||
if (flags & MNT_EXPORTED)
|
||||
break;
|
||||
|
||||
if (!(flags & MNT_NODEV) ||
|
||||
!(flags & MNT_NOSUID))
|
||||
break;
|
||||
|
||||
/*
|
||||
* Only super-user, or user that did the mount,
|
||||
* can update.
|
||||
*/
|
||||
if (mp->mnt_stat.f_owner !=
|
||||
kauth_cred_geteuid(cred))
|
||||
break;
|
||||
|
||||
/* Retain 'noexec'. */
|
||||
if ((mp->mnt_flag & MNT_NOEXEC) &&
|
||||
!(flags & MNT_NOEXEC))
|
||||
break;
|
||||
|
||||
result = KAUTH_RESULT_ALLOW;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
result = KAUTH_RESULT_DEFER;
|
||||
break;
|
||||
}
|
||||
|
||||
case KAUTH_SYSTEM_TIME:
|
||||
switch (req) {
|
||||
case KAUTH_REQ_SYSTEM_TIME_ADJTIME:
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: kauth.h,v 1.29 2006/12/26 10:43:44 elad Exp $ */
|
||||
/* $NetBSD: kauth.h,v 1.30 2007/01/02 10:47:28 elad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005, 2006 Elad Efrat <elad@NetBSD.org>
|
||||
@ -87,6 +87,7 @@ enum {
|
||||
KAUTH_SYSTEM_FILEHANDLE,
|
||||
KAUTH_SYSTEM_LKM,
|
||||
KAUTH_SYSTEM_MKNOD,
|
||||
KAUTH_SYSTEM_MOUNT,
|
||||
KAUTH_SYSTEM_REBOOT,
|
||||
KAUTH_SYSTEM_SETIDCORE,
|
||||
KAUTH_SYSTEM_SWAPCTL,
|
||||
@ -101,6 +102,10 @@ enum kauth_system_req {
|
||||
KAUTH_REQ_SYSTEM_CHROOT_CHROOT=1,
|
||||
KAUTH_REQ_SYSTEM_CHROOT_FCHROOT,
|
||||
KAUTH_REQ_SYSTEM_DEBUG_IPKDB,
|
||||
KAUTH_REQ_SYSTEM_MOUNT_GET,
|
||||
KAUTH_REQ_SYSTEM_MOUNT_NEW,
|
||||
KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT,
|
||||
KAUTH_REQ_SYSTEM_MOUNT_UPDATE,
|
||||
KAUTH_REQ_SYSTEM_SYSCTL_ADD,
|
||||
KAUTH_REQ_SYSTEM_SYSCTL_DELETE,
|
||||
KAUTH_REQ_SYSTEM_SYSCTL_DESC,
|
||||
|
Loading…
Reference in New Issue
Block a user