Subject: Re: CVS commit: src/sys/secmodel/bsd44
To: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
From: Elad Efrat <elad@NetBSD.org>
List: tech-kern
Date: 11/03/2006 18:37:59
This is a multi-part message in MIME format.
--Boundary_(ID_95KQ1E/+D2UCYjnaWwoudg)
Content-type: text/plain; charset=ISO-8859-1
Content-transfer-encoding: 7BIT
YAMAMOTO Takashi wrote:
>> what do we pass to iskmemdev()? I assume we don't want to issue a
>> VOP_GETATTR() on vp?
>
> (vp->v_type == VCHR && iskmemdev(vp->v_rdev)) should work.
okay, see attached diff.
-e.
--
Elad Efrat
--Boundary_(ID_95KQ1E/+D2UCYjnaWwoudg)
Content-type: text/plain; name=rawio.diff
Content-transfer-encoding: 7BIT
Content-disposition: inline; filename=rawio.diff
Index: sys/kauth.h
===================================================================
RCS file: /cvsroot/src/sys/sys/kauth.h,v
retrieving revision 1.16
diff -u -p -r1.16 kauth.h
--- sys/kauth.h 25 Oct 2006 22:49:23 -0000 1.16
+++ sys/kauth.h 3 Nov 2006 16:35:13 -0000
@@ -86,7 +86,6 @@ enum {
KAUTH_SYSTEM_FILEHANDLE,
KAUTH_SYSTEM_LKM,
KAUTH_SYSTEM_MKNOD,
- KAUTH_SYSTEM_RAWIO,
KAUTH_SYSTEM_REBOOT,
KAUTH_SYSTEM_SETIDCORE,
KAUTH_SYSTEM_SWAPCTL,
@@ -101,11 +100,6 @@ enum kauth_system_req {
KAUTH_REQ_SYSTEM_CHROOT_CHROOT=1,
KAUTH_REQ_SYSTEM_CHROOT_FCHROOT,
KAUTH_REQ_SYSTEM_DEBUG_IPKDB,
- KAUTH_REQ_SYSTEM_RAWIO_DISK,
- KAUTH_REQ_SYSTEM_RAWIO_MEMORY,
- KAUTH_REQ_SYSTEM_RAWIO_READ,
- KAUTH_REQ_SYSTEM_RAWIO_RW,
- KAUTH_REQ_SYSTEM_RAWIO_WRITE,
KAUTH_REQ_SYSTEM_SYSCTL_ADD,
KAUTH_REQ_SYSTEM_SYSCTL_DELETE,
KAUTH_REQ_SYSTEM_SYSCTL_DESC,
@@ -201,7 +195,18 @@ enum kauth_machdep_req {
*/
enum {
KAUTH_DEVICE_TTY_OPEN=1,
- KAUTH_DEVICE_TTY_PRIVSET
+ KAUTH_DEVICE_TTY_PRIVSET,
+ KAUTH_DEVICE_RAWIO_SPEC,
+ KAUTH_DEVICE_RAWIO_PASSTHRU
+};
+
+/*
+ * Device scope - sub-actions.
+ */
+enum kauth_device_req {
+ KAUTH_REQ_DEVICE_RAWIO_SPEC_READ,
+ KAUTH_REQ_DEVICE_RAWIO_SPEC_WRITE,
+ KAUTH_REQ_DEVICE_RAWIO_SPEC_RW,
};
#define NOCRED ((kauth_cred_t)-1) /* no credential available */
@@ -229,6 +234,9 @@ int kauth_authorize_network(kauth_cred_t
int kauth_authorize_machdep(kauth_cred_t, kauth_action_t,
enum kauth_machdep_req, void *, void *, void *);
int kauth_authorize_device_tty(kauth_cred_t, kauth_action_t, struct tty *);
+int kauth_authorize_device_spec(kauth_cred_t, enum kauth_device_req,
+ struct vnode *);
+int kauth_authorize_device_passthru(kauth_cred_t, dev_t, void *);
/* Kauth credentials management routines. */
kauth_cred_t kauth_cred_alloc(void);
Index: sys/conf.h
===================================================================
RCS file: /cvsroot/src/sys/sys/conf.h,v
retrieving revision 1.124
diff -u -p -r1.124 conf.h
--- sys/conf.h 9 Oct 2006 07:56:33 -0000 1.124
+++ sys/conf.h 3 Nov 2006 16:35:13 -0000
@@ -192,6 +192,8 @@ void ttyldisc_release(struct line
int ttyerrpoll (struct tty *, int, struct lwp *);
int ttynullioctl(struct tty *, u_long, caddr_t, int, struct lwp *);
+
+int iskmemdev(dev_t);
#endif
#ifdef _KERNEL
Index: kern/kern_auth.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_auth.c,v
retrieving revision 1.29
diff -u -p -r1.29 kern_auth.c
--- kern/kern_auth.c 22 Oct 2006 13:07:15 -0000 1.29
+++ kern/kern_auth.c 3 Nov 2006 16:35:15 -0000
@@ -818,3 +818,19 @@ kauth_authorize_device_tty(kauth_cred_t
return (kauth_authorize_action(kauth_builtin_scope_device, cred,
action, tty, NULL, NULL, NULL));
}
+
+int
+kauth_authorize_device_spec(kauth_cred_t cred, enum kauth_device_req req,
+ struct vnode *vp)
+{
+ return (kauth_authorize_action(kauth_builtin_scope_device, cred,
+ KAUTH_DEVICE_RAWIO_SPEC, (void *)req, vp, NULL, NULL));
+}
+
+int
+kauth_authorize_device_passthru(kauth_cred_t cred, dev_t dev, void *data)
+{
+ return (kauth_authorize_action(kauth_builtin_scope_device, cred,
+ KAUTH_DEVICE_RAWIO_PASSTHRU, 0, (void *)(u_long)dev, data,
+ NULL));
+}
Index: miscfs/specfs/spec_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/specfs/spec_vnops.c,v
retrieving revision 1.95
diff -u -p -r1.95 spec_vnops.c
--- miscfs/specfs/spec_vnops.c 2 Nov 2006 12:48:35 -0000 1.95
+++ miscfs/specfs/spec_vnops.c 3 Nov 2006 16:35:15 -0000
@@ -154,7 +154,7 @@ spec_lookup(v)
/*
* Returns true if dev is /dev/mem or /dev/kmem.
*/
-static int
+int
iskmemdev(dev_t dev)
{
/* mem_no is emitted by config(8) to generated devsw.c */
@@ -186,6 +186,7 @@ spec_open(v)
int error;
struct partinfo pi;
int (*d_ioctl)(dev_t, u_long, caddr_t, int, struct lwp *);
+ enum kauth_device_req req;
/*
* Don't allow open if fs is mounted -nodev.
@@ -193,9 +194,10 @@ spec_open(v)
if (vp->v_mount && (vp->v_mount->mnt_flag & MNT_NODEV))
return (ENXIO);
-#define M2K(m) (((m) & FREAD) && ((m) & FWRITE) ? KAUTH_REQ_SYSTEM_RAWIO_RW : \
- (m) & FWRITE ? KAUTH_REQ_SYSTEM_RAWIO_WRITE : \
- KAUTH_REQ_SYSTEM_RAWIO_READ)
+#define M2K(m) (((m) & FREAD) && ((m) & FWRITE) ? \
+ KAUTH_REQ_DEVICE_RAWIO_SPEC_RW : \
+ (m) & FWRITE ? KAUTH_REQ_DEVICE_RAWIO_SPEC_WRITE : \
+ KAUTH_REQ_DEVICE_RAWIO_SPEC_READ)
switch (vp->v_type) {
@@ -204,49 +206,32 @@ spec_open(v)
if (cdev == NULL)
return (ENXIO);
- if (ap->a_cred != FSCRED) {
- u_long rw;
+ req = M2K(ap->a_mode);
- rw = M2K(ap->a_mode);
- error = 0;
+ error = kauth_authorize_device_spec(ap->a_cred, req, vp);
+ if (error)
+ return (error);
- /* XXX we're holding a vnode lock here */
+#if NVERIEXEC > 0
+ if (ap->a_mode & FWRITE) {
if (iskmemdev(dev)) {
- error = kauth_authorize_system(ap->a_cred,
- KAUTH_SYSTEM_RAWIO,
- KAUTH_REQ_SYSTEM_RAWIO_MEMORY,
- (void *)rw, NULL, NULL);
+ if (veriexec_strict >= VERIEXEC_IPS)
+ return (EPERM);
} else {
- error = kauth_authorize_system(ap->a_cred,
- KAUTH_SYSTEM_RAWIO,
- KAUTH_REQ_SYSTEM_RAWIO_DISK,
- (void *)rw, vp, (void *)(u_long)dev);
- }
+ struct vnode *bvp;
+ dev_t blkdev;
- if (error)
- return (error);
-
-#if NVERIEXEC > 0
- if (ap->a_mode & FWRITE) {
- if (iskmemdev(dev)) {
- if (veriexec_strict >= VERIEXEC_IPS)
- return (EPERM);
- } else {
- struct vnode *bvp;
- dev_t blkdev;
-
- blkdev = devsw_chr2blk(dev);
- if (blkdev != NODEV) {
- bvp = NULL;
- vfinddev(blkdev, VBLK, &bvp);
- error = veriexec_rawchk(bvp);
- if (error)
- return (error);
- }
+ blkdev = devsw_chr2blk(dev);
+ if (blkdev != NODEV) {
+ bvp = NULL;
+ vfinddev(blkdev, VBLK, &bvp);
+ error = veriexec_rawchk(bvp);
+ if (error)
+ return (error);
}
}
-#endif /* NVERIEXEC > 0 */
}
+#endif /* NVERIEXEC > 0 */
if (cdev->d_type == D_TTY)
vp->v_flag |= VISTTY;
@@ -263,25 +248,11 @@ spec_open(v)
if (bdev == NULL)
return (ENXIO);
- /*
- * When running in very secure mode, do not allow
- * opens for writing of any disk block devices.
- */
- if (ap->a_cred != FSCRED) {
- u_long rw;
-
- if ((error = vfs_mountedon(vp)) != 0)
- return (error);
-
- rw = M2K(ap->a_mode);
+ req = M2K(ap->a_mode);
- error = kauth_authorize_system(ap->a_cred,
- KAUTH_SYSTEM_RAWIO,
- KAUTH_REQ_SYSTEM_RAWIO_DISK,
- (void *)rw, vp, (void *)(u_long)dev);
- if (error)
- return (error);
- }
+ error = kauth_authorize_device_spec(ap->a_cred, req, vp);
+ if (error)
+ return (error);
#if NVERIEXEC > 0
error = veriexec_rawchk(vp);
Index: secmodel/bsd44/secmodel_bsd44_securelevel.c
===================================================================
RCS file: /cvsroot/src/sys/secmodel/bsd44/secmodel_bsd44_securelevel.c,v
retrieving revision 1.9
diff -u -p -r1.9 secmodel_bsd44_securelevel.c
--- secmodel/bsd44/secmodel_bsd44_securelevel.c 12 Oct 2006 01:32:50 -0000 1.9
+++ secmodel/bsd44/secmodel_bsd44_securelevel.c 3 Nov 2006 16:35:16 -0000
@@ -53,6 +53,8 @@ __KERNEL_RCSID(0, "$NetBSD: secmodel_bsd
#include <sys/sysctl.h>
#include <sys/vnode.h>
+#include <miscfs/specfs/specdev.h>
+
#include <secmodel/bsd44/securelevel.h>
/*
@@ -126,6 +128,8 @@ secmodel_bsd44_securelevel_start(void)
secmodel_bsd44_securelevel_network_cb, NULL);
kauth_listen_scope(KAUTH_SCOPE_MACHDEP,
secmodel_bsd44_securelevel_machdep_cb, NULL);
+ kauth_listen_scope(KAUTH_SCOPE_DEVICE,
+ secmodel_bsd44_securelevel_device_cb, NULL);
}
/*
@@ -147,127 +151,6 @@ secmodel_bsd44_securelevel_system_cb(kau
req = (enum kauth_system_req)arg0;
switch (action) {
- case KAUTH_SYSTEM_RAWIO: {
- u_int rw;
-
- rw = (u_int)(u_long)arg1;
-
- switch (req) {
- case KAUTH_REQ_SYSTEM_RAWIO_MEMORY: {
- switch (rw) {
- case KAUTH_REQ_SYSTEM_RAWIO_READ:
- result = KAUTH_RESULT_ALLOW;
- break;
-
- case KAUTH_REQ_SYSTEM_RAWIO_WRITE:
- case KAUTH_REQ_SYSTEM_RAWIO_RW:
- if (securelevel < 1)
- result = KAUTH_RESULT_ALLOW;
- break;
-
- default:
- result = KAUTH_RESULT_DEFER;
- break;
- }
-
- break;
- }
-
- case KAUTH_REQ_SYSTEM_RAWIO_DISK: {
- struct vnode *vp = arg2;
- dev_t dev = (dev_t)(u_long)arg3;
-
- if (vp == NULL || dev == NODEV) {
- switch (rw) {
- case KAUTH_REQ_SYSTEM_RAWIO_READ:
- result = KAUTH_RESULT_ALLOW;
- break;
-
- case KAUTH_REQ_SYSTEM_RAWIO_RW:
- case KAUTH_REQ_SYSTEM_RAWIO_WRITE:
- if (securelevel < 1)
- result = KAUTH_RESULT_ALLOW;
- break;
-
- default:
- result = KAUTH_RESULT_DEFER;
- break;
- }
-
- break;
- }
-
- switch (vp->v_type) {
- case VCHR: {
- const struct cdevsw *cdev;
- struct vnode *bvp;
-
- switch (rw) {
- case KAUTH_REQ_SYSTEM_RAWIO_READ:
- result = KAUTH_RESULT_ALLOW;
- break;
-
- case KAUTH_REQ_SYSTEM_RAWIO_WRITE:
- case KAUTH_REQ_SYSTEM_RAWIO_RW:
- cdev = cdevsw_lookup(dev);
- if (cdev == NULL)
- break;
-
- if (cdev->d_type == D_DISK &&
- securelevel > 1)
- break;
-
- bvp = NULL;
- vfinddev(devsw_chr2blk(dev), VBLK, &bvp);
- if (bvp != NULL) {
- if (vfs_mountedon(bvp) &&
- securelevel > 0)
- break;
- }
-
- result = KAUTH_RESULT_ALLOW;
-
- break;
-
- default:
- result = KAUTH_RESULT_DEFER;
- break;
- }
-
- break;
- }
-
- case VBLK: {
- const struct bdevsw *bdev;
-
- bdev = bdevsw_lookup(dev);
- if (bdev == NULL)
- break;
-
- if (bdev->d_type == D_DISK &&
- rw != KAUTH_REQ_SYSTEM_RAWIO_READ &&
- securelevel > 1)
- break;
-
- result = KAUTH_RESULT_ALLOW;
-
- break;
- }
-
- default:
- result = KAUTH_RESULT_DEFER;
- break;
- }
- break;
- }
-
- default:
- result = KAUTH_RESULT_DEFER;
- break;
- }
- break;
- }
-
case KAUTH_SYSTEM_TIME:
switch (req) {
case KAUTH_REQ_SYSTEM_TIME_BACKWARDS:
@@ -448,3 +331,123 @@ secmodel_bsd44_securelevel_machdep_cb(ka
return (result);
}
+
+/*
+ * kauth(9) listener
+ *
+ * Security model: Traditional NetBSD
+ * Scope: Device
+ * Responsibility: Securelevel
+ */
+int
+secmodel_bsd44_securelevel_device_cb(kauth_cred_t cred __unused,
+ kauth_action_t action, void *cookie __unused, void *arg0,
+ void *arg1, void *arg2 __unused, void *arg3 __unused)
+{
+ int result;
+ enum kauth_device_req req;
+
+ result = KAUTH_RESULT_DENY;
+ req = (enum kauth_device_req)arg0;
+
+ switch (action) {
+ case KAUTH_DEVICE_RAWIO_SPEC: {
+ struct vnode *vp;
+ dev_t dev;
+
+ vp = arg1;
+
+ if (vp == NULL) {
+ result = KAUTH_RESULT_ALLOW;
+ break;
+ }
+
+ dev = vp->v_un.vu_specinfo->si_rdev;
+
+ /* Handle /dev/mem and /dev/kmem. */
+ if ((vp->v_type == VCHR) && iskmemdev(dev)) {
+ switch (req) {
+ case KAUTH_REQ_DEVICE_RAWIO_SPEC_READ:
+ result = KAUTH_RESULT_ALLOW;
+ break;
+
+ case KAUTH_REQ_DEVICE_RAWIO_SPEC_WRITE:
+ case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW:
+ if (securelevel < 1)
+ result = KAUTH_RESULT_ALLOW;
+ break;
+
+ default:
+ result = KAUTH_RESULT_DEFER;
+ break;
+ }
+
+ break;
+ }
+
+ switch (req) {
+ case KAUTH_REQ_DEVICE_RAWIO_SPEC_READ:
+ result = KAUTH_RESULT_ALLOW;
+ break;
+
+ case KAUTH_REQ_DEVICE_RAWIO_SPEC_WRITE:
+ case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW:
+ switch (vp->v_type) {
+ case VCHR: {
+ const struct cdevsw *cdev;
+
+ cdev = cdevsw_lookup(dev);
+ if ((cdev == NULL) ||
+ (cdev->d_type != D_DISK)) {
+ result = KAUTH_RESULT_ALLOW;
+ break;
+ }
+
+ break;
+ }
+ case VBLK: {
+ const struct bdevsw *bdev;
+
+ bdev = bdevsw_lookup(dev);
+ if ((bdev == NULL) ||
+ (bdev->d_type != D_DISK)) {
+ result = KAUTH_RESULT_ALLOW;
+ break;
+ }
+
+ break;
+ }
+ default:
+ result = KAUTH_RESULT_DEFER;
+ break;
+ }
+
+ if (vfs_mountedon(vp) && (securelevel > 0))
+ break;
+
+ if (securelevel < 2)
+ result = KAUTH_RESULT_ALLOW;
+
+ break;
+
+ default:
+ result = KAUTH_RESULT_DEFER;
+ break;
+ }
+
+ break;
+ }
+
+ case KAUTH_DEVICE_RAWIO_PASSTHRU:
+ if (securelevel < 1)
+ result = KAUTH_RESULT_ALLOW;
+
+ break;
+
+ default:
+ result = KAUTH_RESULT_DEFER;
+ break;
+ }
+
+ return (result);
+}
--Boundary_(ID_95KQ1E/+D2UCYjnaWwoudg)--