Module Name: src
Committed By: mbalmer
Date: Fri Aug 14 21:17:22 UTC 2009
Modified Files:
src/distrib/sets/lists/man: mi
src/share/man/man4: Makefile
src/sys/conf: files
src/sys/dev/gpio: files.gpio
src/sys/secmodel: files.secmodel
src/sys/sys: Makefile
Added Files:
src/share/man/man4: gpiolock.4
src/sys/dev: keylock.c
src/sys/dev/gpio: gpiolock.c
src/sys/secmodel/keylock: files.keylock keylock.h secmodel_keylock.c
src/sys/sys: keylock.h
Log Message:
Add support for multi-position electro-mechanical keylocks. An example
driver, gpiolock(4), is provided as an example how to interface real hardware.
A new securemodel, securemodel_keylock, is provided to show how this can
be used to tie keylocks to overall system security. This is experimental
code. The diff has been on tech-kern for several weeks.
Reviewed by many, kauth(9) integration reviewed by Elad Efrat; approved by
tonnerre@ and t...@. Thanks to everyone who provided feedback.
To generate a diff of this commit:
cvs rdiff -u -r1.1152 -r1.1153 src/distrib/sets/lists/man/mi
cvs rdiff -u -r1.496 -r1.497 src/share/man/man4/Makefile
cvs rdiff -u -r0 -r1.1 src/share/man/man4/gpiolock.4
cvs rdiff -u -r1.952 -r1.953 src/sys/conf/files
cvs rdiff -u -r0 -r1.1 src/sys/dev/keylock.c
cvs rdiff -u -r1.7 -r1.8 src/sys/dev/gpio/files.gpio
cvs rdiff -u -r0 -r1.1 src/sys/dev/gpio/gpiolock.c
cvs rdiff -u -r1.2 -r1.3 src/sys/secmodel/files.secmodel
cvs rdiff -u -r0 -r1.1 src/sys/secmodel/keylock/files.keylock \
src/sys/secmodel/keylock/keylock.h \
src/sys/secmodel/keylock/secmodel_keylock.c
cvs rdiff -u -r1.118 -r1.119 src/sys/sys/Makefile
cvs rdiff -u -r0 -r1.1 src/sys/sys/keylock.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/distrib/sets/lists/man/mi
diff -u src/distrib/sets/lists/man/mi:1.1152 src/distrib/sets/lists/man/mi:1.1153
--- src/distrib/sets/lists/man/mi:1.1152 Sun Aug 9 08:20:53 2009
+++ src/distrib/sets/lists/man/mi Fri Aug 14 21:17:21 2009
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1152 2009/08/09 08:20:53 mbalmer Exp $
+# $NetBSD: mi,v 1.1153 2009/08/14 21:17:21 mbalmer Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@@ -939,6 +939,7 @@
./usr/share/man/cat4/gpib.0 man-sys-catman .cat
./usr/share/man/cat4/gpio.0 man-sys-catman .cat
./usr/share/man/cat4/gpioiic.0 man-sys-catman .cat
+./usr/share/man/cat4/gpiolock.0 man-sys-catman .cat
./usr/share/man/cat4/gpioow.0 man-sys-catman .cat
./usr/share/man/cat4/gpiosim.0 man-sys-catman .cat
./usr/share/man/cat4/gre.0 man-sys-catman .cat
@@ -3548,6 +3549,7 @@
./usr/share/man/html4/gpib.html man-sys-htmlman html
./usr/share/man/html4/gpio.html man-sys-htmlman html
./usr/share/man/html4/gpioiic.html man-sys-htmlman html
+./usr/share/man/html4/gpiolock.html man-sys-htmlman html
./usr/share/man/html4/gpioow.html man-sys-htmlman html
./usr/share/man/html4/gpiosim.html man-sys-htmlman html
./usr/share/man/html4/gre.html man-sys-htmlman html
@@ -5937,6 +5939,7 @@
./usr/share/man/man4/gpib.4 man-sys-man .man
./usr/share/man/man4/gpio.4 man-sys-man .man
./usr/share/man/man4/gpioiic.4 man-sys-man .man
+./usr/share/man/man4/gpiolock.4 man-sys-man .man
./usr/share/man/man4/gpioow.4 man-sys-man .man
./usr/share/man/man4/gpiosim.4 man-sys-man .man
./usr/share/man/man4/gre.4 man-sys-man .man
Index: src/share/man/man4/Makefile
diff -u src/share/man/man4/Makefile:1.496 src/share/man/man4/Makefile:1.497
--- src/share/man/man4/Makefile:1.496 Sun Aug 9 08:20:53 2009
+++ src/share/man/man4/Makefile Fri Aug 14 21:17:21 2009
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.496 2009/08/09 08:20:53 mbalmer Exp $
+# $NetBSD: Makefile,v 1.497 2009/08/14 21:17:21 mbalmer Exp $
# @(#)Makefile 8.1 (Berkeley) 6/18/93
MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 acpidalb.4 \
@@ -25,8 +25,8 @@
esa.4 esiop.4 esm.4 eso.4 etherip.4 exphy.4 \
fast_ipsec.4 fd.4 finsio.4 fpa.4 fms.4 fss.4 fxp.4 \
gcscaudio.4 gem.4 genfb.4 gentbi.4 geodeide.4 \
- glxtphy.4 gpib.4 gpio.4 gpiosim.4 gre.4 gphyter.4 gsip.4 hifn.4 hme.4 \
- hpqlb.4 hptide.4 \
+ glxtphy.4 gpib.4 gpio.4 gpiolock.4 gpiosim.4 gre.4 gphyter.4 gsip.4 \
+ hifn.4 hme.4 hpqlb.4 hptide.4 \
ichlpcib.4 ichsmb.4 icmp.4 icp.4 icsphy.4 iee.4 ieee80211.4 \
ifmedia.4 igsfb.4 iha.4 iic.4 inet.4 ikphy.4 inphy.4 intersil7170.4 \
ioasic.4 ioat.4 iop.4 iophy.4 iopsp.4 ip.4 ipkdb.4 ipmi.4 ipw.4 \
Index: src/sys/conf/files
diff -u src/sys/conf/files:1.952 src/sys/conf/files:1.953
--- src/sys/conf/files:1.952 Sun Aug 9 06:40:10 2009
+++ src/sys/conf/files Fri Aug 14 21:17:21 2009
@@ -1,4 +1,4 @@
-# $NetBSD: files,v 1.952 2009/08/09 06:40:10 kiyohara Exp $
+# $NetBSD: files,v 1.953 2009/08/14 21:17:21 mbalmer Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
version 20090313
@@ -24,6 +24,7 @@
defflag PTRACE
defflag COREDUMP
defflag MODULAR
+defflag KEYLOCK
defparam DEFCORENAME
defparam HZ
@@ -1371,6 +1372,7 @@
file dev/dkwedge/dkwedge_mbr.c dkwedge_method_mbr
file dev/firmload.c firmload
file dev/fss.c fss needs-count
+file dev/keylock.c keylock
file dev/lockstat.c lockstat needs-flag
file dev/md.c md needs-count
file dev/midi.c midi | midibus needs-flag
Index: src/sys/dev/gpio/files.gpio
diff -u src/sys/dev/gpio/files.gpio:1.7 src/sys/dev/gpio/files.gpio:1.8
--- src/sys/dev/gpio/files.gpio:1.7 Sun Aug 9 08:18:00 2009
+++ src/sys/dev/gpio/files.gpio Fri Aug 14 21:17:22 2009
@@ -1,4 +1,4 @@
-# $NetBSD: files.gpio,v 1.7 2009/08/09 08:18:00 mbalmer Exp $
+# $NetBSD: files.gpio,v 1.8 2009/08/14 21:17:22 mbalmer Exp $
define gpio {[offset = -1], [mask = 0]}
@@ -19,3 +19,8 @@
device gpioow: onewirebus, onewire_bitbang
attach gpioow at gpio
file dev/gpio/gpioow.c gpioow
+
+# Keylock
+device gpiolock: gpiobus
+attach gpiolock at gpio
+file dev/gpio/gpiolock.c gpiolock
Index: src/sys/secmodel/files.secmodel
diff -u src/sys/secmodel/files.secmodel:1.2 src/sys/secmodel/files.secmodel:1.3
--- src/sys/secmodel/files.secmodel:1.2 Wed Nov 21 22:49:07 2007
+++ src/sys/secmodel/files.secmodel Fri Aug 14 21:17:22 2009
@@ -1,4 +1,4 @@
-# $NetBSD: files.secmodel,v 1.2 2007/11/21 22:49:07 elad Exp $
+# $NetBSD: files.secmodel,v 1.3 2009/08/14 21:17:22 mbalmer Exp $
#
# Traditional 4.4BSD - Securelevel
@@ -14,3 +14,8 @@
# Sample overlay model on-top of the traditional one
#
include "secmodel/overlay/files.overlay"
+
+#
+# Multi-position keylock
+#
+include "secmodel/keylock/files.keylock"
Index: src/sys/sys/Makefile
diff -u src/sys/sys/Makefile:1.118 src/sys/sys/Makefile:1.119
--- src/sys/sys/Makefile:1.118 Mon Nov 24 16:05:21 2008
+++ src/sys/sys/Makefile Fri Aug 14 21:17:22 2009
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.118 2008/11/24 16:05:21 joerg Exp $
+# $NetBSD: Makefile,v 1.119 2009/08/14 21:17:22 mbalmer Exp $
.include <bsd.sys.mk>
@@ -17,7 +17,7 @@
float_ieee754.h fstypes.h gcq.h gmon.h gpio.h hash.h \
ieee754.h inttypes.h ioccom.h ioctl.h ioctl_compat.h iostat.h ipc.h \
joystick.h \
- kcore.h kgdb.h kmem.h ksem.h ksyms.h ktrace.h \
+ kcore.h keylock.h kgdb.h kmem.h ksem.h ksyms.h ktrace.h \
localedef.h lock.h lockf.h lwp.h lwpctl.h \
malloc.h mallocvar.h mbuf.h md4.h md5.h midiio.h \
mman.h module.h mount.h mqueue.h msg.h msgbuf.h mtio.h mutex.h \
Added files:
Index: src/share/man/man4/gpiolock.4
diff -u /dev/null src/share/man/man4/gpiolock.4:1.1
--- /dev/null Fri Aug 14 21:17:22 2009
+++ src/share/man/man4/gpiolock.4 Fri Aug 14 21:17:21 2009
@@ -0,0 +1,67 @@
+.\" $NetBSD: gpiolock.4,v 1.1 2009/08/14 21:17:21 mbalmer Exp $
+.\"
+.\" Copyright (c) 2009 Marc Balmer <[email protected]>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd August 10, 2009
+.Dt GPIOLOCK 4
+.Os
+.Sh NAME
+.Nm gpiolock
+.Nd support for multi-position keylocks attached to GPIO pins
+.Sh SYNOPSIS
+.Cd "gpiolock* at gpio? offset ? mask ?"
+.Cd "gpiolock* at gpio?"
+.Sh DESCRIPTION
+The
+.Nm
+driver allows connecting of multi-position keylocks over GPIO pins.
+The keylock driver registers with a in-kernel keylock supporting system
+and provides
+.Xr kauth 9
+support through an experimental security model.
+The keylock state can be queried using the hw.keylock sysctl variables.
+Only locks with 2-4 positions are currently supported.
+The pin number is specified in the kernel configuration with the
+.Ar offset
+locator.
+The
+.Ar mask
+locator denotes the pins used for the lock (minimum 2, maximum 4 pins are used).
+The
+.Ar offset
+and
+.Ar mask
+can also be specified when
+.Nm
+is attached at runtime using the
+.Dv GPIOATTACH
+.Xr ioctl 2
+on the
+.Xr gpio 4
+device.
+.Sh SEE ALSO
+.Xr gpio 4 ,
+.Xr intro 4 ,
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Nx 5.0 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Marc Balmer Aq [email protected] .
Index: src/sys/dev/keylock.c
diff -u /dev/null src/sys/dev/keylock.c:1.1
--- /dev/null Fri Aug 14 21:17:22 2009
+++ src/sys/dev/keylock.c Fri Aug 14 21:17:22 2009
@@ -0,0 +1,210 @@
+/* $NetBSD: keylock.c,v 1.1 2009/08/14 21:17:22 mbalmer Exp $ */
+
+/*
+ * Copyright (c) 2009 Marc Balmer <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opt_secmodel_keylock.h"
+
+/* Support for multi-position electro-mechanical keylocks */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/keylock.h>
+#include <sys/sysctl.h>
+
+#ifdef secmodel_keylock
+#include <sys/kauth.h>
+#include <secmodel/keylock/keylock.h>
+#endif
+
+static int (*keylock_pos_cb)(void *) = NULL;
+static void *keylock_pos_cb_arg = NULL;
+static int keylock_npos = 0;
+static int keylock_order = 0;
+
+int keylock_pos_sysctl(SYSCTLFN_PROTO);
+int keylock_state_sysctl(SYSCTLFN_PROTO);
+int keylock_order_sysctl(SYSCTLFN_PROTO);
+
+SYSCTL_SETUP(sysctl_keylock_setup, "sysctl keylock setup")
+{
+ const struct sysctlnode *node = NULL;
+
+ sysctl_createv(clog, 0, NULL, NULL,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_NODE, "hw", NULL,
+ NULL, 0, NULL, 0,
+ CTL_HW, CTL_EOL);
+ sysctl_createv(clog, 0, NULL, &node,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_NODE, "keylock",
+ SYSCTL_DESCR("Keylock state"),
+ NULL, 0, NULL, 0,
+ CTL_HW, CTL_CREATE, CTL_EOL);
+
+ if (node == NULL)
+ return;
+
+ sysctl_createv(clog, 0, &node, NULL,
+ CTLFLAG_PERMANENT | CTLFLAG_READONLY,
+ CTLTYPE_INT, "pos",
+ SYSCTL_DESCR("Current keylock position"),
+ keylock_pos_sysctl, 0, NULL, 0,
+ CTL_CREATE, CTL_EOL);
+ sysctl_createv(clog, 0, &node, NULL,
+ CTLFLAG_PERMANENT | CTLFLAG_READONLY,
+ CTLTYPE_INT, "npos",
+ SYSCTL_DESCR("Number of keylock positions"),
+ NULL, 0, &keylock_npos, 0,
+ CTL_CREATE, CTL_EOL);
+ sysctl_createv(clog, 0, &node, NULL,
+ CTLFLAG_PERMANENT | CTLFLAG_READONLY,
+ CTLTYPE_INT, "state",
+ SYSCTL_DESCR("Keylock state"),
+ keylock_state_sysctl, 0, NULL, 0,
+ CTL_CREATE, CTL_EOL);
+ sysctl_createv(clog, 0, &node, NULL,
+ CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
+ CTLTYPE_INT, "order",
+ SYSCTL_DESCR("Keylock closedness order"),
+ keylock_order_sysctl, 0, NULL, 0,
+ CTL_CREATE, CTL_EOL);
+}
+
+int
+keylock_register(void *cb_arg, int npos, int (*cb)(void *))
+{
+ if (keylock_pos_cb != NULL)
+ return -1;
+
+ keylock_pos_cb = cb;
+ keylock_pos_cb_arg = cb_arg;
+ keylock_npos = npos;
+#ifdef secmodel_keylock
+ secmodel_keylock_start();
+#endif
+ return 0;
+}
+
+void
+keylock_unregister(void *cb_arg, int (*cb)(void *))
+{
+ if (keylock_pos_cb != cb || keylock_pos_cb_arg != cb_arg)
+ return;
+
+#ifdef secmodel_keylock
+ secmodel_keylock_stop();
+#endif
+ keylock_pos_cb = NULL;
+ keylock_pos_cb_arg = NULL;
+ keylock_npos = 0;
+}
+
+int
+keylock_position(void)
+{
+ if (keylock_pos_cb == NULL)
+ return 0;
+
+ return (*keylock_pos_cb)(keylock_pos_cb_arg);
+}
+
+int
+keylock_num_positions(void)
+{
+ return keylock_npos;
+}
+
+int
+keylock_state(void)
+{
+ int pos;
+
+ if (keylock_npos == 0)
+ return KEYLOCK_ABSENT;
+
+ pos = keylock_position();
+ if (pos == 0)
+ return KEYLOCK_TAMPER;
+
+ /*
+ * XXX How should the intermediate positions be handled?
+ * At the moment only the ultimate positions are properly handled,
+ * we need to think about what we do with the intermediate positions.
+ * For now we return KEYLOCK_SEMIOPEN for them.
+ */
+ if (pos == 1)
+ return keylock_order == 0 ? KEYLOCK_CLOSE : KEYLOCK_OPEN;
+ else if (pos == keylock_npos)
+ return keylock_order == 0 ? KEYLOCK_OPEN : KEYLOCK_CLOSE;
+ return KEYLOCK_SEMIOPEN;
+}
+
+int
+keylock_pos_sysctl(SYSCTLFN_ARGS)
+{
+ struct sysctlnode node;
+ int val;
+
+ node = *rnode;
+ node.sysctl_data = &val;
+
+ val = keylock_position();
+ return sysctl_lookup(SYSCTLFN_CALL(&node));
+}
+
+int
+keylock_state_sysctl(SYSCTLFN_ARGS)
+{
+ struct sysctlnode node;
+ int val;
+
+ node = *rnode;
+ node.sysctl_data = &val;
+
+ val = keylock_state();
+ return sysctl_lookup(SYSCTLFN_CALL(&node));
+}
+
+int
+keylock_order_sysctl(SYSCTLFN_ARGS)
+{
+ struct sysctlnode node;
+ int val, error;
+
+ node = *rnode;
+ node.sysctl_data = &val;
+
+ val = keylock_order;
+ error = sysctl_lookup(SYSCTLFN_CALL(&node));
+ if (error || newp == NULL)
+ return error;
+ if (keylock_state() != KEYLOCK_OPEN)
+ return -1;
+
+ keylock_order = val;
+ return 0;
+}
+
Index: src/sys/dev/gpio/gpiolock.c
diff -u /dev/null src/sys/dev/gpio/gpiolock.c:1.1
--- /dev/null Fri Aug 14 21:17:22 2009
+++ src/sys/dev/gpio/gpiolock.c Fri Aug 14 21:17:22 2009
@@ -0,0 +1,178 @@
+/* $NetBSD: gpiolock.c,v 1.1 2009/08/14 21:17:22 mbalmer Exp $ */
+
+/*
+ * Copyright (c) 2009 Marc Balmer <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Driver for multi-position keylocks on GPIO pins
+ */
+
+#include "opt_keylock.h"
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/gpio.h>
+#include <sys/keylock.h>
+
+#include <dev/gpio/gpiovar.h>
+
+#define GPIOLOCK_MAXPINS 4
+#define GPIOLOCK_MINPINS 2
+
+struct gpiolock_softc {
+ void * sc_gpio;
+ struct gpio_pinmap sc_map;
+ int _map[GPIOLOCK_MAXPINS];
+
+ int sc_npins;
+ int sc_data;
+ int sc_dying;
+};
+
+int gpiolock_match(device_t, cfdata_t, void *);
+void gpiolock_attach(device_t, device_t, void *);
+int gpiolock_detach(device_t, int);
+int gpiolock_activate(device_t, enum devact);
+int gpiolock_position(void *);
+
+CFATTACH_DECL_NEW(gpiolock, sizeof(struct gpiolock_softc),
+ gpiolock_match, gpiolock_attach, gpiolock_detach, gpiolock_activate);
+
+extern struct cfdriver gpiolock_cd;
+
+int
+gpiolock_match(device_t parent, cfdata_t cf,
+ void *aux)
+{
+ struct gpio_attach_args *ga = aux;
+ int npins;
+
+ if (strcmp(ga->ga_dvname, cf->cf_name))
+ return 0;
+
+ if (ga->ga_offset == -1)
+ return 0;
+
+ /* Check number of pins */
+ npins = gpio_npins(ga->ga_mask);
+ if (npins < GPIOLOCK_MINPINS || npins > GPIOLOCK_MAXPINS) {
+ aprint_debug("%s: invalid pin mask 0x%02x\n", cf->cf_name,
+ ga->ga_mask);
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+gpiolock_attach(device_t parent, device_t self, void *aux)
+{
+ struct gpiolock_softc *sc = device_private(self);
+ struct gpio_attach_args *ga = aux;
+ int pin, caps;
+
+ sc->sc_npins = gpio_npins(ga->ga_mask);
+
+ /* Map pins */
+ sc->sc_gpio = ga->ga_gpio;
+ sc->sc_map.pm_map = sc->_map;
+ if (gpio_pin_map(sc->sc_gpio, ga->ga_offset, ga->ga_mask,
+ &sc->sc_map)) {
+ aprint_error(": can't map pins\n");
+ return;
+ }
+
+ /* Configure data pins */
+ for (pin = 0; pin < sc->sc_npins; pin++) {
+ caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, pin);
+ if (!(caps & GPIO_PIN_INPUT)) {
+ aprint_error(": data pin is unable to read input\n");
+ goto fail;
+ }
+ aprint_normal(" [%d]", sc->sc_map.pm_map[pin]);
+ sc->sc_data = GPIO_PIN_INPUT;
+ gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, pin, sc->sc_data);
+ }
+
+#ifdef KEYLOCK
+ /* Register keylock */
+ if (keylock_register(self, sc->sc_npins, gpiolock_position)) {
+ aprint_error(": can't register keylock\n");
+ goto fail;
+ }
+#endif
+ pmf_device_register(self, NULL, NULL);
+
+ aprint_normal("\n");
+ return;
+
+fail:
+ gpio_pin_unmap(sc->sc_gpio, &sc->sc_map);
+}
+
+int
+gpiolock_detach(device_t self, int flags)
+{
+ struct gpiolock_softc *sc = device_private(self);
+
+ pmf_device_deregister(self);
+#ifdef KEYLOCK
+ keylock_unregister(self, gpiolock_position);
+#endif
+ gpio_pin_unmap(sc->sc_gpio, &sc->sc_map);
+
+ return 0;
+}
+
+int
+gpiolock_activate(device_t self, enum devact act)
+{
+ struct gpiolock_softc *sc = device_private(self);
+
+ switch (act) {
+ case DVACT_ACTIVATE:
+ return EOPNOTSUPP;
+ case DVACT_DEACTIVATE:
+ sc->sc_dying = 1;
+ break;
+ }
+
+ return 0;
+}
+
+int
+gpiolock_position(void *arg)
+{
+ struct gpiolock_softc *sc = device_private((device_t)arg);
+ int pos, pin;
+
+ for (pos = pin = 0; pin < sc->sc_npins; pin++) {
+ if (gpio_pin_read(sc->sc_gpio, &sc->sc_map, pin) ==
+ GPIO_PIN_HIGH)
+ pos = pin + 1;
+ }
+ return pos;
+}
+
Index: src/sys/secmodel/keylock/files.keylock
diff -u /dev/null src/sys/secmodel/keylock/files.keylock:1.1
--- /dev/null Fri Aug 14 21:17:22 2009
+++ src/sys/secmodel/keylock/files.keylock Fri Aug 14 21:17:22 2009
@@ -0,0 +1,5 @@
+# $NetBSD: files.keylock,v 1.1 2009/08/14 21:17:22 mbalmer Exp $
+
+defflag secmodel_keylock
+
+file secmodel/keylock/secmodel_keylock.c secmodel_keylock
Index: src/sys/secmodel/keylock/keylock.h
diff -u /dev/null src/sys/secmodel/keylock/keylock.h:1.1
--- /dev/null Fri Aug 14 21:17:22 2009
+++ src/sys/secmodel/keylock/keylock.h Fri Aug 14 21:17:22 2009
@@ -0,0 +1,51 @@
+/* $NetBSD: keylock.h,v 1.1 2009/08/14 21:17:22 mbalmer Exp $ */
+/*-
+ * Copyright (c) 2009 Marc Balmer <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SECMODEL_KEYLOCK_KEYLOCK_H_
+#define _SECMODEL_KEYLOCK_KEYLOCK_H_
+
+int secmodel_keylock_sysctl(SYSCTLFN_PROTO);
+
+void secmodel_keylock_init(void);
+void secmodel_keylock_start(void);
+void secmodel_keylock_stop(void);
+
+#if defined(_LKM)
+SYSCTL_SETUP_PROTO(sysctl_security_keylock_setup);
+#endif /* _LKM */
+
+int secmodel_keylock_system_cb(kauth_cred_t, kauth_action_t, void *,
+ void *, void *, void *, void *);
+int secmodel_keylock_process_cb(kauth_cred_t, kauth_action_t, void *,
+ void *, void *, void *, void *);
+int secmodel_keylock_network_cb(kauth_cred_t, kauth_action_t, void *,
+ void *, void *, void *, void *);
+int secmodel_keylock_machdep_cb(kauth_cred_t, kauth_action_t, void *,
+ void *, void *, void *, void *);
+int secmodel_keylock_device_cb(kauth_cred_t, kauth_action_t, void *,
+ void *, void *, void *, void *);
+
+#endif /* !_SECMODEL_KEYLOCK_KEYLOCK_H_ */
Index: src/sys/secmodel/keylock/secmodel_keylock.c
diff -u /dev/null src/sys/secmodel/keylock/secmodel_keylock.c:1.1
--- /dev/null Fri Aug 14 21:17:22 2009
+++ src/sys/secmodel/keylock/secmodel_keylock.c Fri Aug 14 21:17:22 2009
@@ -0,0 +1,548 @@
+/* $NetBSD: secmodel_keylock.c,v 1.1 2009/08/14 21:17:22 mbalmer Exp $ */
+/*-
+ * Copyright (c) 2009 Marc Balmer <[email protected]>
+ * Copyright (c) 2006 Elad Efrat <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file contains kauth(9) listeners needed to implement an experimental
+ * keylock based security scheme.
+ *
+ * The position of the keylock is a system-global indication on what
+ * operations are allowed or not. It affects all users, including root.
+ *
+ * Rules:
+ *
+ * - If the number of possible keylock positions is 0, assume there is no
+ * keylock present, do not dissallow any action, i.e. do nothing
+ *
+ * - If the number of possible keylock positions is greater than 0, but the
+ * current lock position is 0, assume tampering with the lock and forbid
+ * all actions.
+ *
+ * - If the lock is in the lowest position, assume the system is locked and
+ * forbid most actions.
+ *
+ * - If the lock is in the highest position, assume the system to be open and
+ * forbid nothing.
+ *
+ * - If the security.models.keylock.order sysctl is set to a value != 0,
+ * reverse this order.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: secmodel_keylock.c,v 1.1 2009/08/14 21:17:22 mbalmer Exp $");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/kauth.h>
+
+#include <sys/conf.h>
+#include <sys/keylock.h>
+#include <sys/mount.h>
+#include <sys/sysctl.h>
+#include <sys/vnode.h>
+
+#include <miscfs/specfs/specdev.h>
+
+#include <secmodel/keylock/keylock.h>
+
+static kauth_listener_t l_system, l_process, l_network, l_machdep, l_device;
+
+SYSCTL_SETUP(sysctl_security_keylock_setup,
+ "sysctl security keylock setup")
+{
+ const struct sysctlnode *rnode;
+
+ sysctl_createv(clog, 0, NULL, &rnode,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_NODE, "security", NULL,
+ NULL, 0, NULL, 0,
+ CTL_SECURITY, CTL_EOL);
+
+ sysctl_createv(clog, 0, &rnode, &rnode,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_NODE, "models", NULL,
+ NULL, 0, NULL, 0,
+ CTL_CREATE, CTL_EOL);
+
+ sysctl_createv(clog, 0, &rnode, &rnode,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_NODE, "keylock",
+ SYSCTL_DESCR("Keylock security model"),
+ NULL, 0, NULL, 0,
+ CTL_CREATE, CTL_EOL);
+
+ sysctl_createv(clog, 0, &rnode, NULL,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_STRING, "name", NULL,
+ NULL, 0, __UNCONST("Keylock"), 0,
+ CTL_CREATE, CTL_EOL);
+}
+
+void
+secmodel_keylock_init(void)
+{
+}
+
+void
+secmodel_keylock_start(void)
+{
+ l_system = kauth_listen_scope(KAUTH_SCOPE_SYSTEM,
+ secmodel_keylock_system_cb, NULL);
+ l_process = kauth_listen_scope(KAUTH_SCOPE_PROCESS,
+ secmodel_keylock_process_cb, NULL);
+ l_network = kauth_listen_scope(KAUTH_SCOPE_NETWORK,
+ secmodel_keylock_network_cb, NULL);
+ l_machdep = kauth_listen_scope(KAUTH_SCOPE_MACHDEP,
+ secmodel_keylock_machdep_cb, NULL);
+ l_device = kauth_listen_scope(KAUTH_SCOPE_DEVICE,
+ secmodel_keylock_device_cb, NULL);
+}
+
+void
+secmodel_keylock_stop(void)
+{
+ kauth_unlisten_scope(l_system);
+ kauth_unlisten_scope(l_process);
+ kauth_unlisten_scope(l_network);
+ kauth_unlisten_scope(l_machdep);
+ kauth_unlisten_scope(l_device);
+}
+
+/*
+ * kauth(9) listener
+ *
+ * Security model: Multi-position keylock
+ * Scope: System
+ * Responsibility: Keylock
+ */
+int
+secmodel_keylock_system_cb(kauth_cred_t cred,
+ kauth_action_t action, void *cookie, void *arg0, void *arg1,
+ void *arg2, void *arg3)
+{
+ int result;
+ enum kauth_system_req req;
+ int kstate;
+
+ kstate = keylock_state();
+ if (kstate == KEYLOCK_ABSENT)
+ return KAUTH_RESULT_DEFER;
+ else if (kstate == KEYLOCK_TAMPER)
+ return KAUTH_RESULT_DENY;
+
+ result = KAUTH_RESULT_DEFER;
+ req = (enum kauth_system_req)arg0;
+
+ switch (action) {
+ case KAUTH_SYSTEM_CHSYSFLAGS:
+ if (kstate == KEYLOCK_CLOSE)
+ result = KAUTH_RESULT_DENY;
+ break;
+
+ case KAUTH_SYSTEM_TIME:
+ switch (req) {
+ case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET:
+ if (kstate == KEYLOCK_CLOSE)
+ result = KAUTH_RESULT_DENY;
+ break;
+
+ case KAUTH_REQ_SYSTEM_TIME_SYSTEM: {
+ struct timespec *ts = arg1;
+ struct timespec *delta = arg2;
+
+ /*
+ * Don't allow the time to be set forward so far it
+ * will wrap and become negative, thus allowing an
+ * attacker to bypass the next check below. The
+ * cutoff is 1 year before rollover occurs, so even
+ * if the attacker uses adjtime(2) to move the time
+ * past the cutoff, it will take a very long time
+ * to get to the wrap point.
+ */
+ if (keylock_position() > 1 &&
+ ((ts->tv_sec > LLONG_MAX - 365*24*60*60) ||
+ (delta->tv_sec < 0 || delta->tv_nsec < 0)))
+ result = KAUTH_RESULT_DENY;
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+
+ case KAUTH_SYSTEM_MODULE:
+ if (kstate == KEYLOCK_CLOSE)
+ result = KAUTH_RESULT_DENY;
+ break;
+
+ case KAUTH_SYSTEM_MOUNT:
+ switch (req) {
+ case KAUTH_REQ_SYSTEM_MOUNT_NEW:
+ if (kstate == KEYLOCK_CLOSE)
+ result = KAUTH_RESULT_DENY;
+
+ break;
+
+ case KAUTH_REQ_SYSTEM_MOUNT_UPDATE:
+ if (kstate == KEYLOCK_CLOSE) {
+ 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))
+ result = KAUTH_RESULT_DENY;
+ }
+ break;
+ default:
+ break;
+ }
+
+ break;
+
+ case KAUTH_SYSTEM_SYSCTL:
+ switch (req) {
+ case KAUTH_REQ_SYSTEM_SYSCTL_ADD:
+ case KAUTH_REQ_SYSTEM_SYSCTL_DELETE:
+ case KAUTH_REQ_SYSTEM_SYSCTL_DESC:
+ if (kstate == KEYLOCK_CLOSE)
+ result = KAUTH_RESULT_DENY;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case KAUTH_SYSTEM_SETIDCORE:
+ if (kstate == KEYLOCK_CLOSE)
+ result = KAUTH_RESULT_DENY;
+ break;
+
+ case KAUTH_SYSTEM_DEBUG:
+ switch (req) {
+ case KAUTH_REQ_SYSTEM_DEBUG_IPKDB:
+ if (kstate == KEYLOCK_CLOSE)
+ result = KAUTH_RESULT_DENY;
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+
+ return result;
+}
+
+/*
+ * kauth(9) listener
+ *
+ * Security model: Multi-position keylock
+ * Scope: Process
+ * Responsibility: Keylock
+ */
+int
+secmodel_keylock_process_cb(kauth_cred_t cred,
+ kauth_action_t action, void *cookie, void *arg0,
+ void *arg1, void *arg2, void *arg3)
+{
+ struct proc *p;
+ int result, kstate;
+
+ kstate = keylock_state();
+ if (kstate == KEYLOCK_ABSENT)
+ return KAUTH_RESULT_DEFER;
+ else if (kstate == KEYLOCK_TAMPER)
+ return KAUTH_RESULT_DENY;
+
+ result = KAUTH_RESULT_DEFER;
+ p = arg0;
+
+ switch (action) {
+ case KAUTH_PROCESS_PROCFS: {
+ enum kauth_process_req req;
+
+ req = (enum kauth_process_req)arg2;
+ switch (req) {
+ case KAUTH_REQ_PROCESS_PROCFS_READ:
+ break;
+
+ case KAUTH_REQ_PROCESS_PROCFS_RW:
+ case KAUTH_REQ_PROCESS_PROCFS_WRITE:
+ if ((p == initproc) && (kstate != KEYLOCK_OPEN))
+ result = KAUTH_RESULT_DENY;
+
+ break;
+ default:
+ break;
+ }
+
+ break;
+ }
+
+ case KAUTH_PROCESS_PTRACE:
+ if ((p == initproc) && (kstate != KEYLOCK_OPEN))
+ result = KAUTH_RESULT_DENY;
+
+ break;
+
+ case KAUTH_PROCESS_CORENAME:
+ if (kstate == KEYLOCK_CLOSE)
+ result = KAUTH_RESULT_DENY;
+ break;
+ }
+ return result;
+}
+
+/*
+ * kauth(9) listener
+ *
+ * Security model: Multi-position keylock
+ * Scope: Network
+ * Responsibility: Keylock
+ */
+int
+secmodel_keylock_network_cb(kauth_cred_t cred,
+ kauth_action_t action, void *cookie, void *arg0,
+ void *arg1, void *arg2, void *arg3)
+{
+ int result, kstate;
+ enum kauth_network_req req;
+
+ kstate = keylock_state();
+ if (kstate == KEYLOCK_ABSENT)
+ return KAUTH_RESULT_DEFER;
+ else if (kstate == KEYLOCK_TAMPER)
+ return KAUTH_RESULT_DENY;
+
+ result = KAUTH_RESULT_DEFER;
+ req = (enum kauth_network_req)arg0;
+
+ switch (action) {
+ case KAUTH_NETWORK_FIREWALL:
+ switch (req) {
+ case KAUTH_REQ_NETWORK_FIREWALL_FW:
+ case KAUTH_REQ_NETWORK_FIREWALL_NAT:
+ if (kstate == KEYLOCK_CLOSE)
+ result = KAUTH_RESULT_DENY;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case KAUTH_NETWORK_FORWSRCRT:
+ if (kstate != KEYLOCK_OPEN)
+ result = KAUTH_RESULT_DENY;
+ break;
+ }
+
+ return result;
+}
+
+/*
+ * kauth(9) listener
+ *
+ * Security model: Multi-position keylock
+ * Scope: Machdep
+ * Responsibility: Keylock
+ */
+int
+secmodel_keylock_machdep_cb(kauth_cred_t cred,
+ kauth_action_t action, void *cookie, void *arg0,
+ void *arg1, void *arg2, void *arg3)
+{
+ int result, kstate;
+
+ kstate = keylock_state();
+ if (kstate == KEYLOCK_ABSENT)
+ return KAUTH_RESULT_DEFER;
+ else if (kstate == KEYLOCK_TAMPER)
+ return KAUTH_RESULT_DENY;
+
+ result = KAUTH_RESULT_DEFER;
+
+ switch (action) {
+ case KAUTH_MACHDEP_IOPERM_SET:
+ case KAUTH_MACHDEP_IOPL:
+ if (kstate != KEYLOCK_OPEN)
+ result = KAUTH_RESULT_DENY;
+ break;
+
+ case KAUTH_MACHDEP_UNMANAGEDMEM:
+ if (kstate != KEYLOCK_OPEN)
+ result = KAUTH_RESULT_DENY;
+ break;
+ }
+
+ return result;
+}
+
+/*
+ * kauth(9) listener
+ *
+ * Security model: Multi-position keylock
+ * Scope: Device
+ * Responsibility: Keylock
+ */
+int
+secmodel_keylock_device_cb(kauth_cred_t cred,
+ kauth_action_t action, void *cookie, void *arg0,
+ void *arg1, void *arg2, void *arg3)
+{
+ int result, kstate;
+
+ kstate = keylock_state();
+ if (kstate == KEYLOCK_ABSENT)
+ return KAUTH_RESULT_DEFER;
+ else if (kstate == KEYLOCK_TAMPER)
+ return KAUTH_RESULT_DENY;
+
+ result = KAUTH_RESULT_DEFER;
+
+ switch (action) {
+ case KAUTH_DEVICE_RAWIO_SPEC: {
+ struct vnode *vp, *bvp;
+ enum kauth_device_req req;
+ dev_t dev;
+ int d_type;
+
+ req = (enum kauth_device_req)arg0;
+ vp = arg1;
+
+ KASSERT(vp != NULL);
+
+ dev = vp->v_rdev;
+ d_type = D_OTHER;
+ bvp = NULL;
+
+ /* Handle /dev/mem and /dev/kmem. */
+ if ((vp->v_type == VCHR) && iskmemdev(dev)) {
+ switch (req) {
+ case KAUTH_REQ_DEVICE_RAWIO_SPEC_READ:
+ break;
+
+ case KAUTH_REQ_DEVICE_RAWIO_SPEC_WRITE:
+ case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW:
+ if (kstate != KEYLOCK_OPEN)
+ result = KAUTH_RESULT_DENY;
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+
+ switch (req) {
+ case KAUTH_REQ_DEVICE_RAWIO_SPEC_READ:
+ 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) {
+ dev_t blkdev;
+
+ blkdev = devsw_chr2blk(dev);
+ if (blkdev != NODEV) {
+ vfinddev(blkdev, VBLK, &bvp);
+ if (bvp != NULL)
+ d_type = (cdev->d_flag
+ & D_TYPEMASK);
+ }
+ }
+
+ break;
+ }
+ case VBLK: {
+ const struct bdevsw *bdev;
+
+ bdev = bdevsw_lookup(dev);
+ if (bdev != NULL)
+ d_type = (bdev->d_flag & D_TYPEMASK);
+
+ bvp = vp;
+
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (d_type != D_DISK)
+ break;
+
+ /*
+ * XXX: This is bogus. We should be failing the request
+ * XXX: not only if this specific slice is mounted, but
+ * XXX: if it's on a disk with any other mounted slice.
+ */
+ if (vfs_mountedon(bvp) && (kstate != KEYLOCK_OPEN))
+ break;
+
+ if (kstate == KEYLOCK_CLOSE)
+ result = KAUTH_RESULT_DENY;
+
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+
+ case KAUTH_DEVICE_RAWIO_PASSTHRU:
+ if (kstate != KEYLOCK_OPEN) {
+ u_long bits;
+
+ bits = (u_long)arg0;
+
+ KASSERT(bits != 0);
+ KASSERT((bits & ~KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_ALL)
+ == 0);
+
+ if (bits & ~KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_READCONF)
+ result = KAUTH_RESULT_DENY;
+ }
+ break;
+
+ case KAUTH_DEVICE_GPIO_PINSET:
+ if (kstate != KEYLOCK_OPEN)
+ result = KAUTH_RESULT_DENY;
+ break;
+ default:
+ break;
+ }
+ return result;
+}
Index: src/sys/sys/keylock.h
diff -u /dev/null src/sys/sys/keylock.h:1.1
--- /dev/null Fri Aug 14 21:17:22 2009
+++ src/sys/sys/keylock.h Fri Aug 14 21:17:22 2009
@@ -0,0 +1,49 @@
+/* $NetBSD: keylock.h,v 1.1 2009/08/14 21:17:22 mbalmer Exp $ */
+
+/*
+ * Copyright (c) 2009 Marc Balmer <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_KEYLOCK_H
+#define _SYS_KEYLOCK_H
+
+#define KEYLOCK_ABSENT 0
+#define KEYLOCK_TAMPER 1
+#define KEYLOCK_OPEN 2
+#define KEYLOCK_SEMIOPEN 3
+#define KEYLOCK_SEMICLOSE 4
+#define KEYLOCK_CLOSE 5
+
+#ifdef _KERNEL
+/* Functions for keylock drivers */
+extern int keylock_register(void *, int, int (*)(void *));
+extern void keylock_unregister(void *, int (*)(void *));
+
+/* Functions to query the keylock state */
+extern int keylock_state(void);
+extern int keylock_position(void);
+extern int keylock_num_positions(void);
+#endif
+
+#endif /* _SYS_KEYLOCK_H */