Add genfs_can_mount() and use it to prevent some more code duplication of
the security checks when mounting a device (VOP_ACCESS() + kauth(9) call)). Proposed with no objections on tech-kern@: http://mail-index.netbsd.org/tech-kern/2009/04/20/msg004859.html The vnode is always expected to be locked, so no locking is done outside the file-system code.
This commit is contained in:
parent
bab57db991
commit
54bf8cc67a
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udf_vfsops.c,v 1.55 2009/02/08 19:04:41 reinoud Exp $ */
|
||||
/* $NetBSD: udf_vfsops.c,v 1.56 2009/04/25 18:53:45 elad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006, 2008 Reinoud Zandijk
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_vfsops.c,v 1.55 2009/02/08 19:04:41 reinoud Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_vfsops.c,v 1.56 2009/04/25 18:53:45 elad Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
@ -378,17 +378,15 @@ udf_mount(struct mount *mp, const char *path,
|
||||
* If mount by non-root, then verify that user has necessary
|
||||
* permissions on the device.
|
||||
*/
|
||||
if (kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, NULL)) {
|
||||
accessmode = VREAD;
|
||||
if ((mp->mnt_flag & MNT_RDONLY) == 0)
|
||||
accessmode |= VWRITE;
|
||||
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
|
||||
error = VOP_ACCESS(devvp, accessmode, l->l_cred);
|
||||
VOP_UNLOCK(devvp, 0);
|
||||
if (error) {
|
||||
vrele(devvp);
|
||||
return error;
|
||||
}
|
||||
accessmode = VREAD;
|
||||
if ((mp->mnt_flag & MNT_RDONLY) == 0)
|
||||
accessmode |= VWRITE;
|
||||
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
|
||||
error = genfs_can_mount(devvp, accessmode, l->l_cred);
|
||||
VOP_UNLOCK(devvp, 0);
|
||||
if (error) {
|
||||
vrele(devvp);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: genfs.h,v 1.24 2009/04/22 22:57:08 elad Exp $ */
|
||||
/* $NetBSD: genfs.h,v 1.25 2009/04/25 18:53:44 elad Exp $ */
|
||||
|
||||
#ifndef _MISCFS_GENFS_GENFS_H_
|
||||
#define _MISCFS_GENFS_GENFS_H_
|
||||
@ -38,5 +38,6 @@ void genfs_renamelock_exit(struct mount *);
|
||||
|
||||
int genfs_can_chmod(vnode_t *, kauth_cred_t, uid_t, gid_t, mode_t);
|
||||
int genfs_can_chown(vnode_t *, kauth_cred_t, uid_t, gid_t, uid_t, gid_t);
|
||||
int genfs_can_mount(vnode_t *, mode_t, kauth_cred_t);
|
||||
|
||||
#endif /* !_MISCFS_GENFS_GENFS_H_ */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: genfs_vnops.c,v 1.169 2009/04/22 22:57:08 elad Exp $ */
|
||||
/* $NetBSD: genfs_vnops.c,v 1.170 2009/04/25 18:53:44 elad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
@ -57,7 +57,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.169 2009/04/22 22:57:08 elad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.170 2009/04/25 18:53:44 elad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -642,3 +642,26 @@ genfs_can_chown(vnode_t *vp, kauth_cred_t cred, uid_t cur_uid,
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Common routine to check if the device can be mounted.
|
||||
*
|
||||
* devvp - the locked vnode of the device
|
||||
* cred - credentials of the invoker
|
||||
* accessmode - the accessmode (VREAD, VWRITE)
|
||||
*
|
||||
* Returns 0 if the mount is allowed, or an error value otherwise.
|
||||
*/
|
||||
int
|
||||
genfs_can_mount(vnode_t *devvp, mode_t accessmode, kauth_cred_t cred)
|
||||
{
|
||||
int error;
|
||||
|
||||
/* Always allow for root. */
|
||||
error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
|
||||
if (!error)
|
||||
return (0);
|
||||
|
||||
error = VOP_ACCESS(devvp, accessmode, cred);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ext2fs_vfsops.c,v 1.142 2009/03/01 15:59:57 christos Exp $ */
|
||||
/* $NetBSD: ext2fs_vfsops.c,v 1.143 2009/04/25 18:53:45 elad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1991, 1993, 1994
|
||||
@ -65,7 +65,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ext2fs_vfsops.c,v 1.142 2009/03/01 15:59:57 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ext2fs_vfsops.c,v 1.143 2009/04/25 18:53:45 elad Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_compat_netbsd.h"
|
||||
@ -380,18 +380,19 @@ ext2fs_mount(struct mount *mp, const char *path, void *data, size_t *data_len)
|
||||
/*
|
||||
* If mount by non-root, then verify that user has necessary
|
||||
* permissions on the device.
|
||||
*
|
||||
* Permission to update a mount is checked higher, so here we presume
|
||||
* updating the mount is okay (for example, as far as securelevel goes)
|
||||
* which leaves us with the normal check.
|
||||
*/
|
||||
if (error == 0 && kauth_authorize_generic(l->l_cred,
|
||||
KAUTH_GENERIC_ISSUSER, NULL) != 0) {
|
||||
accessmode = VREAD;
|
||||
if (update ?
|
||||
(mp->mnt_iflag & IMNT_WANTRDWR) != 0 :
|
||||
(mp->mnt_flag & MNT_RDONLY) == 0)
|
||||
accessmode |= VWRITE;
|
||||
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
|
||||
error = VOP_ACCESS(devvp, accessmode, l->l_cred);
|
||||
VOP_UNLOCK(devvp, 0);
|
||||
}
|
||||
accessmode = VREAD;
|
||||
if (update ?
|
||||
(mp->mnt_iflag & IMNT_WANTRDWR) != 0 :
|
||||
(mp->mnt_flag & MNT_RDONLY) == 0)
|
||||
accessmode |= VWRITE;
|
||||
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
|
||||
error = genfs_can_mount(devvp, accessmode, l->l_cred);
|
||||
VOP_UNLOCK(devvp, 0);
|
||||
|
||||
if (error) {
|
||||
vrele(devvp);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ffs_vfsops.c,v 1.245 2009/03/29 10:29:00 ad Exp $ */
|
||||
/* $NetBSD: ffs_vfsops.c,v 1.246 2009/04/25 18:53:45 elad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
|
||||
@ -61,7 +61,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.245 2009/03/29 10:29:00 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.246 2009/04/25 18:53:45 elad Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_ffs.h"
|
||||
@ -381,18 +381,19 @@ ffs_mount(struct mount *mp, const char *path, void *data, size_t *data_len)
|
||||
/*
|
||||
* If mount by non-root, then verify that user has necessary
|
||||
* permissions on the device.
|
||||
*
|
||||
* Permission to update a mount is checked higher, so here we presume
|
||||
* updating the mount is okay (for example, as far as securelevel goes)
|
||||
* which leaves us with the normal check.
|
||||
*/
|
||||
if (error == 0 && kauth_authorize_generic(l->l_cred,
|
||||
KAUTH_GENERIC_ISSUSER, NULL) != 0) {
|
||||
accessmode = VREAD;
|
||||
if (update ?
|
||||
(mp->mnt_iflag & IMNT_WANTRDWR) != 0 :
|
||||
(mp->mnt_flag & MNT_RDONLY) == 0)
|
||||
accessmode |= VWRITE;
|
||||
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
|
||||
error = VOP_ACCESS(devvp, accessmode, l->l_cred);
|
||||
VOP_UNLOCK(devvp, 0);
|
||||
}
|
||||
accessmode = VREAD;
|
||||
if (update ?
|
||||
(mp->mnt_iflag & IMNT_WANTRDWR) != 0 :
|
||||
(mp->mnt_flag & MNT_RDONLY) == 0)
|
||||
accessmode |= VWRITE;
|
||||
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
|
||||
error = genfs_can_mount(devvp, accessmode, l->l_cred);
|
||||
VOP_UNLOCK(devvp, 0);
|
||||
|
||||
if (error) {
|
||||
vrele(devvp);
|
||||
|
Loading…
Reference in New Issue
Block a user