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 * Copyright (c) 2008-2009 Apple Inc.
7 * All rights reserved.
8 *
9 * This software was developed by Robert Watson and Ilmar Habibulin for the
10 * TrustedBSD Project.
11 *
12 * This software was developed for the FreeBSD Project in part by Network
13 * Associates Laboratories, the Security Research Division of Network
14 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
15 * as part of the DARPA CHATS research program.
16 *
17 * This software was enhanced by SPARTA ISSO under SPAWAR contract
18 * N66001-04-C-6019 ("SEFOS").
19 *
20 * This software was developed at the University of Cambridge Computer
21 * Laboratory with support from a grant from Google, Inc.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the above copyright
27 *    notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 *    notice, this list of conditions and the following disclaimer in the
30 *    documentation and/or other materials provided with the distribution.
31 *
32 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
36 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
40 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
41 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 * SUCH DAMAGE.
43 */
44
45/*-
46 * Framework for extensible kernel access control.  This file contains core
47 * kernel infrastructure for the TrustedBSD MAC Framework, including policy
48 * registration, versioning, locking, error composition operator, and system
49 * calls.
50 *
51 * The MAC Framework implements three programming interfaces:
52 *
53 * - The kernel MAC interface, defined in mac_framework.h, and invoked
54 *   throughout the kernel to request security decisions, notify of security
55 *   related events, etc.
56 *
57 * - The MAC policy module interface, defined in mac_policy.h, which is
58 *   implemented by MAC policy modules and invoked by the MAC Framework to
59 *   forward kernel security requests and notifications to policy modules.
60 *
61 * - The user MAC API, defined in mac.h, which allows user programs to query
62 *   and set label state on objects.
63 *
64 * The majority of the MAC Framework implementation may be found in
65 * src/sys/security/mac.  Sample policy modules may be found in
66 * src/sys/security/mac_*.
67 */
68
69#include "opt_mac.h"
70
71#include <sys/cdefs.h>
72__FBSDID("$FreeBSD: stable/11/sys/security/mac/mac_framework.c 337465 2018-08-08 17:11:07Z markj $");
73
74#include <sys/param.h>
75#include <sys/systm.h>
76#include <sys/condvar.h>
77#include <sys/kernel.h>
78#include <sys/lock.h>
79#include <sys/mac.h>
80#include <sys/module.h>
81#include <sys/rmlock.h>
82#include <sys/sdt.h>
83#include <sys/sx.h>
84#include <sys/sysctl.h>
85
86#include <security/mac/mac_framework.h>
87#include <security/mac/mac_internal.h>
88#include <security/mac/mac_policy.h>
89
90/*
91 * DTrace SDT providers for MAC.
92 */
93SDT_PROVIDER_DEFINE(mac);
94SDT_PROVIDER_DEFINE(mac_framework);
95
96SDT_PROBE_DEFINE2(mac, , policy, modevent, "int",
97    "struct mac_policy_conf *");
98SDT_PROBE_DEFINE1(mac, , policy, register,
99    "struct mac_policy_conf *");
100SDT_PROBE_DEFINE1(mac, , policy, unregister,
101    "struct mac_policy_conf *");
102
103/*
104 * Root sysctl node for all MAC and MAC policy controls.
105 */
106SYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0,
107    "TrustedBSD MAC policy controls");
108
109/*
110 * Declare that the kernel provides MAC support, version 3 (FreeBSD 7.x).
111 * This permits modules to refuse to be loaded if the necessary support isn't
112 * present, even if it's pre-boot.
113 */
114MODULE_VERSION(kernel_mac_support, MAC_VERSION);
115
116static unsigned int	mac_version = MAC_VERSION;
117SYSCTL_UINT(_security_mac, OID_AUTO, version, CTLFLAG_RD, &mac_version, 0,
118    "");
119
120/*
121 * Labels consist of a indexed set of "slots", which are allocated policies
122 * as required.  The MAC Framework maintains a bitmask of slots allocated so
123 * far to prevent reuse.  Slots cannot be reused, as the MAC Framework
124 * guarantees that newly allocated slots in labels will be NULL unless
125 * otherwise initialized, and because we do not have a mechanism to garbage
126 * collect slots on policy unload.  As labeled policies tend to be statically
127 * loaded during boot, and not frequently unloaded and reloaded, this is not
128 * generally an issue.
129 */
130#if MAC_MAX_SLOTS > 32
131#error "MAC_MAX_SLOTS too large"
132#endif
133
134static unsigned int mac_max_slots = MAC_MAX_SLOTS;
135static unsigned int mac_slot_offsets_free = (1 << MAC_MAX_SLOTS) - 1;
136SYSCTL_UINT(_security_mac, OID_AUTO, max_slots, CTLFLAG_RD, &mac_max_slots,
137    0, "");
138
139/*
140 * Has the kernel started generating labeled objects yet?  All read/write
141 * access to this variable is serialized during the boot process.  Following
142 * the end of serialization, we don't update this flag; no locking.
143 */
144static int	mac_late = 0;
145
146/*
147 * Each policy declares a mask of object types requiring labels to be
148 * allocated for them.  For convenience, we combine and cache the bitwise or
149 * of the per-policy object flags to track whether we will allocate a label
150 * for an object type at run-time.
151 */
152uint64_t	mac_labeled;
153SYSCTL_UQUAD(_security_mac, OID_AUTO, labeled, CTLFLAG_RD, &mac_labeled, 0,
154    "Mask of object types being labeled");
155
156MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
157
158/*
159 * MAC policy modules are placed in one of two lists: mac_static_policy_list,
160 * for policies that are loaded early and cannot be unloaded, and
161 * mac_policy_list, which holds policies either loaded later in the boot
162 * cycle or that may be unloaded.  The static policy list does not require
163 * locks to iterate over, but the dynamic list requires synchronization.
164 * Support for dynamic policy loading can be compiled out using the
165 * MAC_STATIC kernel option.
166 *
167 * The dynamic policy list is protected by two locks: modifying the list
168 * requires both locks to be held exclusively.  One of the locks,
169 * mac_policy_rm, is acquired over policy entry points that will never sleep;
170 * the other, mac_policy_sx, is acquire over policy entry points that may
171 * sleep.  The former category will be used when kernel locks may be held
172 * over calls to the MAC Framework, during network processing in ithreads,
173 * etc.  The latter will tend to involve potentially blocking memory
174 * allocations, extended attribute I/O, etc.
175 */
176#ifndef MAC_STATIC
177static struct rmlock mac_policy_rm;	/* Non-sleeping entry points. */
178static struct sx mac_policy_sx;		/* Sleeping entry points. */
179#endif
180
181struct mac_policy_list_head mac_policy_list;
182struct mac_policy_list_head mac_static_policy_list;
183u_int mac_policy_count;			/* Registered policy count. */
184
185static void	mac_policy_xlock(void);
186static void	mac_policy_xlock_assert(void);
187static void	mac_policy_xunlock(void);
188
189void
190mac_policy_slock_nosleep(struct rm_priotracker *tracker)
191{
192
193#ifndef MAC_STATIC
194	if (!mac_late)
195		return;
196
197	rm_rlock(&mac_policy_rm, tracker);
198#endif
199}
200
201void
202mac_policy_slock_sleep(void)
203{
204
205	WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
206 	    "mac_policy_slock_sleep");
207
208#ifndef MAC_STATIC
209	if (!mac_late)
210		return;
211
212	sx_slock(&mac_policy_sx);
213#endif
214}
215
216void
217mac_policy_sunlock_nosleep(struct rm_priotracker *tracker)
218{
219
220#ifndef MAC_STATIC
221	if (!mac_late)
222		return;
223
224	rm_runlock(&mac_policy_rm, tracker);
225#endif
226}
227
228void
229mac_policy_sunlock_sleep(void)
230{
231
232#ifndef MAC_STATIC
233	if (!mac_late)
234		return;
235
236	sx_sunlock(&mac_policy_sx);
237#endif
238}
239
240static void
241mac_policy_xlock(void)
242{
243
244	WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
245 	    "mac_policy_xlock()");
246
247#ifndef MAC_STATIC
248	if (!mac_late)
249		return;
250
251	sx_xlock(&mac_policy_sx);
252	rm_wlock(&mac_policy_rm);
253#endif
254}
255
256static void
257mac_policy_xunlock(void)
258{
259
260#ifndef MAC_STATIC
261	if (!mac_late)
262		return;
263
264	rm_wunlock(&mac_policy_rm);
265	sx_xunlock(&mac_policy_sx);
266#endif
267}
268
269static void
270mac_policy_xlock_assert(void)
271{
272
273#ifndef MAC_STATIC
274	if (!mac_late)
275		return;
276
277	/* XXXRW: rm_assert(&mac_policy_rm, RA_WLOCKED); */
278	sx_assert(&mac_policy_sx, SA_XLOCKED);
279#endif
280}
281
282/*
283 * Initialize the MAC subsystem, including appropriate SMP locks.
284 */
285static void
286mac_init(void)
287{
288
289	LIST_INIT(&mac_static_policy_list);
290	LIST_INIT(&mac_policy_list);
291	mac_labelzone_init();
292
293#ifndef MAC_STATIC
294	rm_init_flags(&mac_policy_rm, "mac_policy_rm", RM_NOWITNESS |
295	    RM_RECURSE);
296	sx_init_flags(&mac_policy_sx, "mac_policy_sx", SX_NOWITNESS);
297#endif
298}
299
300/*
301 * For the purposes of modules that want to know if they were loaded "early",
302 * set the mac_late flag once we've processed modules either linked into the
303 * kernel, or loaded before the kernel startup.
304 */
305static void
306mac_late_init(void)
307{
308
309	mac_late = 1;
310}
311
312/*
313 * Given a policy, derive from its set of non-NULL label init methods what
314 * object types the policy is interested in.
315 */
316static uint64_t
317mac_policy_getlabeled(struct mac_policy_conf *mpc)
318{
319	uint64_t labeled;
320
321#define	MPC_FLAG(method, flag)					\
322	if (mpc->mpc_ops->mpo_ ## method != NULL)			\
323		labeled |= (flag);					\
324
325	labeled = 0;
326	MPC_FLAG(cred_init_label, MPC_OBJECT_CRED);
327	MPC_FLAG(proc_init_label, MPC_OBJECT_PROC);
328	MPC_FLAG(vnode_init_label, MPC_OBJECT_VNODE);
329	MPC_FLAG(inpcb_init_label, MPC_OBJECT_INPCB);
330	MPC_FLAG(socket_init_label, MPC_OBJECT_SOCKET);
331	MPC_FLAG(devfs_init_label, MPC_OBJECT_DEVFS);
332	MPC_FLAG(mbuf_init_label, MPC_OBJECT_MBUF);
333	MPC_FLAG(ipq_init_label, MPC_OBJECT_IPQ);
334	MPC_FLAG(ifnet_init_label, MPC_OBJECT_IFNET);
335	MPC_FLAG(bpfdesc_init_label, MPC_OBJECT_BPFDESC);
336	MPC_FLAG(pipe_init_label, MPC_OBJECT_PIPE);
337	MPC_FLAG(mount_init_label, MPC_OBJECT_MOUNT);
338	MPC_FLAG(posixsem_init_label, MPC_OBJECT_POSIXSEM);
339	MPC_FLAG(posixshm_init_label, MPC_OBJECT_POSIXSHM);
340	MPC_FLAG(sysvmsg_init_label, MPC_OBJECT_SYSVMSG);
341	MPC_FLAG(sysvmsq_init_label, MPC_OBJECT_SYSVMSQ);
342	MPC_FLAG(sysvsem_init_label, MPC_OBJECT_SYSVSEM);
343	MPC_FLAG(sysvshm_init_label, MPC_OBJECT_SYSVSHM);
344	MPC_FLAG(syncache_init_label, MPC_OBJECT_SYNCACHE);
345	MPC_FLAG(ip6q_init_label, MPC_OBJECT_IP6Q);
346
347#undef MPC_FLAG
348	return (labeled);
349}
350
351/*
352 * When policies are loaded or unloaded, walk the list of registered policies
353 * and built mac_labeled, a bitmask representing the union of all objects
354 * requiring labels across all policies.
355 */
356static void
357mac_policy_update(void)
358{
359	struct mac_policy_conf *mpc;
360
361	mac_policy_xlock_assert();
362
363	mac_labeled = 0;
364	mac_policy_count = 0;
365	LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {
366		mac_labeled |= mac_policy_getlabeled(mpc);
367		mac_policy_count++;
368	}
369	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {
370		mac_labeled |= mac_policy_getlabeled(mpc);
371		mac_policy_count++;
372	}
373}
374
375static int
376mac_policy_register(struct mac_policy_conf *mpc)
377{
378	struct mac_policy_conf *tmpc;
379	int error, slot, static_entry;
380
381	error = 0;
382
383	/*
384	 * We don't technically need exclusive access while !mac_late, but
385	 * hold it for assertion consistency.
386	 */
387	mac_policy_xlock();
388
389	/*
390	 * If the module can potentially be unloaded, or we're loading late,
391	 * we have to stick it in the non-static list and pay an extra
392	 * performance overhead.  Otherwise, we can pay a light locking cost
393	 * and stick it in the static list.
394	 */
395	static_entry = (!mac_late &&
396	    !(mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK));
397
398	if (static_entry) {
399		LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) {
400			if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) {
401				error = EEXIST;
402				goto out;
403			}
404		}
405	} else {
406		LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) {
407			if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) {
408				error = EEXIST;
409				goto out;
410			}
411		}
412	}
413	if (mpc->mpc_field_off != NULL) {
414		slot = ffs(mac_slot_offsets_free);
415		if (slot == 0) {
416			error = ENOMEM;
417			goto out;
418		}
419		slot--;
420		mac_slot_offsets_free &= ~(1 << slot);
421		*mpc->mpc_field_off = slot;
422	}
423	mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED;
424
425	/*
426	 * If we're loading a MAC module after the framework has initialized,
427	 * it has to go into the dynamic list.  If we're loading it before
428	 * we've finished initializing, it can go into the static list with
429	 * weaker locker requirements.
430	 */
431	if (static_entry)
432		LIST_INSERT_HEAD(&mac_static_policy_list, mpc, mpc_list);
433	else
434		LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list);
435
436	/*
437	 * Per-policy initialization.  Currently, this takes place under the
438	 * exclusive lock, so policies must not sleep in their init method.
439	 * In the future, we may want to separate "init" from "start", with
440	 * "init" occurring without the lock held.  Likewise, on tear-down,
441	 * breaking out "stop" from "destroy".
442	 */
443	if (mpc->mpc_ops->mpo_init != NULL)
444		(*(mpc->mpc_ops->mpo_init))(mpc);
445	mac_policy_update();
446
447	SDT_PROBE1(mac, , policy, register, mpc);
448	printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname,
449	    mpc->mpc_name);
450
451out:
452	mac_policy_xunlock();
453	return (error);
454}
455
456static int
457mac_policy_unregister(struct mac_policy_conf *mpc)
458{
459
460	/*
461	 * If we fail the load, we may get a request to unload.  Check to see
462	 * if we did the run-time registration, and if not, silently succeed.
463	 */
464	mac_policy_xlock();
465	if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) {
466		mac_policy_xunlock();
467		return (0);
468	}
469#if 0
470	/*
471	 * Don't allow unloading modules with private data.
472	 */
473	if (mpc->mpc_field_off != NULL) {
474		mac_policy_xunlock();
475		return (EBUSY);
476	}
477#endif
478	/*
479	 * Only allow the unload to proceed if the module is unloadable by
480	 * its own definition.
481	 */
482	if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) {
483		mac_policy_xunlock();
484		return (EBUSY);
485	}
486	if (mpc->mpc_ops->mpo_destroy != NULL)
487		(*(mpc->mpc_ops->mpo_destroy))(mpc);
488
489	LIST_REMOVE(mpc, mpc_list);
490	mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED;
491	mac_policy_update();
492	mac_policy_xunlock();
493
494	SDT_PROBE1(mac, , policy, unregister, mpc);
495	printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname,
496	    mpc->mpc_name);
497
498	return (0);
499}
500
501/*
502 * Allow MAC policy modules to register during boot, etc.
503 */
504int
505mac_policy_modevent(module_t mod, int type, void *data)
506{
507	struct mac_policy_conf *mpc;
508	int error;
509
510	error = 0;
511	mpc = (struct mac_policy_conf *) data;
512
513#ifdef MAC_STATIC
514	if (mac_late) {
515		printf("mac_policy_modevent: MAC_STATIC and late\n");
516		return (EBUSY);
517	}
518#endif
519
520	SDT_PROBE2(mac, , policy, modevent, type, mpc);
521	switch (type) {
522	case MOD_LOAD:
523		if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE &&
524		    mac_late) {
525			printf("mac_policy_modevent: can't load %s policy "
526			    "after booting\n", mpc->mpc_name);
527			error = EBUSY;
528			break;
529		}
530		error = mac_policy_register(mpc);
531		break;
532	case MOD_UNLOAD:
533		/* Don't unregister the module if it was never registered. */
534		if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED)
535		    != 0)
536			error = mac_policy_unregister(mpc);
537		else
538			error = 0;
539		break;
540	default:
541		error = EOPNOTSUPP;
542		break;
543	}
544
545	return (error);
546}
547
548/*
549 * Define an error value precedence, and given two arguments, selects the
550 * value with the higher precedence.
551 */
552int
553mac_error_select(int error1, int error2)
554{
555
556	/* Certain decision-making errors take top priority. */
557	if (error1 == EDEADLK || error2 == EDEADLK)
558		return (EDEADLK);
559
560	/* Invalid arguments should be reported where possible. */
561	if (error1 == EINVAL || error2 == EINVAL)
562		return (EINVAL);
563
564	/* Precedence goes to "visibility", with both process and file. */
565	if (error1 == ESRCH || error2 == ESRCH)
566		return (ESRCH);
567
568	if (error1 == ENOENT || error2 == ENOENT)
569		return (ENOENT);
570
571	/* Precedence goes to DAC/MAC protections. */
572	if (error1 == EACCES || error2 == EACCES)
573		return (EACCES);
574
575	/* Precedence goes to privilege. */
576	if (error1 == EPERM || error2 == EPERM)
577		return (EPERM);
578
579	/* Precedence goes to error over success; otherwise, arbitrary. */
580	if (error1 != 0)
581		return (error1);
582	return (error2);
583}
584
585int
586mac_check_structmac_consistent(struct mac *mac)
587{
588
589	/* Require that labels have a non-zero length. */
590	if (mac->m_buflen > MAC_MAX_LABEL_BUF_LEN ||
591	    mac->m_buflen <= sizeof(""))
592		return (EINVAL);
593
594	return (0);
595}
596
597SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL);
598SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL);
599