secmodel_keylock.c revision 1.2.2.3 1 1.2.2.3 yamt /* $NetBSD: secmodel_keylock.c,v 1.2.2.3 2010/03/11 15:04:40 yamt Exp $ */
2 1.2.2.2 yamt /*-
3 1.2.2.2 yamt * Copyright (c) 2009 Marc Balmer <marc (at) msys.ch>
4 1.2.2.2 yamt * Copyright (c) 2006 Elad Efrat <elad (at) NetBSD.org>
5 1.2.2.2 yamt * All rights reserved.
6 1.2.2.2 yamt *
7 1.2.2.2 yamt * Redistribution and use in source and binary forms, with or without
8 1.2.2.2 yamt * modification, are permitted provided that the following conditions
9 1.2.2.2 yamt * are met:
10 1.2.2.2 yamt * 1. Redistributions of source code must retain the above copyright
11 1.2.2.2 yamt * notice, this list of conditions and the following disclaimer.
12 1.2.2.2 yamt * 2. Redistributions in binary form must reproduce the above copyright
13 1.2.2.2 yamt * notice, this list of conditions and the following disclaimer in the
14 1.2.2.2 yamt * documentation and/or other materials provided with the distribution.
15 1.2.2.2 yamt * 3. The name of the author may not be used to endorse or promote products
16 1.2.2.2 yamt * derived from this software without specific prior written permission.
17 1.2.2.2 yamt *
18 1.2.2.2 yamt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 1.2.2.2 yamt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 1.2.2.2 yamt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 1.2.2.2 yamt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 1.2.2.2 yamt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 1.2.2.2 yamt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 1.2.2.2 yamt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 1.2.2.2 yamt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 1.2.2.2 yamt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 1.2.2.2 yamt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 1.2.2.2 yamt */
29 1.2.2.2 yamt
30 1.2.2.2 yamt /*
31 1.2.2.2 yamt * This file contains kauth(9) listeners needed to implement an experimental
32 1.2.2.2 yamt * keylock based security scheme.
33 1.2.2.2 yamt *
34 1.2.2.2 yamt * The position of the keylock is a system-global indication on what
35 1.2.2.2 yamt * operations are allowed or not. It affects all users, including root.
36 1.2.2.2 yamt *
37 1.2.2.2 yamt * Rules:
38 1.2.2.2 yamt *
39 1.2.2.2 yamt * - If the number of possible keylock positions is 0, assume there is no
40 1.2.2.2 yamt * keylock present, do not dissallow any action, i.e. do nothing
41 1.2.2.2 yamt *
42 1.2.2.2 yamt * - If the number of possible keylock positions is greater than 0, but the
43 1.2.2.2 yamt * current lock position is 0, assume tampering with the lock and forbid
44 1.2.2.2 yamt * all actions.
45 1.2.2.2 yamt *
46 1.2.2.2 yamt * - If the lock is in the lowest position, assume the system is locked and
47 1.2.2.2 yamt * forbid most actions.
48 1.2.2.2 yamt *
49 1.2.2.2 yamt * - If the lock is in the highest position, assume the system to be open and
50 1.2.2.2 yamt * forbid nothing.
51 1.2.2.2 yamt *
52 1.2.2.2 yamt * - If the security.models.keylock.order sysctl is set to a value != 0,
53 1.2.2.2 yamt * reverse this order.
54 1.2.2.2 yamt */
55 1.2.2.2 yamt
56 1.2.2.2 yamt #include <sys/cdefs.h>
57 1.2.2.3 yamt __KERNEL_RCSID(0, "$NetBSD: secmodel_keylock.c,v 1.2.2.3 2010/03/11 15:04:40 yamt Exp $");
58 1.2.2.2 yamt
59 1.2.2.2 yamt #include <sys/types.h>
60 1.2.2.2 yamt #include <sys/param.h>
61 1.2.2.2 yamt #include <sys/kauth.h>
62 1.2.2.2 yamt
63 1.2.2.2 yamt #include <sys/conf.h>
64 1.2.2.2 yamt #include <sys/mount.h>
65 1.2.2.2 yamt #include <sys/sysctl.h>
66 1.2.2.2 yamt #include <sys/vnode.h>
67 1.2.2.3 yamt #include <sys/timevar.h>
68 1.2.2.2 yamt
69 1.2.2.2 yamt #include <dev/keylock.h>
70 1.2.2.2 yamt
71 1.2.2.2 yamt #include <miscfs/specfs/specdev.h>
72 1.2.2.2 yamt
73 1.2.2.2 yamt #include <secmodel/keylock/keylock.h>
74 1.2.2.2 yamt
75 1.2.2.2 yamt static kauth_listener_t l_system, l_process, l_network, l_machdep, l_device;
76 1.2.2.2 yamt
77 1.2.2.2 yamt SYSCTL_SETUP(sysctl_security_keylock_setup,
78 1.2.2.2 yamt "sysctl security keylock setup")
79 1.2.2.2 yamt {
80 1.2.2.2 yamt const struct sysctlnode *rnode;
81 1.2.2.2 yamt
82 1.2.2.2 yamt sysctl_createv(clog, 0, NULL, &rnode,
83 1.2.2.2 yamt CTLFLAG_PERMANENT,
84 1.2.2.2 yamt CTLTYPE_NODE, "security", NULL,
85 1.2.2.2 yamt NULL, 0, NULL, 0,
86 1.2.2.2 yamt CTL_SECURITY, CTL_EOL);
87 1.2.2.2 yamt
88 1.2.2.2 yamt sysctl_createv(clog, 0, &rnode, &rnode,
89 1.2.2.2 yamt CTLFLAG_PERMANENT,
90 1.2.2.2 yamt CTLTYPE_NODE, "models", NULL,
91 1.2.2.2 yamt NULL, 0, NULL, 0,
92 1.2.2.2 yamt CTL_CREATE, CTL_EOL);
93 1.2.2.2 yamt
94 1.2.2.2 yamt sysctl_createv(clog, 0, &rnode, &rnode,
95 1.2.2.2 yamt CTLFLAG_PERMANENT,
96 1.2.2.2 yamt CTLTYPE_NODE, "keylock",
97 1.2.2.2 yamt SYSCTL_DESCR("Keylock security model"),
98 1.2.2.2 yamt NULL, 0, NULL, 0,
99 1.2.2.2 yamt CTL_CREATE, CTL_EOL);
100 1.2.2.2 yamt
101 1.2.2.2 yamt sysctl_createv(clog, 0, &rnode, NULL,
102 1.2.2.2 yamt CTLFLAG_PERMANENT,
103 1.2.2.2 yamt CTLTYPE_STRING, "name", NULL,
104 1.2.2.2 yamt NULL, 0, __UNCONST("Keylock"), 0,
105 1.2.2.2 yamt CTL_CREATE, CTL_EOL);
106 1.2.2.2 yamt }
107 1.2.2.2 yamt
108 1.2.2.2 yamt void
109 1.2.2.2 yamt secmodel_keylock_init(void)
110 1.2.2.2 yamt {
111 1.2.2.2 yamt }
112 1.2.2.2 yamt
113 1.2.2.2 yamt void
114 1.2.2.2 yamt secmodel_keylock_start(void)
115 1.2.2.2 yamt {
116 1.2.2.2 yamt l_system = kauth_listen_scope(KAUTH_SCOPE_SYSTEM,
117 1.2.2.2 yamt secmodel_keylock_system_cb, NULL);
118 1.2.2.2 yamt l_process = kauth_listen_scope(KAUTH_SCOPE_PROCESS,
119 1.2.2.2 yamt secmodel_keylock_process_cb, NULL);
120 1.2.2.2 yamt l_network = kauth_listen_scope(KAUTH_SCOPE_NETWORK,
121 1.2.2.2 yamt secmodel_keylock_network_cb, NULL);
122 1.2.2.2 yamt l_machdep = kauth_listen_scope(KAUTH_SCOPE_MACHDEP,
123 1.2.2.2 yamt secmodel_keylock_machdep_cb, NULL);
124 1.2.2.2 yamt l_device = kauth_listen_scope(KAUTH_SCOPE_DEVICE,
125 1.2.2.2 yamt secmodel_keylock_device_cb, NULL);
126 1.2.2.2 yamt }
127 1.2.2.2 yamt
128 1.2.2.2 yamt void
129 1.2.2.2 yamt secmodel_keylock_stop(void)
130 1.2.2.2 yamt {
131 1.2.2.2 yamt kauth_unlisten_scope(l_system);
132 1.2.2.2 yamt kauth_unlisten_scope(l_process);
133 1.2.2.2 yamt kauth_unlisten_scope(l_network);
134 1.2.2.2 yamt kauth_unlisten_scope(l_machdep);
135 1.2.2.2 yamt kauth_unlisten_scope(l_device);
136 1.2.2.2 yamt }
137 1.2.2.2 yamt
138 1.2.2.2 yamt /*
139 1.2.2.2 yamt * kauth(9) listener
140 1.2.2.2 yamt *
141 1.2.2.2 yamt * Security model: Multi-position keylock
142 1.2.2.2 yamt * Scope: System
143 1.2.2.2 yamt * Responsibility: Keylock
144 1.2.2.2 yamt */
145 1.2.2.2 yamt int
146 1.2.2.2 yamt secmodel_keylock_system_cb(kauth_cred_t cred,
147 1.2.2.2 yamt kauth_action_t action, void *cookie, void *arg0, void *arg1,
148 1.2.2.2 yamt void *arg2, void *arg3)
149 1.2.2.2 yamt {
150 1.2.2.2 yamt int result;
151 1.2.2.2 yamt enum kauth_system_req req;
152 1.2.2.2 yamt int kstate;
153 1.2.2.2 yamt
154 1.2.2.2 yamt kstate = keylock_state();
155 1.2.2.2 yamt if (kstate == KEYLOCK_ABSENT)
156 1.2.2.2 yamt return KAUTH_RESULT_DEFER;
157 1.2.2.2 yamt else if (kstate == KEYLOCK_TAMPER)
158 1.2.2.2 yamt return KAUTH_RESULT_DENY;
159 1.2.2.2 yamt
160 1.2.2.2 yamt result = KAUTH_RESULT_DEFER;
161 1.2.2.2 yamt req = (enum kauth_system_req)arg0;
162 1.2.2.2 yamt
163 1.2.2.2 yamt switch (action) {
164 1.2.2.2 yamt case KAUTH_SYSTEM_CHSYSFLAGS:
165 1.2.2.2 yamt if (kstate == KEYLOCK_CLOSE)
166 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
167 1.2.2.2 yamt break;
168 1.2.2.2 yamt
169 1.2.2.2 yamt case KAUTH_SYSTEM_TIME:
170 1.2.2.2 yamt switch (req) {
171 1.2.2.2 yamt case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET:
172 1.2.2.2 yamt if (kstate == KEYLOCK_CLOSE)
173 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
174 1.2.2.2 yamt break;
175 1.2.2.2 yamt
176 1.2.2.2 yamt case KAUTH_REQ_SYSTEM_TIME_SYSTEM: {
177 1.2.2.2 yamt struct timespec *ts = arg1;
178 1.2.2.2 yamt struct timespec *delta = arg2;
179 1.2.2.2 yamt
180 1.2.2.3 yamt if (keylock_position() > 1 && time_wraps(ts, delta))
181 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
182 1.2.2.2 yamt break;
183 1.2.2.2 yamt }
184 1.2.2.2 yamt default:
185 1.2.2.2 yamt break;
186 1.2.2.2 yamt }
187 1.2.2.2 yamt break;
188 1.2.2.2 yamt
189 1.2.2.2 yamt case KAUTH_SYSTEM_MODULE:
190 1.2.2.2 yamt if (kstate == KEYLOCK_CLOSE)
191 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
192 1.2.2.2 yamt break;
193 1.2.2.2 yamt
194 1.2.2.2 yamt case KAUTH_SYSTEM_MOUNT:
195 1.2.2.2 yamt switch (req) {
196 1.2.2.2 yamt case KAUTH_REQ_SYSTEM_MOUNT_NEW:
197 1.2.2.2 yamt if (kstate == KEYLOCK_CLOSE)
198 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
199 1.2.2.2 yamt
200 1.2.2.2 yamt break;
201 1.2.2.2 yamt
202 1.2.2.2 yamt case KAUTH_REQ_SYSTEM_MOUNT_UPDATE:
203 1.2.2.2 yamt if (kstate == KEYLOCK_CLOSE) {
204 1.2.2.2 yamt struct mount *mp = arg1;
205 1.2.2.2 yamt u_long flags = (u_long)arg2;
206 1.2.2.2 yamt
207 1.2.2.2 yamt /*
208 1.2.2.2 yamt * Can only degrade from read/write to
209 1.2.2.2 yamt * read-only.
210 1.2.2.2 yamt */
211 1.2.2.2 yamt if (flags != (mp->mnt_flag | MNT_RDONLY |
212 1.2.2.2 yamt MNT_RELOAD | MNT_FORCE | MNT_UPDATE))
213 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
214 1.2.2.2 yamt }
215 1.2.2.2 yamt break;
216 1.2.2.2 yamt default:
217 1.2.2.2 yamt break;
218 1.2.2.2 yamt }
219 1.2.2.2 yamt
220 1.2.2.2 yamt break;
221 1.2.2.2 yamt
222 1.2.2.2 yamt case KAUTH_SYSTEM_SYSCTL:
223 1.2.2.2 yamt switch (req) {
224 1.2.2.2 yamt case KAUTH_REQ_SYSTEM_SYSCTL_ADD:
225 1.2.2.2 yamt case KAUTH_REQ_SYSTEM_SYSCTL_DELETE:
226 1.2.2.2 yamt case KAUTH_REQ_SYSTEM_SYSCTL_DESC:
227 1.2.2.2 yamt if (kstate == KEYLOCK_CLOSE)
228 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
229 1.2.2.2 yamt break;
230 1.2.2.2 yamt default:
231 1.2.2.2 yamt break;
232 1.2.2.2 yamt }
233 1.2.2.2 yamt break;
234 1.2.2.2 yamt
235 1.2.2.2 yamt case KAUTH_SYSTEM_SETIDCORE:
236 1.2.2.2 yamt if (kstate == KEYLOCK_CLOSE)
237 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
238 1.2.2.2 yamt break;
239 1.2.2.2 yamt
240 1.2.2.2 yamt case KAUTH_SYSTEM_DEBUG:
241 1.2.2.2 yamt switch (req) {
242 1.2.2.2 yamt case KAUTH_REQ_SYSTEM_DEBUG_IPKDB:
243 1.2.2.2 yamt if (kstate == KEYLOCK_CLOSE)
244 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
245 1.2.2.2 yamt break;
246 1.2.2.2 yamt default:
247 1.2.2.2 yamt break;
248 1.2.2.2 yamt }
249 1.2.2.2 yamt break;
250 1.2.2.2 yamt }
251 1.2.2.2 yamt
252 1.2.2.2 yamt return result;
253 1.2.2.2 yamt }
254 1.2.2.2 yamt
255 1.2.2.2 yamt /*
256 1.2.2.2 yamt * kauth(9) listener
257 1.2.2.2 yamt *
258 1.2.2.2 yamt * Security model: Multi-position keylock
259 1.2.2.2 yamt * Scope: Process
260 1.2.2.2 yamt * Responsibility: Keylock
261 1.2.2.2 yamt */
262 1.2.2.2 yamt int
263 1.2.2.2 yamt secmodel_keylock_process_cb(kauth_cred_t cred,
264 1.2.2.2 yamt kauth_action_t action, void *cookie, void *arg0,
265 1.2.2.2 yamt void *arg1, void *arg2, void *arg3)
266 1.2.2.2 yamt {
267 1.2.2.2 yamt struct proc *p;
268 1.2.2.2 yamt int result, kstate;
269 1.2.2.2 yamt
270 1.2.2.2 yamt kstate = keylock_state();
271 1.2.2.2 yamt if (kstate == KEYLOCK_ABSENT)
272 1.2.2.2 yamt return KAUTH_RESULT_DEFER;
273 1.2.2.2 yamt else if (kstate == KEYLOCK_TAMPER)
274 1.2.2.2 yamt return KAUTH_RESULT_DENY;
275 1.2.2.2 yamt
276 1.2.2.2 yamt result = KAUTH_RESULT_DEFER;
277 1.2.2.2 yamt p = arg0;
278 1.2.2.2 yamt
279 1.2.2.2 yamt switch (action) {
280 1.2.2.2 yamt case KAUTH_PROCESS_PROCFS: {
281 1.2.2.2 yamt enum kauth_process_req req;
282 1.2.2.2 yamt
283 1.2.2.2 yamt req = (enum kauth_process_req)arg2;
284 1.2.2.2 yamt switch (req) {
285 1.2.2.2 yamt case KAUTH_REQ_PROCESS_PROCFS_READ:
286 1.2.2.2 yamt break;
287 1.2.2.2 yamt
288 1.2.2.2 yamt case KAUTH_REQ_PROCESS_PROCFS_RW:
289 1.2.2.2 yamt case KAUTH_REQ_PROCESS_PROCFS_WRITE:
290 1.2.2.2 yamt if ((p == initproc) && (kstate != KEYLOCK_OPEN))
291 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
292 1.2.2.2 yamt
293 1.2.2.2 yamt break;
294 1.2.2.2 yamt default:
295 1.2.2.2 yamt break;
296 1.2.2.2 yamt }
297 1.2.2.2 yamt
298 1.2.2.2 yamt break;
299 1.2.2.2 yamt }
300 1.2.2.2 yamt
301 1.2.2.2 yamt case KAUTH_PROCESS_PTRACE:
302 1.2.2.2 yamt if ((p == initproc) && (kstate != KEYLOCK_OPEN))
303 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
304 1.2.2.2 yamt
305 1.2.2.2 yamt break;
306 1.2.2.2 yamt
307 1.2.2.2 yamt case KAUTH_PROCESS_CORENAME:
308 1.2.2.2 yamt if (kstate == KEYLOCK_CLOSE)
309 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
310 1.2.2.2 yamt break;
311 1.2.2.2 yamt }
312 1.2.2.2 yamt return result;
313 1.2.2.2 yamt }
314 1.2.2.2 yamt
315 1.2.2.2 yamt /*
316 1.2.2.2 yamt * kauth(9) listener
317 1.2.2.2 yamt *
318 1.2.2.2 yamt * Security model: Multi-position keylock
319 1.2.2.2 yamt * Scope: Network
320 1.2.2.2 yamt * Responsibility: Keylock
321 1.2.2.2 yamt */
322 1.2.2.2 yamt int
323 1.2.2.2 yamt secmodel_keylock_network_cb(kauth_cred_t cred,
324 1.2.2.2 yamt kauth_action_t action, void *cookie, void *arg0,
325 1.2.2.2 yamt void *arg1, void *arg2, void *arg3)
326 1.2.2.2 yamt {
327 1.2.2.2 yamt int result, kstate;
328 1.2.2.2 yamt enum kauth_network_req req;
329 1.2.2.2 yamt
330 1.2.2.2 yamt kstate = keylock_state();
331 1.2.2.2 yamt if (kstate == KEYLOCK_ABSENT)
332 1.2.2.2 yamt return KAUTH_RESULT_DEFER;
333 1.2.2.2 yamt else if (kstate == KEYLOCK_TAMPER)
334 1.2.2.2 yamt return KAUTH_RESULT_DENY;
335 1.2.2.2 yamt
336 1.2.2.2 yamt result = KAUTH_RESULT_DEFER;
337 1.2.2.2 yamt req = (enum kauth_network_req)arg0;
338 1.2.2.2 yamt
339 1.2.2.2 yamt switch (action) {
340 1.2.2.2 yamt case KAUTH_NETWORK_FIREWALL:
341 1.2.2.2 yamt switch (req) {
342 1.2.2.2 yamt case KAUTH_REQ_NETWORK_FIREWALL_FW:
343 1.2.2.2 yamt case KAUTH_REQ_NETWORK_FIREWALL_NAT:
344 1.2.2.2 yamt if (kstate == KEYLOCK_CLOSE)
345 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
346 1.2.2.2 yamt break;
347 1.2.2.2 yamt
348 1.2.2.2 yamt default:
349 1.2.2.2 yamt break;
350 1.2.2.2 yamt }
351 1.2.2.2 yamt break;
352 1.2.2.2 yamt
353 1.2.2.2 yamt case KAUTH_NETWORK_FORWSRCRT:
354 1.2.2.2 yamt if (kstate != KEYLOCK_OPEN)
355 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
356 1.2.2.2 yamt break;
357 1.2.2.2 yamt }
358 1.2.2.2 yamt
359 1.2.2.2 yamt return result;
360 1.2.2.2 yamt }
361 1.2.2.2 yamt
362 1.2.2.2 yamt /*
363 1.2.2.2 yamt * kauth(9) listener
364 1.2.2.2 yamt *
365 1.2.2.2 yamt * Security model: Multi-position keylock
366 1.2.2.2 yamt * Scope: Machdep
367 1.2.2.2 yamt * Responsibility: Keylock
368 1.2.2.2 yamt */
369 1.2.2.2 yamt int
370 1.2.2.2 yamt secmodel_keylock_machdep_cb(kauth_cred_t cred,
371 1.2.2.2 yamt kauth_action_t action, void *cookie, void *arg0,
372 1.2.2.2 yamt void *arg1, void *arg2, void *arg3)
373 1.2.2.2 yamt {
374 1.2.2.2 yamt int result, kstate;
375 1.2.2.2 yamt
376 1.2.2.2 yamt kstate = keylock_state();
377 1.2.2.2 yamt if (kstate == KEYLOCK_ABSENT)
378 1.2.2.2 yamt return KAUTH_RESULT_DEFER;
379 1.2.2.2 yamt else if (kstate == KEYLOCK_TAMPER)
380 1.2.2.2 yamt return KAUTH_RESULT_DENY;
381 1.2.2.2 yamt
382 1.2.2.2 yamt result = KAUTH_RESULT_DEFER;
383 1.2.2.2 yamt
384 1.2.2.2 yamt switch (action) {
385 1.2.2.2 yamt case KAUTH_MACHDEP_IOPERM_SET:
386 1.2.2.2 yamt case KAUTH_MACHDEP_IOPL:
387 1.2.2.2 yamt if (kstate != KEYLOCK_OPEN)
388 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
389 1.2.2.2 yamt break;
390 1.2.2.2 yamt
391 1.2.2.2 yamt case KAUTH_MACHDEP_UNMANAGEDMEM:
392 1.2.2.2 yamt if (kstate != KEYLOCK_OPEN)
393 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
394 1.2.2.2 yamt break;
395 1.2.2.2 yamt }
396 1.2.2.2 yamt
397 1.2.2.2 yamt return result;
398 1.2.2.2 yamt }
399 1.2.2.2 yamt
400 1.2.2.2 yamt /*
401 1.2.2.2 yamt * kauth(9) listener
402 1.2.2.2 yamt *
403 1.2.2.2 yamt * Security model: Multi-position keylock
404 1.2.2.2 yamt * Scope: Device
405 1.2.2.2 yamt * Responsibility: Keylock
406 1.2.2.2 yamt */
407 1.2.2.2 yamt int
408 1.2.2.2 yamt secmodel_keylock_device_cb(kauth_cred_t cred,
409 1.2.2.2 yamt kauth_action_t action, void *cookie, void *arg0,
410 1.2.2.2 yamt void *arg1, void *arg2, void *arg3)
411 1.2.2.2 yamt {
412 1.2.2.3 yamt int result, kstate, error;
413 1.2.2.2 yamt
414 1.2.2.2 yamt kstate = keylock_state();
415 1.2.2.2 yamt if (kstate == KEYLOCK_ABSENT)
416 1.2.2.2 yamt return KAUTH_RESULT_DEFER;
417 1.2.2.2 yamt else if (kstate == KEYLOCK_TAMPER)
418 1.2.2.2 yamt return KAUTH_RESULT_DENY;
419 1.2.2.2 yamt
420 1.2.2.2 yamt result = KAUTH_RESULT_DEFER;
421 1.2.2.2 yamt
422 1.2.2.2 yamt switch (action) {
423 1.2.2.2 yamt case KAUTH_DEVICE_RAWIO_SPEC: {
424 1.2.2.3 yamt struct vnode *vp;
425 1.2.2.2 yamt enum kauth_device_req req;
426 1.2.2.2 yamt
427 1.2.2.2 yamt req = (enum kauth_device_req)arg0;
428 1.2.2.2 yamt vp = arg1;
429 1.2.2.2 yamt
430 1.2.2.2 yamt KASSERT(vp != NULL);
431 1.2.2.2 yamt
432 1.2.2.2 yamt /* Handle /dev/mem and /dev/kmem. */
433 1.2.2.3 yamt if (iskmemvp(vp)) {
434 1.2.2.2 yamt switch (req) {
435 1.2.2.2 yamt case KAUTH_REQ_DEVICE_RAWIO_SPEC_READ:
436 1.2.2.2 yamt break;
437 1.2.2.2 yamt
438 1.2.2.2 yamt case KAUTH_REQ_DEVICE_RAWIO_SPEC_WRITE:
439 1.2.2.2 yamt case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW:
440 1.2.2.2 yamt if (kstate != KEYLOCK_OPEN)
441 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
442 1.2.2.2 yamt break;
443 1.2.2.2 yamt default:
444 1.2.2.2 yamt break;
445 1.2.2.2 yamt }
446 1.2.2.2 yamt break;
447 1.2.2.2 yamt }
448 1.2.2.2 yamt
449 1.2.2.2 yamt switch (req) {
450 1.2.2.2 yamt case KAUTH_REQ_DEVICE_RAWIO_SPEC_READ:
451 1.2.2.2 yamt break;
452 1.2.2.2 yamt
453 1.2.2.2 yamt case KAUTH_REQ_DEVICE_RAWIO_SPEC_WRITE:
454 1.2.2.2 yamt case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW:
455 1.2.2.3 yamt error = rawdev_mounted(vp, NULL);
456 1.2.2.2 yamt
457 1.2.2.3 yamt if (error == EINVAL)
458 1.2.2.2 yamt break;
459 1.2.2.2 yamt
460 1.2.2.3 yamt if (error && (kstate != KEYLOCK_OPEN))
461 1.2.2.2 yamt break;
462 1.2.2.2 yamt
463 1.2.2.2 yamt if (kstate == KEYLOCK_CLOSE)
464 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
465 1.2.2.2 yamt
466 1.2.2.2 yamt break;
467 1.2.2.2 yamt default:
468 1.2.2.2 yamt break;
469 1.2.2.2 yamt }
470 1.2.2.2 yamt break;
471 1.2.2.2 yamt }
472 1.2.2.2 yamt
473 1.2.2.2 yamt case KAUTH_DEVICE_RAWIO_PASSTHRU:
474 1.2.2.2 yamt if (kstate != KEYLOCK_OPEN) {
475 1.2.2.2 yamt u_long bits;
476 1.2.2.2 yamt
477 1.2.2.2 yamt bits = (u_long)arg0;
478 1.2.2.2 yamt
479 1.2.2.2 yamt KASSERT(bits != 0);
480 1.2.2.2 yamt KASSERT((bits & ~KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_ALL)
481 1.2.2.2 yamt == 0);
482 1.2.2.2 yamt
483 1.2.2.2 yamt if (bits & ~KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_READCONF)
484 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
485 1.2.2.2 yamt }
486 1.2.2.2 yamt break;
487 1.2.2.2 yamt
488 1.2.2.2 yamt case KAUTH_DEVICE_GPIO_PINSET:
489 1.2.2.2 yamt if (kstate != KEYLOCK_OPEN)
490 1.2.2.2 yamt result = KAUTH_RESULT_DENY;
491 1.2.2.2 yamt break;
492 1.2.2.2 yamt default:
493 1.2.2.2 yamt break;
494 1.2.2.2 yamt }
495 1.2.2.2 yamt return result;
496 1.2.2.2 yamt }
497