1 /*-
2 * Copyright (c) 1999-2002, 2006, 2009 Robert N. M. Watson
3 * Copyright (c) 2001 Ilmar S. Habibulin
4 * Copyright (c) 2001-2005 Networks Associates Technology, Inc.
5 * Copyright (c) 2005-2006 SPARTA, Inc.
6 * All rights reserved.
7 *
8 * This software was developed by Robert Watson and Ilmar Habibulin for the
9 * TrustedBSD Project.
10 *
11 * This software was developed for the FreeBSD Project in part by Network
12 * Associates Laboratories, the Security Research Division of Network
13 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
14 * as part of the DARPA CHATS research program.
15 *
16 * This software was enhanced by SPARTA ISSO under SPAWAR contract
17 * N66001-04-C-6019 ("SEFOS").
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 * 1. Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in the
26 * documentation and/or other materials provided with the distribution.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 */
40
41 /*-
42 * Framework for extensible kernel access control. This file contains core
43 * kernel infrastructure for the TrustedBSD MAC Framework, including policy
44 * registration, versioning, locking, error composition operator, and system
45 * calls.
46 *
47 * The MAC Framework implements three programming interfaces:
48 *
49 * - The kernel MAC interface, defined in mac_framework.h, and invoked
50 * throughout the kernel to request security decisions, notify of security
51 * related events, etc.
52 *
53 * - The MAC policy module interface, defined in mac_policy.h, which is
54 * implemented by MAC policy modules and invoked by the MAC Framework to
55 * forward kernel security requests and notifications to policy modules.
56 *
57 * - The user MAC API, defined in mac.h, which allows user programs to query
58 * and set label state on objects.
59 *
60 * The majority of the MAC Framework implementation may be found in
61 * src/sys/security/mac. Sample policy modules may be found in
62 * src/sys/security/mac_*.
63 */
64
65 #include "opt_kdtrace.h"
66 #include "opt_mac.h"
67
68 #include <sys/cdefs.h>
69 __FBSDID("$FreeBSD$");
70
71 #include <sys/param.h>
72 #include <sys/condvar.h>
73 #include <sys/kernel.h>
74 #include <sys/lock.h>
75 #include <sys/mutex.h>
76 #include <sys/mac.h>
77 #include <sys/module.h>
78 #include <sys/sdt.h>
79 #include <sys/systm.h>
80 #include <sys/sysctl.h>
81
82 #include <security/mac/mac_framework.h>
83 #include <security/mac/mac_internal.h>
84 #include <security/mac/mac_policy.h>
85
86 /*
87 * DTrace SDT provider for MAC.
88 */
89 SDT_PROVIDER_DEFINE(mac);
90 SDT_PROBE_DEFINE2(mac, kernel, policy, modevent, "int",
91 "struct mac_policy_conf *mpc");
92 SDT_PROBE_DEFINE1(mac, kernel, policy, register, "struct mac_policy_conf *");
93 SDT_PROBE_DEFINE1(mac, kernel, policy, unregister, "struct mac_policy_conf *");
94
95 /*
96 * Root sysctl node for all MAC and MAC policy controls.
97 */
98 SYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0,
99 "TrustedBSD MAC policy controls");
100
101 /*
102 * Declare that the kernel provides MAC support, version 3 (FreeBSD 7.x).
103 * This permits modules to refuse to be loaded if the necessary support isn't
104 * present, even if it's pre-boot.
105 */
106 MODULE_VERSION(kernel_mac_support, MAC_VERSION);
107
108 static unsigned int mac_version = MAC_VERSION;
109 SYSCTL_UINT(_security_mac, OID_AUTO, version, CTLFLAG_RD, &mac_version, 0,
110 "");
111
112 /*
113 * Labels consist of a indexed set of "slots", which are allocated policies
114 * as required. The MAC Framework maintains a bitmask of slots allocated so
115 * far to prevent reuse. Slots cannot be reused, as the MAC Framework
116 * guarantees that newly allocated slots in labels will be NULL unless
117 * otherwise initialized, and because we do not have a mechanism to garbage
118 * collect slots on policy unload. As labeled policies tend to be statically
119 * loaded during boot, and not frequently unloaded and reloaded, this is not
120 * generally an issue.
121 */
122 #if MAC_MAX_SLOTS > 32
123 #error "MAC_MAX_SLOTS too large"
124 #endif
125
126 static unsigned int mac_max_slots = MAC_MAX_SLOTS;
127 static unsigned int mac_slot_offsets_free = (1 << MAC_MAX_SLOTS) - 1;
128 SYSCTL_UINT(_security_mac, OID_AUTO, max_slots, CTLFLAG_RD, &mac_max_slots,
129 0, "");
130
131 /*
132 * Has the kernel started generating labeled objects yet? All read/write
133 * access to this variable is serialized during the boot process. Following
134 * the end of serialization, we don't update this flag; no locking.
135 */
136 static int mac_late = 0;
137
138 /*
139 * Flag to indicate whether or not we should allocate label storage for new
140 * mbufs. Since most dynamic policies we currently work with don't rely on
141 * mbuf labeling, try to avoid paying the cost of mtag allocation unless
142 * specifically notified of interest. One result of this is that if a
143 * dynamically loaded policy requests mbuf labels, it must be able to deal
144 * with a NULL label being returned on any mbufs that were already in flight
145 * when the policy was loaded. Since the policy already has to deal with
146 * uninitialized labels, this probably won't be a problem. Note: currently
147 * no locking. Will this be a problem?
148 *
149 * In the future, we may want to allow objects to request labeling on a per-
150 * object type basis, rather than globally for all objects.
151 */
152 #ifndef MAC_ALWAYS_LABEL_MBUF
153 int mac_labelmbufs = 0;
154 #endif
155
156 MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
157
158 /*
159 * mac_static_policy_list holds a list of policy modules that are not loaded
160 * while the system is "live", and cannot be unloaded. These policies can be
161 * invoked without holding the busy count.
162 *
163 * mac_policy_list stores the list of dynamic policies. A busy count is
164 * maintained for the list, stored in mac_policy_busy. The busy count is
165 * protected by mac_policy_mtx; the list may be modified only while the busy
166 * count is 0, requiring that the lock be held to prevent new references to
167 * the list from being acquired. For almost all operations, incrementing the
168 * busy count is sufficient to guarantee consistency, as the list cannot be
169 * modified while the busy count is elevated. For a few special operations
170 * involving a change to the list of active policies, the mtx itself must be
171 * held. A condition variable, mac_policy_cv, is used to signal potential
172 * exclusive consumers that they should try to acquire the lock if a first
173 * attempt at exclusive access fails.
174 *
175 * This design intentionally avoids fairness, and may starve attempts to
176 * acquire an exclusive lock on a busy system. This is required because we
177 * do not ever want acquiring a read reference to perform an unbounded length
178 * sleep. Read references are acquired in ithreads, network isrs, etc, and
179 * any unbounded blocking could lead quickly to deadlock.
180 *
181 * Another reason for never blocking on read references is that the MAC
182 * Framework may recurse: if a policy calls a VOP, for example, this might
183 * lead to vnode life cycle operations (such as init/destroy).
184 *
185 * If the kernel option MAC_STATIC has been compiled in, all locking becomes
186 * a no-op, and the global list of policies is not allowed to change after
187 * early boot.
188 *
189 * XXXRW: Currently, we signal mac_policy_cv every time the framework becomes
190 * unbusy and there is a thread waiting to enter it exclusively. Since it
191 * may take some time before the thread runs, we may issue a lot of signals.
192 * We should instead keep track of the fact that we've signalled, taking into
193 * account that the framework may be busy again by the time the thread runs,
194 * requiring us to re-signal.
195 */
196 #ifndef MAC_STATIC
197 static struct mtx mac_policy_mtx;
198 static struct cv mac_policy_cv;
199 static int mac_policy_count;
200 static int mac_policy_wait;
201 #endif
202 struct mac_policy_list_head mac_policy_list;
203 struct mac_policy_list_head mac_static_policy_list;
204
205 /*
206 * We manually invoke WITNESS_WARN() to allow Witness to generate warnings
207 * even if we don't end up ever triggering the wait at run-time. The
208 * consumer of the exclusive interface must not hold any locks (other than
209 * potentially Giant) since we may sleep for long (potentially indefinite)
210 * periods of time waiting for the framework to become quiescent so that a
211 * policy list change may be made.
212 */
213 void
214 mac_policy_grab_exclusive(void)
215 {
216
217 #ifndef MAC_STATIC
218 if (!mac_late)
219 return;
220
221 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
222 "mac_policy_grab_exclusive() at %s:%d", __FILE__, __LINE__);
223 mtx_lock(&mac_policy_mtx);
224 while (mac_policy_count != 0) {
225 mac_policy_wait++;
226 cv_wait(&mac_policy_cv, &mac_policy_mtx);
227 mac_policy_wait--;
228 }
229 #endif
230 }
231
232 void
233 mac_policy_assert_exclusive(void)
234 {
235
236 #ifndef MAC_STATIC
237 if (!mac_late)
238 return;
239
240 mtx_assert(&mac_policy_mtx, MA_OWNED);
241 KASSERT(mac_policy_count == 0,
242 ("mac_policy_assert_exclusive(): not exclusive"));
243 #endif
244 }
245
246 void
247 mac_policy_release_exclusive(void)
248 {
249 #ifndef MAC_STATIC
250 int dowakeup;
251
252 if (!mac_late)
253 return;
254
255 KASSERT(mac_policy_count == 0,
256 ("mac_policy_release_exclusive(): not exclusive"));
257 dowakeup = (mac_policy_wait != 0);
258 mtx_unlock(&mac_policy_mtx);
259 if (dowakeup)
260 cv_signal(&mac_policy_cv);
261 #endif
262 }
263
264 void
265 mac_policy_list_busy(void)
266 {
267
268 #ifndef MAC_STATIC
269 if (!mac_late)
270 return;
271
272 mtx_lock(&mac_policy_mtx);
273 mac_policy_count++;
274 mtx_unlock(&mac_policy_mtx);
275 #endif
276 }
277
278 int
279 mac_policy_list_conditional_busy(void)
280 {
281 #ifndef MAC_STATIC
282 int ret;
283
284 if (!mac_late)
285 return (1);
286
287 mtx_lock(&mac_policy_mtx);
288 if (!LIST_EMPTY(&mac_policy_list)) {
289 mac_policy_count++;
290 ret = 1;
291 } else
292 ret = 0;
293 mtx_unlock(&mac_policy_mtx);
294 return (ret);
295 #else
296 return (1);
297 #endif
298 }
299
300 void
301 mac_policy_list_unbusy(void)
302 {
303 #ifndef MAC_STATIC
304 int dowakeup;
305
306 if (!mac_late)
307 return;
308
309 mtx_lock(&mac_policy_mtx);
310 mac_policy_count--;
311 KASSERT(mac_policy_count >= 0, ("MAC_POLICY_LIST_LOCK"));
312 dowakeup = (mac_policy_count == 0 && mac_policy_wait != 0);
313 mtx_unlock(&mac_policy_mtx);
314
315 if (dowakeup)
316 cv_signal(&mac_policy_cv);
317 #endif
318 }
319
320 /*
321 * Initialize the MAC subsystem, including appropriate SMP locks.
322 */
323 static void
324 mac_init(void)
325 {
326
327 LIST_INIT(&mac_static_policy_list);
328 LIST_INIT(&mac_policy_list);
329 mac_labelzone_init();
330
331 #ifndef MAC_STATIC
332 mtx_init(&mac_policy_mtx, "mac_policy_mtx", NULL, MTX_DEF);
333 cv_init(&mac_policy_cv, "mac_policy_cv");
334 #endif
335 }
336
337 /*
338 * For the purposes of modules that want to know if they were loaded "early",
339 * set the mac_late flag once we've processed modules either linked into the
340 * kernel, or loaded before the kernel startup.
341 */
342 static void
343 mac_late_init(void)
344 {
345
346 mac_late = 1;
347 }
348
349 /*
350 * After the policy list has changed, walk the list to update any global
351 * flags. Currently, we support only one flag, and it's conditionally
352 * defined; as a result, the entire function is conditional. Eventually, the
353 * #else case might also iterate across the policies.
354 */
355 static void
356 mac_policy_updateflags(void)
357 {
358 #ifndef MAC_ALWAYS_LABEL_MBUF
359 struct mac_policy_conf *tmpc;
360 int labelmbufs;
361
362 mac_policy_assert_exclusive();
363
364 labelmbufs = 0;
365 LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) {
366 if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS)
367 labelmbufs++;
368 }
369 LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) {
370 if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS)
371 labelmbufs++;
372 }
373 mac_labelmbufs = (labelmbufs != 0);
374 #endif
375 }
376
377 static int
378 mac_policy_register(struct mac_policy_conf *mpc)
379 {
380 struct mac_policy_conf *tmpc;
381 int error, slot, static_entry;
382
383 error = 0;
384
385 /*
386 * We don't technically need exclusive access while !mac_late, but
387 * hold it for assertion consistency.
388 */
389 mac_policy_grab_exclusive();
390
391 /*
392 * If the module can potentially be unloaded, or we're loading late,
393 * we have to stick it in the non-static list and pay an extra
394 * performance overhead. Otherwise, we can pay a light locking cost
395 * and stick it in the static list.
396 */
397 static_entry = (!mac_late &&
398 !(mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK));
399
400 if (static_entry) {
401 LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) {
402 if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) {
403 error = EEXIST;
404 goto out;
405 }
406 }
407 } else {
408 LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) {
409 if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) {
410 error = EEXIST;
411 goto out;
412 }
413 }
414 }
415 if (mpc->mpc_field_off != NULL) {
416 slot = ffs(mac_slot_offsets_free);
417 if (slot == 0) {
418 error = ENOMEM;
419 goto out;
420 }
421 slot--;
422 mac_slot_offsets_free &= ~(1 << slot);
423 *mpc->mpc_field_off = slot;
424 }
425 mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED;
426
427 /*
428 * If we're loading a MAC module after the framework has initialized,
429 * it has to go into the dynamic list. If we're loading it before
430 * we've finished initializing, it can go into the static list with
431 * weaker locker requirements.
432 */
433 if (static_entry)
434 LIST_INSERT_HEAD(&mac_static_policy_list, mpc, mpc_list);
435 else
436 LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list);
437
438 /*
439 * Per-policy initialization. Currently, this takes place under the
440 * exclusive lock, so policies must not sleep in their init method.
441 * In the future, we may want to separate "init" from "start", with
442 * "init" occuring without the lock held. Likewise, on tear-down,
443 * breaking out "stop" from "destroy".
444 */
445 if (mpc->mpc_ops->mpo_init != NULL)
446 (*(mpc->mpc_ops->mpo_init))(mpc);
447 mac_policy_updateflags();
448
449 SDT_PROBE(mac, kernel, policy, register, mpc, 0, 0, 0, 0);
450 printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname,
451 mpc->mpc_name);
452
453 out:
454 mac_policy_release_exclusive();
455 return (error);
456 }
457
458 static int
459 mac_policy_unregister(struct mac_policy_conf *mpc)
460 {
461
462 /*
463 * If we fail the load, we may get a request to unload. Check to see
464 * if we did the run-time registration, and if not, silently succeed.
465 */
466 mac_policy_grab_exclusive();
467 if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) {
468 mac_policy_release_exclusive();
469 return (0);
470 }
471 #if 0
472 /*
473 * Don't allow unloading modules with private data.
474 */
475 if (mpc->mpc_field_off != NULL) {
476 MAC_POLICY_LIST_UNLOCK();
477 return (EBUSY);
478 }
479 #endif
480 /*
481 * Only allow the unload to proceed if the module is unloadable by
482 * its own definition.
483 */
484 if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) {
485 mac_policy_release_exclusive();
486 return (EBUSY);
487 }
488 if (mpc->mpc_ops->mpo_destroy != NULL)
489 (*(mpc->mpc_ops->mpo_destroy))(mpc);
490
491 LIST_REMOVE(mpc, mpc_list);
492 mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED;
493 mac_policy_updateflags();
494
495 mac_policy_release_exclusive();
496
497 SDT_PROBE(mac, kernel, policy, unregister, mpc, 0, 0, 0, 0);
498 printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname,
499 mpc->mpc_name);
500
501 return (0);
502 }
503
504 /*
505 * Allow MAC policy modules to register during boot, etc.
506 */
507 int
508 mac_policy_modevent(module_t mod, int type, void *data)
509 {
510 struct mac_policy_conf *mpc;
511 int error;
512
513 error = 0;
514 mpc = (struct mac_policy_conf *) data;
515
516 #ifdef MAC_STATIC
517 if (mac_late) {
518 printf("mac_policy_modevent: MAC_STATIC and late\n");
519 return (EBUSY);
520 }
521 #endif
522
523 SDT_PROBE(mac, kernel, policy, modevent, type, mpc, 0, 0, 0);
524 switch (type) {
525 case MOD_LOAD:
526 if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE &&
527 mac_late) {
528 printf("mac_policy_modevent: can't load %s policy "
529 "after booting\n", mpc->mpc_name);
530 error = EBUSY;
531 break;
532 }
533 error = mac_policy_register(mpc);
534 break;
535 case MOD_UNLOAD:
536 /* Don't unregister the module if it was never registered. */
537 if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED)
538 != 0)
539 error = mac_policy_unregister(mpc);
540 else
541 error = 0;
542 break;
543 default:
544 error = EOPNOTSUPP;
545 break;
546 }
547
548 return (error);
549 }
550
551 /*
552 * Define an error value precedence, and given two arguments, selects the
553 * value with the higher precedence.
554 */
555 int
556 mac_error_select(int error1, int error2)
557 {
558
559 /* Certain decision-making errors take top priority. */
560 if (error1 == EDEADLK || error2 == EDEADLK)
561 return (EDEADLK);
562
563 /* Invalid arguments should be reported where possible. */
564 if (error1 == EINVAL || error2 == EINVAL)
565 return (EINVAL);
566
567 /* Precedence goes to "visibility", with both process and file. */
568 if (error1 == ESRCH || error2 == ESRCH)
569 return (ESRCH);
570
571 if (error1 == ENOENT || error2 == ENOENT)
572 return (ENOENT);
573
574 /* Precedence goes to DAC/MAC protections. */
575 if (error1 == EACCES || error2 == EACCES)
576 return (EACCES);
577
578 /* Precedence goes to privilege. */
579 if (error1 == EPERM || error2 == EPERM)
580 return (EPERM);
581
582 /* Precedence goes to error over success; otherwise, arbitrary. */
583 if (error1 != 0)
584 return (error1);
585 return (error2);
586 }
587
588 int
589 mac_check_structmac_consistent(struct mac *mac)
590 {
591
592 if (mac->m_buflen < 0 ||
593 mac->m_buflen > MAC_MAX_LABEL_BUF_LEN)
594 return (EINVAL);
595
596 return (0);
597 }
598
599 SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL);
600 SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL);
Cache object: 9419b6a4929c5103cd0aa6c3f0242c4d
|