1 /* $NetBSD: secmodel_keylock.c,v 1.4 2009/10/06 04:28:10 elad Exp $ */
3 * Copyright (c) 2009 Marc Balmer <marc@msys.ch>
4 * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * This file contains kauth(9) listeners needed to implement an experimental
32 * keylock based security scheme.
34 * The position of the keylock is a system-global indication on what
35 * operations are allowed or not. It affects all users, including root.
39 * - If the number of possible keylock positions is 0, assume there is no
40 * keylock present, do not dissallow any action, i.e. do nothing
42 * - If the number of possible keylock positions is greater than 0, but the
43 * current lock position is 0, assume tampering with the lock and forbid
46 * - If the lock is in the lowest position, assume the system is locked and
47 * forbid most actions.
49 * - If the lock is in the highest position, assume the system to be open and
52 * - If the security.models.keylock.order sysctl is set to a value != 0,
56 #include <sys/cdefs.h>
57 __KERNEL_RCSID(0, "$NetBSD: secmodel_keylock.c,v 1.4 2009/10/06 04:28:10 elad Exp $");
59 #include <sys/types.h>
60 #include <sys/param.h>
61 #include <sys/kauth.h>
64 #include <sys/mount.h>
65 #include <sys/sysctl.h>
66 #include <sys/vnode.h>
67 #include <sys/timevar.h>
69 #include <dev/keylock.h>
71 #include <miscfs/specfs/specdev.h>
73 #include <secmodel/keylock/keylock.h>
75 static kauth_listener_t l_system
, l_process
, l_network
, l_machdep
, l_device
;
77 SYSCTL_SETUP(sysctl_security_keylock_setup
,
78 "sysctl security keylock setup")
80 const struct sysctlnode
*rnode
;
82 sysctl_createv(clog
, 0, NULL
, &rnode
,
84 CTLTYPE_NODE
, "security", NULL
,
86 CTL_SECURITY
, CTL_EOL
);
88 sysctl_createv(clog
, 0, &rnode
, &rnode
,
90 CTLTYPE_NODE
, "models", NULL
,
94 sysctl_createv(clog
, 0, &rnode
, &rnode
,
96 CTLTYPE_NODE
, "keylock",
97 SYSCTL_DESCR("Keylock security model"),
101 sysctl_createv(clog
, 0, &rnode
, NULL
,
103 CTLTYPE_STRING
, "name", NULL
,
104 NULL
, 0, __UNCONST("Keylock"), 0,
105 CTL_CREATE
, CTL_EOL
);
109 secmodel_keylock_init(void)
114 secmodel_keylock_start(void)
116 l_system
= kauth_listen_scope(KAUTH_SCOPE_SYSTEM
,
117 secmodel_keylock_system_cb
, NULL
);
118 l_process
= kauth_listen_scope(KAUTH_SCOPE_PROCESS
,
119 secmodel_keylock_process_cb
, NULL
);
120 l_network
= kauth_listen_scope(KAUTH_SCOPE_NETWORK
,
121 secmodel_keylock_network_cb
, NULL
);
122 l_machdep
= kauth_listen_scope(KAUTH_SCOPE_MACHDEP
,
123 secmodel_keylock_machdep_cb
, NULL
);
124 l_device
= kauth_listen_scope(KAUTH_SCOPE_DEVICE
,
125 secmodel_keylock_device_cb
, NULL
);
129 secmodel_keylock_stop(void)
131 kauth_unlisten_scope(l_system
);
132 kauth_unlisten_scope(l_process
);
133 kauth_unlisten_scope(l_network
);
134 kauth_unlisten_scope(l_machdep
);
135 kauth_unlisten_scope(l_device
);
141 * Security model: Multi-position keylock
143 * Responsibility: Keylock
146 secmodel_keylock_system_cb(kauth_cred_t cred
,
147 kauth_action_t action
, void *cookie
, void *arg0
, void *arg1
,
148 void *arg2
, void *arg3
)
151 enum kauth_system_req req
;
154 kstate
= keylock_state();
155 if (kstate
== KEYLOCK_ABSENT
)
156 return KAUTH_RESULT_DEFER
;
157 else if (kstate
== KEYLOCK_TAMPER
)
158 return KAUTH_RESULT_DENY
;
160 result
= KAUTH_RESULT_DEFER
;
161 req
= (enum kauth_system_req
)arg0
;
164 case KAUTH_SYSTEM_CHSYSFLAGS
:
165 if (kstate
== KEYLOCK_CLOSE
)
166 result
= KAUTH_RESULT_DENY
;
169 case KAUTH_SYSTEM_TIME
:
171 case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET
:
172 if (kstate
== KEYLOCK_CLOSE
)
173 result
= KAUTH_RESULT_DENY
;
176 case KAUTH_REQ_SYSTEM_TIME_SYSTEM
: {
177 struct timespec
*ts
= arg1
;
178 struct timespec
*delta
= arg2
;
180 if (keylock_position() > 1 && time_wraps(ts
, delta
))
181 result
= KAUTH_RESULT_DENY
;
189 case KAUTH_SYSTEM_MODULE
:
190 if (kstate
== KEYLOCK_CLOSE
)
191 result
= KAUTH_RESULT_DENY
;
194 case KAUTH_SYSTEM_MOUNT
:
196 case KAUTH_REQ_SYSTEM_MOUNT_NEW
:
197 if (kstate
== KEYLOCK_CLOSE
)
198 result
= KAUTH_RESULT_DENY
;
202 case KAUTH_REQ_SYSTEM_MOUNT_UPDATE
:
203 if (kstate
== KEYLOCK_CLOSE
) {
204 struct mount
*mp
= arg1
;
205 u_long flags
= (u_long
)arg2
;
208 * Can only degrade from read/write to
211 if (flags
!= (mp
->mnt_flag
| MNT_RDONLY
|
212 MNT_RELOAD
| MNT_FORCE
| MNT_UPDATE
))
213 result
= KAUTH_RESULT_DENY
;
222 case KAUTH_SYSTEM_SYSCTL
:
224 case KAUTH_REQ_SYSTEM_SYSCTL_ADD
:
225 case KAUTH_REQ_SYSTEM_SYSCTL_DELETE
:
226 case KAUTH_REQ_SYSTEM_SYSCTL_DESC
:
227 if (kstate
== KEYLOCK_CLOSE
)
228 result
= KAUTH_RESULT_DENY
;
235 case KAUTH_SYSTEM_SETIDCORE
:
236 if (kstate
== KEYLOCK_CLOSE
)
237 result
= KAUTH_RESULT_DENY
;
240 case KAUTH_SYSTEM_DEBUG
:
242 case KAUTH_REQ_SYSTEM_DEBUG_IPKDB
:
243 if (kstate
== KEYLOCK_CLOSE
)
244 result
= KAUTH_RESULT_DENY
;
258 * Security model: Multi-position keylock
260 * Responsibility: Keylock
263 secmodel_keylock_process_cb(kauth_cred_t cred
,
264 kauth_action_t action
, void *cookie
, void *arg0
,
265 void *arg1
, void *arg2
, void *arg3
)
270 kstate
= keylock_state();
271 if (kstate
== KEYLOCK_ABSENT
)
272 return KAUTH_RESULT_DEFER
;
273 else if (kstate
== KEYLOCK_TAMPER
)
274 return KAUTH_RESULT_DENY
;
276 result
= KAUTH_RESULT_DEFER
;
280 case KAUTH_PROCESS_PROCFS
: {
281 enum kauth_process_req req
;
283 req
= (enum kauth_process_req
)arg2
;
285 case KAUTH_REQ_PROCESS_PROCFS_READ
:
288 case KAUTH_REQ_PROCESS_PROCFS_RW
:
289 case KAUTH_REQ_PROCESS_PROCFS_WRITE
:
290 if ((p
== initproc
) && (kstate
!= KEYLOCK_OPEN
))
291 result
= KAUTH_RESULT_DENY
;
301 case KAUTH_PROCESS_PTRACE
:
302 if ((p
== initproc
) && (kstate
!= KEYLOCK_OPEN
))
303 result
= KAUTH_RESULT_DENY
;
307 case KAUTH_PROCESS_CORENAME
:
308 if (kstate
== KEYLOCK_CLOSE
)
309 result
= KAUTH_RESULT_DENY
;
318 * Security model: Multi-position keylock
320 * Responsibility: Keylock
323 secmodel_keylock_network_cb(kauth_cred_t cred
,
324 kauth_action_t action
, void *cookie
, void *arg0
,
325 void *arg1
, void *arg2
, void *arg3
)
328 enum kauth_network_req req
;
330 kstate
= keylock_state();
331 if (kstate
== KEYLOCK_ABSENT
)
332 return KAUTH_RESULT_DEFER
;
333 else if (kstate
== KEYLOCK_TAMPER
)
334 return KAUTH_RESULT_DENY
;
336 result
= KAUTH_RESULT_DEFER
;
337 req
= (enum kauth_network_req
)arg0
;
340 case KAUTH_NETWORK_FIREWALL
:
342 case KAUTH_REQ_NETWORK_FIREWALL_FW
:
343 case KAUTH_REQ_NETWORK_FIREWALL_NAT
:
344 if (kstate
== KEYLOCK_CLOSE
)
345 result
= KAUTH_RESULT_DENY
;
353 case KAUTH_NETWORK_FORWSRCRT
:
354 if (kstate
!= KEYLOCK_OPEN
)
355 result
= KAUTH_RESULT_DENY
;
365 * Security model: Multi-position keylock
367 * Responsibility: Keylock
370 secmodel_keylock_machdep_cb(kauth_cred_t cred
,
371 kauth_action_t action
, void *cookie
, void *arg0
,
372 void *arg1
, void *arg2
, void *arg3
)
376 kstate
= keylock_state();
377 if (kstate
== KEYLOCK_ABSENT
)
378 return KAUTH_RESULT_DEFER
;
379 else if (kstate
== KEYLOCK_TAMPER
)
380 return KAUTH_RESULT_DENY
;
382 result
= KAUTH_RESULT_DEFER
;
385 case KAUTH_MACHDEP_IOPERM_SET
:
386 case KAUTH_MACHDEP_IOPL
:
387 if (kstate
!= KEYLOCK_OPEN
)
388 result
= KAUTH_RESULT_DENY
;
391 case KAUTH_MACHDEP_UNMANAGEDMEM
:
392 if (kstate
!= KEYLOCK_OPEN
)
393 result
= KAUTH_RESULT_DENY
;
403 * Security model: Multi-position keylock
405 * Responsibility: Keylock
408 secmodel_keylock_device_cb(kauth_cred_t cred
,
409 kauth_action_t action
, void *cookie
, void *arg0
,
410 void *arg1
, void *arg2
, void *arg3
)
412 int result
, kstate
, error
;
414 kstate
= keylock_state();
415 if (kstate
== KEYLOCK_ABSENT
)
416 return KAUTH_RESULT_DEFER
;
417 else if (kstate
== KEYLOCK_TAMPER
)
418 return KAUTH_RESULT_DENY
;
420 result
= KAUTH_RESULT_DEFER
;
423 case KAUTH_DEVICE_RAWIO_SPEC
: {
425 enum kauth_device_req req
;
427 req
= (enum kauth_device_req
)arg0
;
432 /* Handle /dev/mem and /dev/kmem. */
435 case KAUTH_REQ_DEVICE_RAWIO_SPEC_READ
:
438 case KAUTH_REQ_DEVICE_RAWIO_SPEC_WRITE
:
439 case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW
:
440 if (kstate
!= KEYLOCK_OPEN
)
441 result
= KAUTH_RESULT_DENY
;
450 case KAUTH_REQ_DEVICE_RAWIO_SPEC_READ
:
453 case KAUTH_REQ_DEVICE_RAWIO_SPEC_WRITE
:
454 case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW
:
455 error
= rawdev_mounted(vp
, NULL
);
460 if (error
&& (kstate
!= KEYLOCK_OPEN
))
463 if (kstate
== KEYLOCK_CLOSE
)
464 result
= KAUTH_RESULT_DENY
;
473 case KAUTH_DEVICE_RAWIO_PASSTHRU
:
474 if (kstate
!= KEYLOCK_OPEN
) {
480 KASSERT((bits
& ~KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_ALL
)
483 if (bits
& ~KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_READCONF
)
484 result
= KAUTH_RESULT_DENY
;
488 case KAUTH_DEVICE_GPIO_PINSET
:
489 if (kstate
!= KEYLOCK_OPEN
)
490 result
= KAUTH_RESULT_DENY
;