mac_cred.c revision 105474
1/*-
2 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3 * Copyright (c) 2001 Ilmar S. Habibulin
4 * Copyright (c) 2001, 2002 Networks Associates Technology, Inc.
5 * All rights reserved.
6 *
7 * This software was developed by Robert Watson and Ilmar Habibulin for the
8 * TrustedBSD Project.
9 *
10 * This software was developed for the FreeBSD Project in part by NAI Labs,
11 * the Security Research Division of Network Associates, Inc. under
12 * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
13 * CHATS research program.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 *    notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 *    notice, this list of conditions and the following disclaimer in the
22 *    documentation and/or other materials provided with the distribution.
23 * 3. The names of the authors may not be used to endorse or promote
24 *    products derived from this software without specific prior written
25 *    permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 * $FreeBSD: head/sys/security/mac/mac_process.c 105474 2002-10-19 20:30:12Z rwatson $
40 */
41/*
42 * Developed by the TrustedBSD Project.
43 *
44 * Framework for extensible kernel access control.  Kernel and userland
45 * interface to the framework, policy registration and composition.
46 */
47
48#include "opt_mac.h"
49#include "opt_devfs.h"
50
51#include <sys/param.h>
52#include <sys/extattr.h>
53#include <sys/kernel.h>
54#include <sys/lock.h>
55#include <sys/malloc.h>
56#include <sys/mutex.h>
57#include <sys/mac.h>
58#include <sys/module.h>
59#include <sys/proc.h>
60#include <sys/systm.h>
61#include <sys/sysproto.h>
62#include <sys/sysent.h>
63#include <sys/vnode.h>
64#include <sys/mount.h>
65#include <sys/file.h>
66#include <sys/namei.h>
67#include <sys/socket.h>
68#include <sys/pipe.h>
69#include <sys/socketvar.h>
70#include <sys/sysctl.h>
71
72#include <vm/vm.h>
73#include <vm/pmap.h>
74#include <vm/vm_map.h>
75#include <vm/vm_object.h>
76
77#include <sys/mac_policy.h>
78
79#include <fs/devfs/devfs.h>
80
81#include <net/bpfdesc.h>
82#include <net/if.h>
83#include <net/if_var.h>
84
85#include <netinet/in.h>
86#include <netinet/ip_var.h>
87
88#ifdef MAC
89
90/*
91 * Declare that the kernel provides MAC support, version 1.  This permits
92 * modules to refuse to be loaded if the necessary support isn't present,
93 * even if it's pre-boot.
94 */
95MODULE_VERSION(kernel_mac_support, 1);
96
97SYSCTL_DECL(_security);
98
99SYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0,
100    "TrustedBSD MAC policy controls");
101
102#ifndef MAC_MAX_POLICIES
103#define	MAC_MAX_POLICIES	8
104#endif
105#if MAC_MAX_POLICIES > 32
106#error "MAC_MAX_POLICIES too large"
107#endif
108static unsigned int mac_max_policies = MAC_MAX_POLICIES;
109static unsigned int mac_policy_offsets_free = (1 << MAC_MAX_POLICIES) - 1;
110SYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD,
111    &mac_max_policies, 0, "");
112
113static int	mac_late = 0;
114
115static int	mac_enforce_fs = 1;
116SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
117    &mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
118TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
119
120static int	mac_enforce_network = 1;
121SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
122    &mac_enforce_network, 0, "Enforce MAC policy on network packets");
123TUNABLE_INT("security.mac.enforce_network", &mac_enforce_network);
124
125static int	mac_enforce_pipe = 1;
126SYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW,
127    &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations");
128TUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe);
129
130static int	mac_enforce_process = 1;
131SYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW,
132    &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations");
133TUNABLE_INT("security.mac.enforce_process", &mac_enforce_process);
134
135static int	mac_enforce_socket = 1;
136SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
137    &mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
138TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
139
140static int     mac_enforce_vm = 1;
141SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
142    &mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
143TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm);
144
145static int	mac_label_size = sizeof(struct mac);
146SYSCTL_INT(_security_mac, OID_AUTO, label_size, CTLFLAG_RD,
147    &mac_label_size, 0, "Pre-compiled MAC label size");
148
149static int	mac_cache_fslabel_in_vnode = 1;
150SYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW,
151    &mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode");
152TUNABLE_INT("security.mac.cache_fslabel_in_vnode",
153    &mac_cache_fslabel_in_vnode);
154
155static int	mac_vnode_label_cache_hits = 0;
156SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_hits, CTLFLAG_RD,
157    &mac_vnode_label_cache_hits, 0, "Cache hits on vnode labels");
158static int	mac_vnode_label_cache_misses = 0;
159SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_misses, CTLFLAG_RD,
160    &mac_vnode_label_cache_misses, 0, "Cache misses on vnode labels");
161
162static int	mac_mmap_revocation = 1;
163SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW,
164    &mac_mmap_revocation, 0, "Revoke mmap access to files on subject "
165    "relabel");
166static int	mac_mmap_revocation_via_cow = 0;
167SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW,
168    &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via "
169    "copy-on-write semantics, or by removing all write access");
170
171#ifdef MAC_DEBUG
172SYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0,
173    "TrustedBSD MAC debug info");
174
175static int	mac_debug_label_fallback = 0;
176SYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW,
177    &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label"
178    "when label is corrupted.");
179TUNABLE_INT("security.mac.debug_label_fallback",
180    &mac_debug_label_fallback);
181
182SYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0,
183    "TrustedBSD MAC object counters");
184
185static unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs,
186    nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents,
187    nmacipqs, nmacpipes;
188
189SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD,
190    &nmacmbufs, 0, "number of mbufs in use");
191SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD,
192    &nmaccreds, 0, "number of ucreds in use");
193SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD,
194    &nmacifnets, 0, "number of ifnets in use");
195SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD,
196    &nmacipqs, 0, "number of ipqs in use");
197SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD,
198    &nmacbpfdescs, 0, "number of bpfdescs in use");
199SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD,
200    &nmacsockets, 0, "number of sockets in use");
201SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, pipes, CTLFLAG_RD,
202    &nmacpipes, 0, "number of pipes in use");
203SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD,
204    &nmacmounts, 0, "number of mounts in use");
205SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD,
206    &nmactemp, 0, "number of temporary labels in use");
207SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD,
208    &nmacvnodes, 0, "number of vnodes in use");
209SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD,
210    &nmacdevfsdirents, 0, "number of devfs dirents inuse");
211#endif
212
213static int	error_select(int error1, int error2);
214static int	mac_externalize(struct label *label, struct mac *mac);
215static int	mac_policy_register(struct mac_policy_conf *mpc);
216static int	mac_policy_unregister(struct mac_policy_conf *mpc);
217
218static int	mac_stdcreatevnode_ea(struct vnode *vp);
219static void	mac_check_vnode_mmap_downgrade(struct ucred *cred,
220		    struct vnode *vp, int *prot);
221static void	mac_cred_mmapped_drop_perms_recurse(struct thread *td,
222		    struct ucred *cred, struct vm_map *map);
223
224static void	mac_destroy_socket_label(struct label *label);
225
226MALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector");
227MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes");
228
229/*
230 * mac_policy_list_lock protects the consistency of 'mac_policy_list',
231 * the linked list of attached policy modules.  Read-only consumers of
232 * the list must acquire a shared lock for the duration of their use;
233 * writers must acquire an exclusive lock.  Note that for compound
234 * operations, locks should be held for the entire compound operation,
235 * and that this is not yet done for relabel requests.
236 */
237static struct mtx mac_policy_list_lock;
238static LIST_HEAD(, mac_policy_conf) mac_policy_list;
239static int mac_policy_list_busy;
240#define	MAC_POLICY_LIST_LOCKINIT()	mtx_init(&mac_policy_list_lock,	\
241	"mac_policy_list_lock", NULL, MTX_DEF);
242#define	MAC_POLICY_LIST_LOCK()	mtx_lock(&mac_policy_list_lock);
243#define	MAC_POLICY_LIST_UNLOCK()	mtx_unlock(&mac_policy_list_lock);
244
245#define	MAC_POLICY_LIST_BUSY() do {					\
246	MAC_POLICY_LIST_LOCK();						\
247	mac_policy_list_busy++;						\
248	MAC_POLICY_LIST_UNLOCK();					\
249} while (0)
250
251#define	MAC_POLICY_LIST_UNBUSY() do {					\
252	MAC_POLICY_LIST_LOCK();						\
253	mac_policy_list_busy--;						\
254	if (mac_policy_list_busy < 0)					\
255		panic("Extra mac_policy_list_busy--");			\
256	MAC_POLICY_LIST_UNLOCK();					\
257} while (0)
258
259/*
260 * MAC_CHECK performs the designated check by walking the policy
261 * module list and checking with each as to how it feels about the
262 * request.  Note that it returns its value via 'error' in the scope
263 * of the caller.
264 */
265#define	MAC_CHECK(check, args...) do {					\
266	struct mac_policy_conf *mpc;					\
267									\
268	error = 0;							\
269	MAC_POLICY_LIST_BUSY();						\
270	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {			\
271		if (mpc->mpc_ops->mpo_ ## check != NULL)		\
272			error = error_select(				\
273			    mpc->mpc_ops->mpo_ ## check (args),		\
274			    error);					\
275	}								\
276	MAC_POLICY_LIST_UNBUSY();					\
277} while (0)
278
279/*
280 * MAC_BOOLEAN performs the designated boolean composition by walking
281 * the module list, invoking each instance of the operation, and
282 * combining the results using the passed C operator.  Note that it
283 * returns its value via 'result' in the scope of the caller, which
284 * should be initialized by the caller in a meaningful way to get
285 * a meaningful result.
286 */
287#define	MAC_BOOLEAN(operation, composition, args...) do {		\
288	struct mac_policy_conf *mpc;					\
289									\
290	MAC_POLICY_LIST_BUSY();						\
291	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {			\
292		if (mpc->mpc_ops->mpo_ ## operation != NULL)		\
293			result = result composition			\
294			    mpc->mpc_ops->mpo_ ## operation (args);	\
295	}								\
296	MAC_POLICY_LIST_UNBUSY();					\
297} while (0)
298
299/*
300 * MAC_PERFORM performs the designated operation by walking the policy
301 * module list and invoking that operation for each policy.
302 */
303#define	MAC_PERFORM(operation, args...) do {				\
304	struct mac_policy_conf *mpc;					\
305									\
306	MAC_POLICY_LIST_BUSY();						\
307	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {			\
308		if (mpc->mpc_ops->mpo_ ## operation != NULL)		\
309			mpc->mpc_ops->mpo_ ## operation (args);		\
310	}								\
311	MAC_POLICY_LIST_UNBUSY();					\
312} while (0)
313
314/*
315 * Initialize the MAC subsystem, including appropriate SMP locks.
316 */
317static void
318mac_init(void)
319{
320
321	LIST_INIT(&mac_policy_list);
322	MAC_POLICY_LIST_LOCKINIT();
323}
324
325/*
326 * For the purposes of modules that want to know if they were loaded
327 * "early", set the mac_late flag once we've processed modules either
328 * linked into the kernel, or loaded before the kernel startup.
329 */
330static void
331mac_late_init(void)
332{
333
334	mac_late = 1;
335}
336
337/*
338 * Allow MAC policy modules to register during boot, etc.
339 */
340int
341mac_policy_modevent(module_t mod, int type, void *data)
342{
343	struct mac_policy_conf *mpc;
344	int error;
345
346	error = 0;
347	mpc = (struct mac_policy_conf *) data;
348
349	switch (type) {
350	case MOD_LOAD:
351		if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE &&
352		    mac_late) {
353			printf("mac_policy_modevent: can't load %s policy "
354			    "after booting\n", mpc->mpc_name);
355			error = EBUSY;
356			break;
357		}
358		error = mac_policy_register(mpc);
359		break;
360	case MOD_UNLOAD:
361		/* Don't unregister the module if it was never registered. */
362		if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED)
363		    != 0)
364			error = mac_policy_unregister(mpc);
365		else
366			error = 0;
367		break;
368	default:
369		break;
370	}
371
372	return (error);
373}
374
375static int
376mac_policy_register(struct mac_policy_conf *mpc)
377{
378	struct mac_policy_conf *tmpc;
379	struct mac_policy_op_entry *mpe;
380	int slot;
381
382	MALLOC(mpc->mpc_ops, struct mac_policy_ops *, sizeof(*mpc->mpc_ops),
383	    M_MACOPVEC, M_WAITOK | M_ZERO);
384	for (mpe = mpc->mpc_entries; mpe->mpe_constant != MAC_OP_LAST; mpe++) {
385		switch (mpe->mpe_constant) {
386		case MAC_OP_LAST:
387			/*
388			 * Doesn't actually happen, but this allows checking
389			 * that all enumerated values are handled.
390			 */
391			break;
392		case MAC_DESTROY:
393			mpc->mpc_ops->mpo_destroy =
394			    mpe->mpe_function;
395			break;
396		case MAC_INIT:
397			mpc->mpc_ops->mpo_init =
398			    mpe->mpe_function;
399			break;
400		case MAC_SYSCALL:
401			mpc->mpc_ops->mpo_syscall =
402			    mpe->mpe_function;
403			break;
404		case MAC_INIT_BPFDESC_LABEL:
405			mpc->mpc_ops->mpo_init_bpfdesc_label =
406			    mpe->mpe_function;
407			break;
408		case MAC_INIT_CRED_LABEL:
409			mpc->mpc_ops->mpo_init_cred_label =
410			    mpe->mpe_function;
411			break;
412		case MAC_INIT_DEVFSDIRENT_LABEL:
413			mpc->mpc_ops->mpo_init_devfsdirent_label =
414			    mpe->mpe_function;
415			break;
416		case MAC_INIT_IFNET_LABEL:
417			mpc->mpc_ops->mpo_init_ifnet_label =
418			    mpe->mpe_function;
419			break;
420		case MAC_INIT_IPQ_LABEL:
421			mpc->mpc_ops->mpo_init_ipq_label =
422			    mpe->mpe_function;
423			break;
424		case MAC_INIT_MBUF_LABEL:
425			mpc->mpc_ops->mpo_init_mbuf_label =
426			    mpe->mpe_function;
427			break;
428		case MAC_INIT_MOUNT_LABEL:
429			mpc->mpc_ops->mpo_init_mount_label =
430			    mpe->mpe_function;
431			break;
432		case MAC_INIT_MOUNT_FS_LABEL:
433			mpc->mpc_ops->mpo_init_mount_fs_label =
434			    mpe->mpe_function;
435			break;
436		case MAC_INIT_PIPE_LABEL:
437			mpc->mpc_ops->mpo_init_pipe_label =
438			    mpe->mpe_function;
439			break;
440		case MAC_INIT_SOCKET_LABEL:
441			mpc->mpc_ops->mpo_init_socket_label =
442			    mpe->mpe_function;
443			break;
444		case MAC_INIT_SOCKET_PEER_LABEL:
445			mpc->mpc_ops->mpo_init_socket_peer_label =
446			    mpe->mpe_function;
447			break;
448		case MAC_INIT_TEMP_LABEL:
449			mpc->mpc_ops->mpo_init_temp_label =
450			    mpe->mpe_function;
451			break;
452		case MAC_INIT_VNODE_LABEL:
453			mpc->mpc_ops->mpo_init_vnode_label =
454			    mpe->mpe_function;
455			break;
456		case MAC_DESTROY_BPFDESC_LABEL:
457			mpc->mpc_ops->mpo_destroy_bpfdesc_label =
458			    mpe->mpe_function;
459			break;
460		case MAC_DESTROY_CRED_LABEL:
461			mpc->mpc_ops->mpo_destroy_cred_label =
462			    mpe->mpe_function;
463			break;
464		case MAC_DESTROY_DEVFSDIRENT_LABEL:
465			mpc->mpc_ops->mpo_destroy_devfsdirent_label =
466			    mpe->mpe_function;
467			break;
468		case MAC_DESTROY_IFNET_LABEL:
469			mpc->mpc_ops->mpo_destroy_ifnet_label =
470			    mpe->mpe_function;
471			break;
472		case MAC_DESTROY_IPQ_LABEL:
473			mpc->mpc_ops->mpo_destroy_ipq_label =
474			    mpe->mpe_function;
475			break;
476		case MAC_DESTROY_MBUF_LABEL:
477			mpc->mpc_ops->mpo_destroy_mbuf_label =
478			    mpe->mpe_function;
479			break;
480		case MAC_DESTROY_MOUNT_LABEL:
481			mpc->mpc_ops->mpo_destroy_mount_label =
482			    mpe->mpe_function;
483			break;
484		case MAC_DESTROY_MOUNT_FS_LABEL:
485			mpc->mpc_ops->mpo_destroy_mount_fs_label =
486			    mpe->mpe_function;
487			break;
488		case MAC_DESTROY_PIPE_LABEL:
489			mpc->mpc_ops->mpo_destroy_pipe_label =
490			    mpe->mpe_function;
491			break;
492		case MAC_DESTROY_SOCKET_LABEL:
493			mpc->mpc_ops->mpo_destroy_socket_label =
494			    mpe->mpe_function;
495			break;
496		case MAC_DESTROY_SOCKET_PEER_LABEL:
497			mpc->mpc_ops->mpo_destroy_socket_peer_label =
498			    mpe->mpe_function;
499			break;
500		case MAC_DESTROY_TEMP_LABEL:
501			mpc->mpc_ops->mpo_destroy_temp_label =
502			    mpe->mpe_function;
503			break;
504		case MAC_DESTROY_VNODE_LABEL:
505			mpc->mpc_ops->mpo_destroy_vnode_label =
506			    mpe->mpe_function;
507			break;
508		case MAC_EXTERNALIZE:
509			mpc->mpc_ops->mpo_externalize =
510			    mpe->mpe_function;
511			break;
512		case MAC_INTERNALIZE:
513			mpc->mpc_ops->mpo_internalize =
514			    mpe->mpe_function;
515			break;
516		case MAC_CREATE_DEVFS_DEVICE:
517			mpc->mpc_ops->mpo_create_devfs_device =
518			    mpe->mpe_function;
519			break;
520		case MAC_CREATE_DEVFS_DIRECTORY:
521			mpc->mpc_ops->mpo_create_devfs_directory =
522			    mpe->mpe_function;
523			break;
524		case MAC_CREATE_DEVFS_SYMLINK:
525			mpc->mpc_ops->mpo_create_devfs_symlink =
526			    mpe->mpe_function;
527			break;
528		case MAC_CREATE_DEVFS_VNODE:
529			mpc->mpc_ops->mpo_create_devfs_vnode =
530			    mpe->mpe_function;
531			break;
532		case MAC_STDCREATEVNODE_EA:
533			mpc->mpc_ops->mpo_stdcreatevnode_ea =
534			    mpe->mpe_function;
535			break;
536		case MAC_CREATE_VNODE:
537			mpc->mpc_ops->mpo_create_vnode =
538			    mpe->mpe_function;
539			break;
540		case MAC_CREATE_MOUNT:
541			mpc->mpc_ops->mpo_create_mount =
542			    mpe->mpe_function;
543			break;
544		case MAC_CREATE_ROOT_MOUNT:
545			mpc->mpc_ops->mpo_create_root_mount =
546			    mpe->mpe_function;
547			break;
548		case MAC_RELABEL_VNODE:
549			mpc->mpc_ops->mpo_relabel_vnode =
550			    mpe->mpe_function;
551			break;
552		case MAC_UPDATE_DEVFSDIRENT:
553			mpc->mpc_ops->mpo_update_devfsdirent =
554			    mpe->mpe_function;
555			break;
556		case MAC_UPDATE_PROCFSVNODE:
557			mpc->mpc_ops->mpo_update_procfsvnode =
558			    mpe->mpe_function;
559			break;
560		case MAC_UPDATE_VNODE_FROM_EXTATTR:
561			mpc->mpc_ops->mpo_update_vnode_from_extattr =
562			    mpe->mpe_function;
563			break;
564		case MAC_UPDATE_VNODE_FROM_EXTERNALIZED:
565			mpc->mpc_ops->mpo_update_vnode_from_externalized =
566			    mpe->mpe_function;
567			break;
568		case MAC_UPDATE_VNODE_FROM_MOUNT:
569			mpc->mpc_ops->mpo_update_vnode_from_mount =
570			    mpe->mpe_function;
571			break;
572		case MAC_CREATE_MBUF_FROM_SOCKET:
573			mpc->mpc_ops->mpo_create_mbuf_from_socket =
574			    mpe->mpe_function;
575			break;
576		case MAC_CREATE_PIPE:
577			mpc->mpc_ops->mpo_create_pipe =
578			    mpe->mpe_function;
579			break;
580		case MAC_CREATE_SOCKET:
581			mpc->mpc_ops->mpo_create_socket =
582			    mpe->mpe_function;
583			break;
584		case MAC_CREATE_SOCKET_FROM_SOCKET:
585			mpc->mpc_ops->mpo_create_socket_from_socket =
586			    mpe->mpe_function;
587			break;
588		case MAC_RELABEL_PIPE:
589			mpc->mpc_ops->mpo_relabel_pipe =
590			    mpe->mpe_function;
591			break;
592		case MAC_RELABEL_SOCKET:
593			mpc->mpc_ops->mpo_relabel_socket =
594			    mpe->mpe_function;
595			break;
596		case MAC_SET_SOCKET_PEER_FROM_MBUF:
597			mpc->mpc_ops->mpo_set_socket_peer_from_mbuf =
598			    mpe->mpe_function;
599			break;
600		case MAC_SET_SOCKET_PEER_FROM_SOCKET:
601			mpc->mpc_ops->mpo_set_socket_peer_from_socket =
602			    mpe->mpe_function;
603			break;
604		case MAC_CREATE_BPFDESC:
605			mpc->mpc_ops->mpo_create_bpfdesc =
606			    mpe->mpe_function;
607			break;
608		case MAC_CREATE_DATAGRAM_FROM_IPQ:
609			mpc->mpc_ops->mpo_create_datagram_from_ipq =
610			    mpe->mpe_function;
611			break;
612		case MAC_CREATE_FRAGMENT:
613			mpc->mpc_ops->mpo_create_fragment =
614			    mpe->mpe_function;
615			break;
616		case MAC_CREATE_IFNET:
617			mpc->mpc_ops->mpo_create_ifnet =
618			    mpe->mpe_function;
619			break;
620		case MAC_CREATE_IPQ:
621			mpc->mpc_ops->mpo_create_ipq =
622			    mpe->mpe_function;
623			break;
624		case MAC_CREATE_MBUF_FROM_MBUF:
625			mpc->mpc_ops->mpo_create_mbuf_from_mbuf =
626			    mpe->mpe_function;
627			break;
628		case MAC_CREATE_MBUF_LINKLAYER:
629			mpc->mpc_ops->mpo_create_mbuf_linklayer =
630			    mpe->mpe_function;
631			break;
632		case MAC_CREATE_MBUF_FROM_BPFDESC:
633			mpc->mpc_ops->mpo_create_mbuf_from_bpfdesc =
634			    mpe->mpe_function;
635			break;
636		case MAC_CREATE_MBUF_FROM_IFNET:
637			mpc->mpc_ops->mpo_create_mbuf_from_ifnet =
638			    mpe->mpe_function;
639			break;
640		case MAC_CREATE_MBUF_MULTICAST_ENCAP:
641			mpc->mpc_ops->mpo_create_mbuf_multicast_encap =
642			    mpe->mpe_function;
643			break;
644		case MAC_CREATE_MBUF_NETLAYER:
645			mpc->mpc_ops->mpo_create_mbuf_netlayer =
646			    mpe->mpe_function;
647			break;
648		case MAC_FRAGMENT_MATCH:
649			mpc->mpc_ops->mpo_fragment_match =
650			    mpe->mpe_function;
651			break;
652		case MAC_RELABEL_IFNET:
653			mpc->mpc_ops->mpo_relabel_ifnet =
654			    mpe->mpe_function;
655			break;
656		case MAC_UPDATE_IPQ:
657			mpc->mpc_ops->mpo_update_ipq =
658			    mpe->mpe_function;
659			break;
660		case MAC_CREATE_CRED:
661			mpc->mpc_ops->mpo_create_cred =
662			    mpe->mpe_function;
663			break;
664		case MAC_EXECVE_TRANSITION:
665			mpc->mpc_ops->mpo_execve_transition =
666			    mpe->mpe_function;
667			break;
668		case MAC_EXECVE_WILL_TRANSITION:
669			mpc->mpc_ops->mpo_execve_will_transition =
670			    mpe->mpe_function;
671			break;
672		case MAC_CREATE_PROC0:
673			mpc->mpc_ops->mpo_create_proc0 =
674			    mpe->mpe_function;
675			break;
676		case MAC_CREATE_PROC1:
677			mpc->mpc_ops->mpo_create_proc1 =
678			    mpe->mpe_function;
679			break;
680		case MAC_RELABEL_CRED:
681			mpc->mpc_ops->mpo_relabel_cred =
682			    mpe->mpe_function;
683			break;
684		case MAC_THREAD_USERRET:
685			mpc->mpc_ops->mpo_thread_userret =
686			    mpe->mpe_function;
687			break;
688		case MAC_CHECK_BPFDESC_RECEIVE:
689			mpc->mpc_ops->mpo_check_bpfdesc_receive =
690			    mpe->mpe_function;
691			break;
692		case MAC_CHECK_CRED_RELABEL:
693			mpc->mpc_ops->mpo_check_cred_relabel =
694			    mpe->mpe_function;
695			break;
696		case MAC_CHECK_CRED_VISIBLE:
697			mpc->mpc_ops->mpo_check_cred_visible =
698			    mpe->mpe_function;
699			break;
700		case MAC_CHECK_IFNET_RELABEL:
701			mpc->mpc_ops->mpo_check_ifnet_relabel =
702			    mpe->mpe_function;
703			break;
704		case MAC_CHECK_IFNET_TRANSMIT:
705			mpc->mpc_ops->mpo_check_ifnet_transmit =
706			    mpe->mpe_function;
707			break;
708		case MAC_CHECK_MOUNT_STAT:
709			mpc->mpc_ops->mpo_check_mount_stat =
710			    mpe->mpe_function;
711			break;
712		case MAC_CHECK_PIPE_IOCTL:
713			mpc->mpc_ops->mpo_check_pipe_ioctl =
714			    mpe->mpe_function;
715			break;
716		case MAC_CHECK_PIPE_POLL:
717			mpc->mpc_ops->mpo_check_pipe_poll =
718			    mpe->mpe_function;
719			break;
720		case MAC_CHECK_PIPE_READ:
721			mpc->mpc_ops->mpo_check_pipe_read =
722			    mpe->mpe_function;
723			break;
724		case MAC_CHECK_PIPE_RELABEL:
725			mpc->mpc_ops->mpo_check_pipe_relabel =
726			    mpe->mpe_function;
727			break;
728		case MAC_CHECK_PIPE_STAT:
729			mpc->mpc_ops->mpo_check_pipe_stat =
730			    mpe->mpe_function;
731			break;
732		case MAC_CHECK_PIPE_WRITE:
733			mpc->mpc_ops->mpo_check_pipe_write =
734			    mpe->mpe_function;
735			break;
736		case MAC_CHECK_PROC_DEBUG:
737			mpc->mpc_ops->mpo_check_proc_debug =
738			    mpe->mpe_function;
739			break;
740		case MAC_CHECK_PROC_SCHED:
741			mpc->mpc_ops->mpo_check_proc_sched =
742			    mpe->mpe_function;
743			break;
744		case MAC_CHECK_PROC_SIGNAL:
745			mpc->mpc_ops->mpo_check_proc_signal =
746			    mpe->mpe_function;
747			break;
748		case MAC_CHECK_SOCKET_BIND:
749			mpc->mpc_ops->mpo_check_socket_bind =
750			    mpe->mpe_function;
751			break;
752		case MAC_CHECK_SOCKET_CONNECT:
753			mpc->mpc_ops->mpo_check_socket_connect =
754			    mpe->mpe_function;
755			break;
756		case MAC_CHECK_SOCKET_DELIVER:
757			mpc->mpc_ops->mpo_check_socket_deliver =
758			    mpe->mpe_function;
759			break;
760		case MAC_CHECK_SOCKET_LISTEN:
761			mpc->mpc_ops->mpo_check_socket_listen =
762			    mpe->mpe_function;
763			break;
764		case MAC_CHECK_SOCKET_RECEIVE:
765			mpc->mpc_ops->mpo_check_socket_receive =
766			    mpe->mpe_function;
767			break;
768		case MAC_CHECK_SOCKET_RELABEL:
769			mpc->mpc_ops->mpo_check_socket_relabel =
770			    mpe->mpe_function;
771			break;
772		case MAC_CHECK_SOCKET_SEND:
773			mpc->mpc_ops->mpo_check_socket_send =
774			    mpe->mpe_function;
775			break;
776		case MAC_CHECK_SOCKET_VISIBLE:
777			mpc->mpc_ops->mpo_check_socket_visible =
778			    mpe->mpe_function;
779			break;
780		case MAC_CHECK_VNODE_ACCESS:
781			mpc->mpc_ops->mpo_check_vnode_access =
782			    mpe->mpe_function;
783			break;
784		case MAC_CHECK_VNODE_CHDIR:
785			mpc->mpc_ops->mpo_check_vnode_chdir =
786			    mpe->mpe_function;
787			break;
788		case MAC_CHECK_VNODE_CHROOT:
789			mpc->mpc_ops->mpo_check_vnode_chroot =
790			    mpe->mpe_function;
791			break;
792		case MAC_CHECK_VNODE_CREATE:
793			mpc->mpc_ops->mpo_check_vnode_create =
794			    mpe->mpe_function;
795			break;
796		case MAC_CHECK_VNODE_DELETE:
797			mpc->mpc_ops->mpo_check_vnode_delete =
798			    mpe->mpe_function;
799			break;
800		case MAC_CHECK_VNODE_DELETEACL:
801			mpc->mpc_ops->mpo_check_vnode_deleteacl =
802			    mpe->mpe_function;
803			break;
804		case MAC_CHECK_VNODE_EXEC:
805			mpc->mpc_ops->mpo_check_vnode_exec =
806			    mpe->mpe_function;
807			break;
808		case MAC_CHECK_VNODE_GETACL:
809			mpc->mpc_ops->mpo_check_vnode_getacl =
810			    mpe->mpe_function;
811			break;
812		case MAC_CHECK_VNODE_GETEXTATTR:
813			mpc->mpc_ops->mpo_check_vnode_getextattr =
814			    mpe->mpe_function;
815			break;
816		case MAC_CHECK_VNODE_LINK:
817			mpc->mpc_ops->mpo_check_vnode_link =
818			    mpe->mpe_function;
819			break;
820		case MAC_CHECK_VNODE_LOOKUP:
821			mpc->mpc_ops->mpo_check_vnode_lookup =
822			    mpe->mpe_function;
823			break;
824		case MAC_CHECK_VNODE_MMAP:
825			mpc->mpc_ops->mpo_check_vnode_mmap =
826			    mpe->mpe_function;
827			break;
828		case MAC_CHECK_VNODE_MMAP_DOWNGRADE:
829			mpc->mpc_ops->mpo_check_vnode_mmap_downgrade =
830			    mpe->mpe_function;
831			break;
832		case MAC_CHECK_VNODE_MPROTECT:
833			mpc->mpc_ops->mpo_check_vnode_mprotect =
834			    mpe->mpe_function;
835			break;
836		case MAC_CHECK_VNODE_OPEN:
837			mpc->mpc_ops->mpo_check_vnode_open =
838			    mpe->mpe_function;
839			break;
840		case MAC_CHECK_VNODE_POLL:
841			mpc->mpc_ops->mpo_check_vnode_poll =
842			    mpe->mpe_function;
843			break;
844		case MAC_CHECK_VNODE_READ:
845			mpc->mpc_ops->mpo_check_vnode_read =
846			    mpe->mpe_function;
847			break;
848		case MAC_CHECK_VNODE_READDIR:
849			mpc->mpc_ops->mpo_check_vnode_readdir =
850			    mpe->mpe_function;
851			break;
852		case MAC_CHECK_VNODE_READLINK:
853			mpc->mpc_ops->mpo_check_vnode_readlink =
854			    mpe->mpe_function;
855			break;
856		case MAC_CHECK_VNODE_RELABEL:
857			mpc->mpc_ops->mpo_check_vnode_relabel =
858			    mpe->mpe_function;
859			break;
860		case MAC_CHECK_VNODE_RENAME_FROM:
861			mpc->mpc_ops->mpo_check_vnode_rename_from =
862			    mpe->mpe_function;
863			break;
864		case MAC_CHECK_VNODE_RENAME_TO:
865			mpc->mpc_ops->mpo_check_vnode_rename_to =
866			    mpe->mpe_function;
867			break;
868		case MAC_CHECK_VNODE_REVOKE:
869			mpc->mpc_ops->mpo_check_vnode_revoke =
870			    mpe->mpe_function;
871			break;
872		case MAC_CHECK_VNODE_SETACL:
873			mpc->mpc_ops->mpo_check_vnode_setacl =
874			    mpe->mpe_function;
875			break;
876		case MAC_CHECK_VNODE_SETEXTATTR:
877			mpc->mpc_ops->mpo_check_vnode_setextattr =
878			    mpe->mpe_function;
879			break;
880		case MAC_CHECK_VNODE_SETFLAGS:
881			mpc->mpc_ops->mpo_check_vnode_setflags =
882			    mpe->mpe_function;
883			break;
884		case MAC_CHECK_VNODE_SETMODE:
885			mpc->mpc_ops->mpo_check_vnode_setmode =
886			    mpe->mpe_function;
887			break;
888		case MAC_CHECK_VNODE_SETOWNER:
889			mpc->mpc_ops->mpo_check_vnode_setowner =
890			    mpe->mpe_function;
891			break;
892		case MAC_CHECK_VNODE_SETUTIMES:
893			mpc->mpc_ops->mpo_check_vnode_setutimes =
894			    mpe->mpe_function;
895			break;
896		case MAC_CHECK_VNODE_STAT:
897			mpc->mpc_ops->mpo_check_vnode_stat =
898			    mpe->mpe_function;
899			break;
900		case MAC_CHECK_VNODE_WRITE:
901			mpc->mpc_ops->mpo_check_vnode_write =
902			    mpe->mpe_function;
903			break;
904/*
905		default:
906			printf("MAC policy `%s': unknown operation %d\n",
907			    mpc->mpc_name, mpe->mpe_constant);
908			return (EINVAL);
909*/
910		}
911	}
912	MAC_POLICY_LIST_LOCK();
913	if (mac_policy_list_busy > 0) {
914		MAC_POLICY_LIST_UNLOCK();
915		FREE(mpc->mpc_ops, M_MACOPVEC);
916		mpc->mpc_ops = NULL;
917		return (EBUSY);
918	}
919	LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) {
920		if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) {
921			MAC_POLICY_LIST_UNLOCK();
922			FREE(mpc->mpc_ops, M_MACOPVEC);
923			mpc->mpc_ops = NULL;
924			return (EEXIST);
925		}
926	}
927	if (mpc->mpc_field_off != NULL) {
928		slot = ffs(mac_policy_offsets_free);
929		if (slot == 0) {
930			MAC_POLICY_LIST_UNLOCK();
931			FREE(mpc->mpc_ops, M_MACOPVEC);
932			mpc->mpc_ops = NULL;
933			return (ENOMEM);
934		}
935		slot--;
936		mac_policy_offsets_free &= ~(1 << slot);
937		*mpc->mpc_field_off = slot;
938	}
939	mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED;
940	LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list);
941
942	/* Per-policy initialization. */
943	if (mpc->mpc_ops->mpo_init != NULL)
944		(*(mpc->mpc_ops->mpo_init))(mpc);
945	MAC_POLICY_LIST_UNLOCK();
946
947	printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname,
948	    mpc->mpc_name);
949
950	return (0);
951}
952
953static int
954mac_policy_unregister(struct mac_policy_conf *mpc)
955{
956
957	/*
958	 * If we fail the load, we may get a request to unload.  Check
959	 * to see if we did the run-time registration, and if not,
960	 * silently succeed.
961	 */
962	MAC_POLICY_LIST_LOCK();
963	if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) {
964		MAC_POLICY_LIST_UNLOCK();
965		return (0);
966	}
967#if 0
968	/*
969	 * Don't allow unloading modules with private data.
970	 */
971	if (mpc->mpc_field_off != NULL) {
972		MAC_POLICY_LIST_UNLOCK();
973		return (EBUSY);
974	}
975#endif
976	/*
977	 * Only allow the unload to proceed if the module is unloadable
978	 * by its own definition.
979	 */
980	if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) {
981		MAC_POLICY_LIST_UNLOCK();
982		return (EBUSY);
983	}
984	/*
985	 * Right now, we EBUSY if the list is in use.  In the future,
986	 * for reliability reasons, we might want to sleep and wakeup
987	 * later to try again.
988	 */
989	if (mac_policy_list_busy > 0) {
990		MAC_POLICY_LIST_UNLOCK();
991		return (EBUSY);
992	}
993	if (mpc->mpc_ops->mpo_destroy != NULL)
994		(*(mpc->mpc_ops->mpo_destroy))(mpc);
995
996	LIST_REMOVE(mpc, mpc_list);
997	MAC_POLICY_LIST_UNLOCK();
998
999	FREE(mpc->mpc_ops, M_MACOPVEC);
1000	mpc->mpc_ops = NULL;
1001	mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED;
1002
1003	printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname,
1004	    mpc->mpc_name);
1005
1006	return (0);
1007}
1008
1009/*
1010 * Define an error value precedence, and given two arguments, selects the
1011 * value with the higher precedence.
1012 */
1013static int
1014error_select(int error1, int error2)
1015{
1016
1017	/* Certain decision-making errors take top priority. */
1018	if (error1 == EDEADLK || error2 == EDEADLK)
1019		return (EDEADLK);
1020
1021	/* Invalid arguments should be reported where possible. */
1022	if (error1 == EINVAL || error2 == EINVAL)
1023		return (EINVAL);
1024
1025	/* Precedence goes to "visibility", with both process and file. */
1026	if (error1 == ESRCH || error2 == ESRCH)
1027		return (ESRCH);
1028
1029	if (error1 == ENOENT || error2 == ENOENT)
1030		return (ENOENT);
1031
1032	/* Precedence goes to DAC/MAC protections. */
1033	if (error1 == EACCES || error2 == EACCES)
1034		return (EACCES);
1035
1036	/* Precedence goes to privilege. */
1037	if (error1 == EPERM || error2 == EPERM)
1038		return (EPERM);
1039
1040	/* Precedence goes to error over success; otherwise, arbitrary. */
1041	if (error1 != 0)
1042		return (error1);
1043	return (error2);
1044}
1045
1046static void
1047mac_init_label(struct label *label)
1048{
1049
1050	bzero(label, sizeof(*label));
1051	label->l_flags = MAC_FLAG_INITIALIZED;
1052}
1053
1054static void
1055mac_destroy_label(struct label *label)
1056{
1057
1058	KASSERT(label->l_flags & MAC_FLAG_INITIALIZED,
1059	    ("destroying uninitialized label"));
1060
1061	bzero(label, sizeof(*label));
1062	/* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */
1063}
1064
1065static void
1066mac_init_structmac(struct mac *mac)
1067{
1068
1069	bzero(mac, sizeof(*mac));
1070	mac->m_macflags = MAC_FLAG_INITIALIZED;
1071}
1072
1073void
1074mac_init_bpfdesc(struct bpf_d *bpf_d)
1075{
1076
1077	mac_init_label(&bpf_d->bd_label);
1078	MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label);
1079#ifdef MAC_DEBUG
1080	atomic_add_int(&nmacbpfdescs, 1);
1081#endif
1082}
1083
1084void
1085mac_init_cred(struct ucred *cr)
1086{
1087
1088	mac_init_label(&cr->cr_label);
1089	MAC_PERFORM(init_cred_label, &cr->cr_label);
1090#ifdef MAC_DEBUG
1091	atomic_add_int(&nmaccreds, 1);
1092#endif
1093}
1094
1095void
1096mac_init_devfsdirent(struct devfs_dirent *de)
1097{
1098
1099	mac_init_label(&de->de_label);
1100	MAC_PERFORM(init_devfsdirent_label, &de->de_label);
1101#ifdef MAC_DEBUG
1102	atomic_add_int(&nmacdevfsdirents, 1);
1103#endif
1104}
1105
1106void
1107mac_init_ifnet(struct ifnet *ifp)
1108{
1109
1110	mac_init_label(&ifp->if_label);
1111	MAC_PERFORM(init_ifnet_label, &ifp->if_label);
1112#ifdef MAC_DEBUG
1113	atomic_add_int(&nmacifnets, 1);
1114#endif
1115}
1116
1117void
1118mac_init_ipq(struct ipq *ipq)
1119{
1120
1121	mac_init_label(&ipq->ipq_label);
1122	MAC_PERFORM(init_ipq_label, &ipq->ipq_label);
1123#ifdef MAC_DEBUG
1124	atomic_add_int(&nmacipqs, 1);
1125#endif
1126}
1127
1128int
1129mac_init_mbuf(struct mbuf *m, int flag)
1130{
1131	int error;
1132
1133	KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf"));
1134
1135	mac_init_label(&m->m_pkthdr.label);
1136
1137	MAC_CHECK(init_mbuf_label, &m->m_pkthdr.label, flag);
1138	if (error) {
1139		MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label);
1140		mac_destroy_label(&m->m_pkthdr.label);
1141	}
1142
1143#ifdef MAC_DEBUG
1144	if (error == 0)
1145		atomic_add_int(&nmacmbufs, 1);
1146#endif
1147	return (error);
1148}
1149
1150void
1151mac_init_mount(struct mount *mp)
1152{
1153
1154	mac_init_label(&mp->mnt_mntlabel);
1155	mac_init_label(&mp->mnt_fslabel);
1156	MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel);
1157	MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel);
1158#ifdef MAC_DEBUG
1159	atomic_add_int(&nmacmounts, 1);
1160#endif
1161}
1162
1163void
1164mac_init_pipe(struct pipe *pipe)
1165{
1166	struct label *label;
1167
1168	label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK);
1169	mac_init_label(label);
1170	pipe->pipe_label = label;
1171	pipe->pipe_peer->pipe_label = label;
1172	MAC_PERFORM(init_pipe_label, pipe->pipe_label);
1173#ifdef MAC_DEBUG
1174	atomic_add_int(&nmacpipes, 1);
1175#endif
1176}
1177
1178static int
1179mac_init_socket_label(struct label *label, int flag)
1180{
1181	int error;
1182
1183	mac_init_label(label);
1184
1185	MAC_CHECK(init_socket_label, label, flag);
1186	if (error) {
1187		MAC_PERFORM(destroy_socket_label, label);
1188		mac_destroy_label(label);
1189	}
1190
1191#ifdef MAC_DEBUG
1192	if (error == 0)
1193		atomic_add_int(&nmacsockets, 1);
1194#endif
1195
1196	return (error);
1197}
1198
1199static int
1200mac_init_socket_peer_label(struct label *label, int flag)
1201{
1202	int error;
1203
1204	mac_init_label(label);
1205
1206	MAC_CHECK(init_socket_peer_label, label, flag);
1207	if (error) {
1208		MAC_PERFORM(destroy_socket_label, label);
1209		mac_destroy_label(label);
1210	}
1211
1212	return (error);
1213}
1214
1215int
1216mac_init_socket(struct socket *socket, int flag)
1217{
1218	int error;
1219
1220	error = mac_init_socket_label(&socket->so_label, flag);
1221	if (error)
1222		return (error);
1223
1224	error = mac_init_socket_peer_label(&socket->so_peerlabel, flag);
1225	if (error)
1226		mac_destroy_socket_label(&socket->so_label);
1227
1228	return (error);
1229}
1230
1231static void
1232mac_init_temp(struct label *label)
1233{
1234
1235	mac_init_label(label);
1236	MAC_PERFORM(init_temp_label, label);
1237#ifdef MAC_DEBUG
1238	atomic_add_int(&nmactemp, 1);
1239#endif
1240}
1241
1242void
1243mac_init_vnode(struct vnode *vp)
1244{
1245
1246	mac_init_label(&vp->v_label);
1247	MAC_PERFORM(init_vnode_label, &vp->v_label);
1248#ifdef MAC_DEBUG
1249	atomic_add_int(&nmacvnodes, 1);
1250#endif
1251}
1252
1253void
1254mac_destroy_bpfdesc(struct bpf_d *bpf_d)
1255{
1256
1257	MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label);
1258	mac_destroy_label(&bpf_d->bd_label);
1259#ifdef MAC_DEBUG
1260	atomic_subtract_int(&nmacbpfdescs, 1);
1261#endif
1262}
1263
1264void
1265mac_destroy_cred(struct ucred *cr)
1266{
1267
1268	MAC_PERFORM(destroy_cred_label, &cr->cr_label);
1269	mac_destroy_label(&cr->cr_label);
1270#ifdef MAC_DEBUG
1271	atomic_subtract_int(&nmaccreds, 1);
1272#endif
1273}
1274
1275void
1276mac_destroy_devfsdirent(struct devfs_dirent *de)
1277{
1278
1279	MAC_PERFORM(destroy_devfsdirent_label, &de->de_label);
1280	mac_destroy_label(&de->de_label);
1281#ifdef MAC_DEBUG
1282	atomic_subtract_int(&nmacdevfsdirents, 1);
1283#endif
1284}
1285
1286void
1287mac_destroy_ifnet(struct ifnet *ifp)
1288{
1289
1290	MAC_PERFORM(destroy_ifnet_label, &ifp->if_label);
1291	mac_destroy_label(&ifp->if_label);
1292#ifdef MAC_DEBUG
1293	atomic_subtract_int(&nmacifnets, 1);
1294#endif
1295}
1296
1297void
1298mac_destroy_ipq(struct ipq *ipq)
1299{
1300
1301	MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label);
1302	mac_destroy_label(&ipq->ipq_label);
1303#ifdef MAC_DEBUG
1304	atomic_subtract_int(&nmacipqs, 1);
1305#endif
1306}
1307
1308void
1309mac_destroy_mbuf(struct mbuf *m)
1310{
1311
1312	MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label);
1313	mac_destroy_label(&m->m_pkthdr.label);
1314#ifdef MAC_DEBUG
1315	atomic_subtract_int(&nmacmbufs, 1);
1316#endif
1317}
1318
1319void
1320mac_destroy_mount(struct mount *mp)
1321{
1322
1323	MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel);
1324	MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel);
1325	mac_destroy_label(&mp->mnt_fslabel);
1326	mac_destroy_label(&mp->mnt_mntlabel);
1327#ifdef MAC_DEBUG
1328	atomic_subtract_int(&nmacmounts, 1);
1329#endif
1330}
1331
1332void
1333mac_destroy_pipe(struct pipe *pipe)
1334{
1335
1336	MAC_PERFORM(destroy_pipe_label, pipe->pipe_label);
1337	mac_destroy_label(pipe->pipe_label);
1338	free(pipe->pipe_label, M_MACPIPELABEL);
1339#ifdef MAC_DEBUG
1340	atomic_subtract_int(&nmacpipes, 1);
1341#endif
1342}
1343
1344static void
1345mac_destroy_socket_label(struct label *label)
1346{
1347
1348	MAC_PERFORM(destroy_socket_label, label);
1349	mac_destroy_label(label);
1350#ifdef MAC_DEBUG
1351	atomic_subtract_int(&nmacsockets, 1);
1352#endif
1353}
1354
1355static void
1356mac_destroy_socket_peer_label(struct label *label)
1357{
1358
1359	MAC_PERFORM(destroy_socket_peer_label, label);
1360	mac_destroy_label(label);
1361}
1362
1363void
1364mac_destroy_socket(struct socket *socket)
1365{
1366
1367	mac_destroy_socket_label(&socket->so_label);
1368	mac_destroy_socket_peer_label(&socket->so_peerlabel);
1369}
1370
1371static void
1372mac_destroy_temp(struct label *label)
1373{
1374
1375	MAC_PERFORM(destroy_temp_label, label);
1376	mac_destroy_label(label);
1377#ifdef MAC_DEBUG
1378	atomic_subtract_int(&nmactemp, 1);
1379#endif
1380}
1381
1382void
1383mac_destroy_vnode(struct vnode *vp)
1384{
1385
1386	MAC_PERFORM(destroy_vnode_label, &vp->v_label);
1387	mac_destroy_label(&vp->v_label);
1388#ifdef MAC_DEBUG
1389	atomic_subtract_int(&nmacvnodes, 1);
1390#endif
1391}
1392
1393static int
1394mac_externalize(struct label *label, struct mac *mac)
1395{
1396	int error;
1397
1398	mac_init_structmac(mac);
1399	MAC_CHECK(externalize, label, mac);
1400
1401	return (error);
1402}
1403
1404static int
1405mac_internalize(struct label *label, struct mac *mac)
1406{
1407	int error;
1408
1409	mac_init_temp(label);
1410	MAC_CHECK(internalize, label, mac);
1411	if (error)
1412		mac_destroy_temp(label);
1413
1414	return (error);
1415}
1416
1417/*
1418 * Initialize MAC label for the first kernel process, from which other
1419 * kernel processes and threads are spawned.
1420 */
1421void
1422mac_create_proc0(struct ucred *cred)
1423{
1424
1425	MAC_PERFORM(create_proc0, cred);
1426}
1427
1428/*
1429 * Initialize MAC label for the first userland process, from which other
1430 * userland processes and threads are spawned.
1431 */
1432void
1433mac_create_proc1(struct ucred *cred)
1434{
1435
1436	MAC_PERFORM(create_proc1, cred);
1437}
1438
1439void
1440mac_thread_userret(struct thread *td)
1441{
1442
1443	MAC_PERFORM(thread_userret, td);
1444}
1445
1446/*
1447 * When a new process is created, its label must be initialized.  Generally,
1448 * this involves inheritence from the parent process, modulo possible
1449 * deltas.  This function allows that processing to take place.
1450 */
1451void
1452mac_create_cred(struct ucred *parent_cred, struct ucred *child_cred)
1453{
1454
1455	MAC_PERFORM(create_cred, parent_cred, child_cred);
1456}
1457
1458void
1459mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp)
1460{
1461
1462	MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label);
1463}
1464
1465void
1466mac_update_procfsvnode(struct vnode *vp, struct ucred *cred)
1467{
1468
1469	MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred);
1470}
1471
1472/*
1473 * Support callout for policies that manage their own externalization
1474 * using extended attributes.
1475 */
1476static int
1477mac_update_vnode_from_extattr(struct vnode *vp, struct mount *mp)
1478{
1479	int error;
1480
1481	MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp,
1482	    &mp->mnt_fslabel);
1483
1484	return (error);
1485}
1486
1487/*
1488 * Given an externalized mac label, internalize it and stamp it on a
1489 * vnode.
1490 */
1491static int
1492mac_update_vnode_from_externalized(struct vnode *vp, struct mac *extmac)
1493{
1494	int error;
1495
1496	MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac);
1497
1498	return (error);
1499}
1500
1501/*
1502 * Call out to individual policies to update the label in a vnode from
1503 * the mountpoint.
1504 */
1505void
1506mac_update_vnode_from_mount(struct vnode *vp, struct mount *mp)
1507{
1508
1509	MAC_PERFORM(update_vnode_from_mount, vp, &vp->v_label, mp,
1510	    &mp->mnt_fslabel);
1511
1512	ASSERT_VOP_LOCKED(vp, "mac_update_vnode_from_mount");
1513	if (mac_cache_fslabel_in_vnode)
1514		vp->v_vflag |= VV_CACHEDLABEL;
1515}
1516
1517/*
1518 * Implementation of VOP_REFRESHLABEL() that relies on extended attributes
1519 * to store label data.  Can be referenced by filesystems supporting
1520 * extended attributes.
1521 */
1522int
1523vop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap)
1524{
1525	struct vnode *vp = ap->a_vp;
1526	struct mac extmac;
1527	int buflen, error;
1528
1529	ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea");
1530
1531	/*
1532	 * Call out to external policies first.  Order doesn't really
1533	 * matter, as long as failure of one assures failure of all.
1534	 */
1535	error = mac_update_vnode_from_extattr(vp, vp->v_mount);
1536	if (error)
1537		return (error);
1538
1539	buflen = sizeof(extmac);
1540	error = vn_extattr_get(vp, IO_NODELOCKED,
1541	    FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, &buflen,
1542	    (char *)&extmac, curthread);
1543	switch (error) {
1544	case 0:
1545		/* Got it */
1546		break;
1547
1548	case ENOATTR:
1549		/*
1550		 * Use the label from the mount point.
1551		 */
1552		mac_update_vnode_from_mount(vp, vp->v_mount);
1553		return (0);
1554
1555	case EOPNOTSUPP:
1556	default:
1557		/* Fail horribly. */
1558		return (error);
1559	}
1560
1561	if (buflen != sizeof(extmac))
1562		error = EPERM;		/* Fail very closed. */
1563	if (error == 0)
1564		error = mac_update_vnode_from_externalized(vp, &extmac);
1565	if (error == 0)
1566		vp->v_vflag |= VV_CACHEDLABEL;
1567	else {
1568		struct vattr va;
1569
1570		printf("Corrupted label on %s",
1571		    vp->v_mount->mnt_stat.f_mntonname);
1572		if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread) == 0)
1573			printf(" inum %ld", va.va_fileid);
1574#ifdef MAC_DEBUG
1575		if (mac_debug_label_fallback) {
1576			printf(", falling back.\n");
1577			mac_update_vnode_from_mount(vp, vp->v_mount);
1578			error = 0;
1579		} else {
1580#endif
1581			printf(".\n");
1582			error = EPERM;
1583#ifdef MAC_DEBUG
1584		}
1585#endif
1586	}
1587
1588	return (error);
1589}
1590
1591/*
1592 * Make sure the vnode label is up-to-date.  If EOPNOTSUPP, then we handle
1593 * the labeling activity outselves.  Filesystems should be careful not
1594 * to change their minds regarding whether they support vop_refreshlabel()
1595 * for a vnode or not.  Don't cache the vnode here, allow the file
1596 * system code to determine if it's safe to cache.  If we update from
1597 * the mount, don't cache since a change to the mount label should affect
1598 * all vnodes.
1599 */
1600static int
1601vn_refreshlabel(struct vnode *vp, struct ucred *cred)
1602{
1603	int error;
1604
1605	ASSERT_VOP_LOCKED(vp, "vn_refreshlabel");
1606
1607	if (vp->v_mount == NULL) {
1608/*
1609		Eventually, we probably want to special-case refreshing
1610		of deadfs vnodes, and if there's a lock-free race somewhere,
1611		that case might be handled here.
1612
1613		mac_update_vnode_deadfs(vp);
1614		return (0);
1615 */
1616		/* printf("vn_refreshlabel: null v_mount\n"); */
1617		if (vp->v_type != VNON)
1618			printf(
1619			    "vn_refreshlabel: null v_mount with non-VNON\n");
1620		return (EBADF);
1621	}
1622
1623	if (vp->v_vflag & VV_CACHEDLABEL) {
1624		mac_vnode_label_cache_hits++;
1625		return (0);
1626	} else
1627		mac_vnode_label_cache_misses++;
1628
1629	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
1630		mac_update_vnode_from_mount(vp, vp->v_mount);
1631		return (0);
1632	}
1633
1634	error = VOP_REFRESHLABEL(vp, cred, curthread);
1635	switch (error) {
1636	case EOPNOTSUPP:
1637		/*
1638		 * If labels are not supported on this vnode, fall back to
1639		 * the label in the mount and propagate it to the vnode.
1640		 * There should probably be some sort of policy/flag/decision
1641		 * about doing this.
1642		 */
1643		mac_update_vnode_from_mount(vp, vp->v_mount);
1644		error = 0;
1645	default:
1646		return (error);
1647	}
1648}
1649
1650/*
1651 * Helper function for file systems using the vop_std*_ea() calls.  This
1652 * function must be called after EA service is available for the vnode,
1653 * but before it's hooked up to the namespace so that the node persists
1654 * if there's a crash, or before it can be accessed.  On successful
1655 * commit of the label to disk (etc), do cache the label.
1656 */
1657int
1658vop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp, struct ucred *cred)
1659{
1660	struct mac extmac;
1661	int error;
1662
1663	ASSERT_VOP_LOCKED(tvp, "vop_stdcreatevnode_ea");
1664	if ((dvp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
1665		mac_update_vnode_from_mount(tvp, tvp->v_mount);
1666	} else {
1667		error = vn_refreshlabel(dvp, cred);
1668		if (error)
1669			return (error);
1670
1671		/*
1672		 * Stick the label in the vnode.  Then try to write to
1673		 * disk.  If we fail, return a failure to abort the
1674		 * create operation.  Really, this failure shouldn't
1675		 * happen except in fairly unusual circumstances (out
1676		 * of disk, etc).
1677		 */
1678		mac_create_vnode(cred, dvp, tvp);
1679
1680		error = mac_stdcreatevnode_ea(tvp);
1681		if (error)
1682			return (error);
1683
1684		/*
1685		 * XXX: Eventually this will go away and all policies will
1686		 * directly manage their extended attributes.
1687		 */
1688		error = mac_externalize(&tvp->v_label, &extmac);
1689		if (error)
1690			return (error);
1691
1692		error = vn_extattr_set(tvp, IO_NODELOCKED,
1693		    FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
1694		    sizeof(extmac), (char *)&extmac, curthread);
1695		if (error == 0)
1696			tvp->v_vflag |= VV_CACHEDLABEL;
1697		else {
1698#if 0
1699			/*
1700			 * In theory, we could have fall-back behavior here.
1701			 * It would probably be incorrect.
1702			 */
1703#endif
1704			return (error);
1705		}
1706	}
1707
1708	return (0);
1709}
1710
1711void
1712mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp)
1713{
1714	int error;
1715
1716	ASSERT_VOP_LOCKED(vp, "mac_execve_transition");
1717
1718	error = vn_refreshlabel(vp, old);
1719	if (error) {
1720		printf("mac_execve_transition: vn_refreshlabel returned %d\n",
1721		    error);
1722		printf("mac_execve_transition: using old vnode label\n");
1723	}
1724
1725	MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label);
1726}
1727
1728int
1729mac_execve_will_transition(struct ucred *old, struct vnode *vp)
1730{
1731	int error, result;
1732
1733	error = vn_refreshlabel(vp, old);
1734	if (error)
1735		return (error);
1736
1737	result = 0;
1738	MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label);
1739
1740	return (result);
1741}
1742
1743int
1744mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags)
1745{
1746	int error;
1747
1748	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access");
1749
1750	if (!mac_enforce_fs)
1751		return (0);
1752
1753	error = vn_refreshlabel(vp, cred);
1754	if (error)
1755		return (error);
1756
1757	MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags);
1758	return (error);
1759}
1760
1761int
1762mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp)
1763{
1764	int error;
1765
1766	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir");
1767
1768	if (!mac_enforce_fs)
1769		return (0);
1770
1771	error = vn_refreshlabel(dvp, cred);
1772	if (error)
1773		return (error);
1774
1775	MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label);
1776	return (error);
1777}
1778
1779int
1780mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp)
1781{
1782	int error;
1783
1784	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot");
1785
1786	if (!mac_enforce_fs)
1787		return (0);
1788
1789	error = vn_refreshlabel(dvp, cred);
1790	if (error)
1791		return (error);
1792
1793	MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label);
1794	return (error);
1795}
1796
1797int
1798mac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
1799    struct componentname *cnp, struct vattr *vap)
1800{
1801	int error;
1802
1803	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create");
1804
1805	if (!mac_enforce_fs)
1806		return (0);
1807
1808	error = vn_refreshlabel(dvp, cred);
1809	if (error)
1810		return (error);
1811
1812	MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap);
1813	return (error);
1814}
1815
1816int
1817mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp,
1818    struct componentname *cnp)
1819{
1820	int error;
1821
1822	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete");
1823	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete");
1824
1825	if (!mac_enforce_fs)
1826		return (0);
1827
1828	error = vn_refreshlabel(dvp, cred);
1829	if (error)
1830		return (error);
1831	error = vn_refreshlabel(vp, cred);
1832	if (error)
1833		return (error);
1834
1835	MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp,
1836	    &vp->v_label, cnp);
1837	return (error);
1838}
1839
1840int
1841mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
1842    acl_type_t type)
1843{
1844	int error;
1845
1846	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl");
1847
1848	if (!mac_enforce_fs)
1849		return (0);
1850
1851	error = vn_refreshlabel(vp, cred);
1852	if (error)
1853		return (error);
1854
1855	MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type);
1856	return (error);
1857}
1858
1859int
1860mac_check_vnode_exec(struct ucred *cred, struct vnode *vp)
1861{
1862	int error;
1863
1864	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec");
1865
1866	if (!mac_enforce_process && !mac_enforce_fs)
1867		return (0);
1868
1869	error = vn_refreshlabel(vp, cred);
1870	if (error)
1871		return (error);
1872	MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label);
1873
1874	return (error);
1875}
1876
1877int
1878mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
1879{
1880	int error;
1881
1882	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl");
1883
1884	if (!mac_enforce_fs)
1885		return (0);
1886
1887	error = vn_refreshlabel(vp, cred);
1888	if (error)
1889		return (error);
1890
1891	MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type);
1892	return (error);
1893}
1894
1895int
1896mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
1897    int attrnamespace, const char *name, struct uio *uio)
1898{
1899	int error;
1900
1901	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr");
1902
1903	if (!mac_enforce_fs)
1904		return (0);
1905
1906	error = vn_refreshlabel(vp, cred);
1907	if (error)
1908		return (error);
1909
1910	MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label,
1911	    attrnamespace, name, uio);
1912	return (error);
1913}
1914
1915int
1916mac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
1917    struct vnode *vp, struct componentname *cnp)
1918{
1919
1920	int error;
1921
1922	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link");
1923	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link");
1924
1925	if (!mac_enforce_fs)
1926		return (0);
1927
1928	error = vn_refreshlabel(dvp, cred);
1929	if (error)
1930		return (error);
1931
1932	error = vn_refreshlabel(vp, cred);
1933	if (error)
1934		return (error);
1935
1936	MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp,
1937	    &vp->v_label, cnp);
1938	return (error);
1939}
1940
1941int
1942mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
1943    struct componentname *cnp)
1944{
1945	int error;
1946
1947	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup");
1948
1949	if (!mac_enforce_fs)
1950		return (0);
1951
1952	error = vn_refreshlabel(dvp, cred);
1953	if (error)
1954		return (error);
1955
1956	MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp);
1957	return (error);
1958}
1959
1960int
1961mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot)
1962{
1963	int error;
1964
1965	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap");
1966
1967	if (!mac_enforce_fs || !mac_enforce_vm)
1968		return (0);
1969
1970	error = vn_refreshlabel(vp, cred);
1971	if (error)
1972		return (error);
1973
1974	MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot);
1975	return (error);
1976}
1977
1978void
1979mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot)
1980{
1981	int result = *prot;
1982
1983	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade");
1984
1985	if (!mac_enforce_fs || !mac_enforce_vm)
1986		return;
1987
1988	MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label,
1989	    &result);
1990
1991	*prot = result;
1992}
1993
1994int
1995mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot)
1996{
1997	int error;
1998
1999	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect");
2000
2001	if (!mac_enforce_fs || !mac_enforce_vm)
2002		return (0);
2003
2004	error = vn_refreshlabel(vp, cred);
2005	if (error)
2006		return (error);
2007
2008	MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot);
2009	return (error);
2010}
2011
2012int
2013mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode)
2014{
2015	int error;
2016
2017	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open");
2018
2019	if (!mac_enforce_fs)
2020		return (0);
2021
2022	error = vn_refreshlabel(vp, cred);
2023	if (error)
2024		return (error);
2025
2026	MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode);
2027	return (error);
2028}
2029
2030int
2031mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2032    struct vnode *vp)
2033{
2034	int error;
2035
2036	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll");
2037
2038	if (!mac_enforce_fs)
2039		return (0);
2040
2041	error = vn_refreshlabel(vp, active_cred);
2042	if (error)
2043		return (error);
2044
2045	MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp,
2046	    &vp->v_label);
2047
2048	return (error);
2049}
2050
2051int
2052mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2053    struct vnode *vp)
2054{
2055	int error;
2056
2057	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read");
2058
2059	if (!mac_enforce_fs)
2060		return (0);
2061
2062	error = vn_refreshlabel(vp, active_cred);
2063	if (error)
2064		return (error);
2065
2066	MAC_CHECK(check_vnode_read, active_cred, file_cred, vp,
2067	    &vp->v_label);
2068
2069	return (error);
2070}
2071
2072int
2073mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp)
2074{
2075	int error;
2076
2077	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir");
2078
2079	if (!mac_enforce_fs)
2080		return (0);
2081
2082	error = vn_refreshlabel(dvp, cred);
2083	if (error)
2084		return (error);
2085
2086	MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label);
2087	return (error);
2088}
2089
2090int
2091mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp)
2092{
2093	int error;
2094
2095	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink");
2096
2097	if (!mac_enforce_fs)
2098		return (0);
2099
2100	error = vn_refreshlabel(vp, cred);
2101	if (error)
2102		return (error);
2103
2104	MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label);
2105	return (error);
2106}
2107
2108static int
2109mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2110    struct label *newlabel)
2111{
2112	int error;
2113
2114	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel");
2115
2116	error = vn_refreshlabel(vp, cred);
2117	if (error)
2118		return (error);
2119
2120	MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel);
2121
2122	return (error);
2123}
2124
2125int
2126mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2127    struct vnode *vp, struct componentname *cnp)
2128{
2129	int error;
2130
2131	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from");
2132	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from");
2133
2134	if (!mac_enforce_fs)
2135		return (0);
2136
2137	error = vn_refreshlabel(dvp, cred);
2138	if (error)
2139		return (error);
2140	error = vn_refreshlabel(vp, cred);
2141	if (error)
2142		return (error);
2143
2144	MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp,
2145	    &vp->v_label, cnp);
2146	return (error);
2147}
2148
2149int
2150mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2151    struct vnode *vp, int samedir, struct componentname *cnp)
2152{
2153	int error;
2154
2155	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to");
2156	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to");
2157
2158	if (!mac_enforce_fs)
2159		return (0);
2160
2161	error = vn_refreshlabel(dvp, cred);
2162	if (error)
2163		return (error);
2164	if (vp != NULL) {
2165		error = vn_refreshlabel(vp, cred);
2166		if (error)
2167			return (error);
2168	}
2169	MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp,
2170	    vp != NULL ? &vp->v_label : NULL, samedir, cnp);
2171	return (error);
2172}
2173
2174int
2175mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp)
2176{
2177	int error;
2178
2179	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke");
2180
2181	if (!mac_enforce_fs)
2182		return (0);
2183
2184	error = vn_refreshlabel(vp, cred);
2185	if (error)
2186		return (error);
2187
2188	MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label);
2189	return (error);
2190}
2191
2192int
2193mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
2194    struct acl *acl)
2195{
2196	int error;
2197
2198	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl");
2199
2200	if (!mac_enforce_fs)
2201		return (0);
2202
2203	error = vn_refreshlabel(vp, cred);
2204	if (error)
2205		return (error);
2206
2207	MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl);
2208	return (error);
2209}
2210
2211int
2212mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2213    int attrnamespace, const char *name, struct uio *uio)
2214{
2215	int error;
2216
2217	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr");
2218
2219	if (!mac_enforce_fs)
2220		return (0);
2221
2222	error = vn_refreshlabel(vp, cred);
2223	if (error)
2224		return (error);
2225
2226	MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label,
2227	    attrnamespace, name, uio);
2228	return (error);
2229}
2230
2231int
2232mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
2233{
2234	int error;
2235
2236	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags");
2237
2238	if (!mac_enforce_fs)
2239		return (0);
2240
2241	error = vn_refreshlabel(vp, cred);
2242	if (error)
2243		return (error);
2244
2245	MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags);
2246	return (error);
2247}
2248
2249int
2250mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
2251{
2252	int error;
2253
2254	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode");
2255
2256	if (!mac_enforce_fs)
2257		return (0);
2258
2259	error = vn_refreshlabel(vp, cred);
2260	if (error)
2261		return (error);
2262
2263	MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode);
2264	return (error);
2265}
2266
2267int
2268mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
2269    gid_t gid)
2270{
2271	int error;
2272
2273	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner");
2274
2275	if (!mac_enforce_fs)
2276		return (0);
2277
2278	error = vn_refreshlabel(vp, cred);
2279	if (error)
2280		return (error);
2281
2282	MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid);
2283	return (error);
2284}
2285
2286int
2287mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2288    struct timespec atime, struct timespec mtime)
2289{
2290	int error;
2291
2292	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes");
2293
2294	if (!mac_enforce_fs)
2295		return (0);
2296
2297	error = vn_refreshlabel(vp, cred);
2298	if (error)
2299		return (error);
2300
2301	MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime,
2302	    mtime);
2303	return (error);
2304}
2305
2306int
2307mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2308    struct vnode *vp)
2309{
2310	int error;
2311
2312	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat");
2313
2314	if (!mac_enforce_fs)
2315		return (0);
2316
2317	error = vn_refreshlabel(vp, active_cred);
2318	if (error)
2319		return (error);
2320
2321	MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp,
2322	    &vp->v_label);
2323	return (error);
2324}
2325
2326int
2327mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
2328    struct vnode *vp)
2329{
2330	int error;
2331
2332	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write");
2333
2334	if (!mac_enforce_fs)
2335		return (0);
2336
2337	error = vn_refreshlabel(vp, active_cred);
2338	if (error)
2339		return (error);
2340
2341	MAC_CHECK(check_vnode_write, active_cred, file_cred, vp,
2342	    &vp->v_label);
2343
2344	return (error);
2345}
2346
2347/*
2348 * When relabeling a process, call out to the policies for the maximum
2349 * permission allowed for each object type we know about in its
2350 * memory space, and revoke access (in the least surprising ways we
2351 * know) when necessary.  The process lock is not held here.
2352 */
2353static void
2354mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred)
2355{
2356
2357	/* XXX freeze all other threads */
2358	mac_cred_mmapped_drop_perms_recurse(td, cred,
2359	    &td->td_proc->p_vmspace->vm_map);
2360	/* XXX allow other threads to continue */
2361}
2362
2363static __inline const char *
2364prot2str(vm_prot_t prot)
2365{
2366
2367	switch (prot & VM_PROT_ALL) {
2368	case VM_PROT_READ:
2369		return ("r--");
2370	case VM_PROT_READ | VM_PROT_WRITE:
2371		return ("rw-");
2372	case VM_PROT_READ | VM_PROT_EXECUTE:
2373		return ("r-x");
2374	case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
2375		return ("rwx");
2376	case VM_PROT_WRITE:
2377		return ("-w-");
2378	case VM_PROT_EXECUTE:
2379		return ("--x");
2380	case VM_PROT_WRITE | VM_PROT_EXECUTE:
2381		return ("-wx");
2382	default:
2383		return ("---");
2384	}
2385}
2386
2387static void
2388mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred,
2389    struct vm_map *map)
2390{
2391	struct vm_map_entry *vme;
2392	int result;
2393	vm_prot_t revokeperms;
2394	vm_object_t object;
2395	vm_ooffset_t offset;
2396	struct vnode *vp;
2397
2398	if (!mac_mmap_revocation)
2399		return;
2400
2401	vm_map_lock_read(map);
2402	for (vme = map->header.next; vme != &map->header; vme = vme->next) {
2403		if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) {
2404			mac_cred_mmapped_drop_perms_recurse(td, cred,
2405			    vme->object.sub_map);
2406			continue;
2407		}
2408		/*
2409		 * Skip over entries that obviously are not shared.
2410		 */
2411		if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) ||
2412		    !vme->max_protection)
2413			continue;
2414		/*
2415		 * Drill down to the deepest backing object.
2416		 */
2417		offset = vme->offset;
2418		object = vme->object.vm_object;
2419		if (object == NULL)
2420			continue;
2421		while (object->backing_object != NULL) {
2422			object = object->backing_object;
2423			offset += object->backing_object_offset;
2424		}
2425		/*
2426		 * At the moment, vm_maps and objects aren't considered
2427		 * by the MAC system, so only things with backing by a
2428		 * normal object (read: vnodes) are checked.
2429		 */
2430		if (object->type != OBJT_VNODE)
2431			continue;
2432		vp = (struct vnode *)object->handle;
2433		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2434		result = vme->max_protection;
2435		mac_check_vnode_mmap_downgrade(cred, vp, &result);
2436		VOP_UNLOCK(vp, 0, td);
2437		/*
2438		 * Find out what maximum protection we may be allowing
2439		 * now but a policy needs to get removed.
2440		 */
2441		revokeperms = vme->max_protection & ~result;
2442		if (!revokeperms)
2443			continue;
2444		printf("pid %ld: revoking %s perms from %#lx:%ld "
2445		    "(max %s/cur %s)\n", (long)td->td_proc->p_pid,
2446		    prot2str(revokeperms), (u_long)vme->start,
2447		    (long)(vme->end - vme->start),
2448		    prot2str(vme->max_protection), prot2str(vme->protection));
2449		vm_map_lock_upgrade(map);
2450		/*
2451		 * This is the really simple case: if a map has more
2452		 * max_protection than is allowed, but it's not being
2453		 * actually used (that is, the current protection is
2454		 * still allowed), we can just wipe it out and do
2455		 * nothing more.
2456		 */
2457		if ((vme->protection & revokeperms) == 0) {
2458			vme->max_protection -= revokeperms;
2459		} else {
2460			if (revokeperms & VM_PROT_WRITE) {
2461				/*
2462				 * In the more complicated case, flush out all
2463				 * pending changes to the object then turn it
2464				 * copy-on-write.
2465				 */
2466				vm_object_reference(object);
2467				vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2468				vm_object_page_clean(object,
2469				    OFF_TO_IDX(offset),
2470				    OFF_TO_IDX(offset + vme->end - vme->start +
2471					PAGE_MASK),
2472				    OBJPC_SYNC);
2473				VOP_UNLOCK(vp, 0, td);
2474				vm_object_deallocate(object);
2475				/*
2476				 * Why bother if there's no read permissions
2477				 * anymore?  For the rest, we need to leave
2478				 * the write permissions on for COW, or
2479				 * remove them entirely if configured to.
2480				 */
2481				if (!mac_mmap_revocation_via_cow) {
2482					vme->max_protection &= ~VM_PROT_WRITE;
2483					vme->protection &= ~VM_PROT_WRITE;
2484				} if ((revokeperms & VM_PROT_READ) == 0)
2485					vme->eflags |= MAP_ENTRY_COW |
2486					    MAP_ENTRY_NEEDS_COPY;
2487			}
2488			if (revokeperms & VM_PROT_EXECUTE) {
2489				vme->max_protection &= ~VM_PROT_EXECUTE;
2490				vme->protection &= ~VM_PROT_EXECUTE;
2491			}
2492			if (revokeperms & VM_PROT_READ) {
2493				vme->max_protection = 0;
2494				vme->protection = 0;
2495			}
2496			pmap_protect(map->pmap, vme->start, vme->end,
2497			    vme->protection & ~revokeperms);
2498			vm_map_simplify_entry(map, vme);
2499		}
2500		vm_map_lock_downgrade(map);
2501	}
2502	vm_map_unlock_read(map);
2503}
2504
2505/*
2506 * When the subject's label changes, it may require revocation of privilege
2507 * to mapped objects.  This can't be done on-the-fly later with a unified
2508 * buffer cache.
2509 */
2510static void
2511mac_relabel_cred(struct ucred *cred, struct label *newlabel)
2512{
2513
2514	MAC_PERFORM(relabel_cred, cred, newlabel);
2515}
2516
2517void
2518mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel)
2519{
2520
2521	MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel);
2522}
2523
2524void
2525mac_create_ifnet(struct ifnet *ifnet)
2526{
2527
2528	MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label);
2529}
2530
2531void
2532mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d)
2533{
2534
2535	MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label);
2536}
2537
2538void
2539mac_create_socket(struct ucred *cred, struct socket *socket)
2540{
2541
2542	MAC_PERFORM(create_socket, cred, socket, &socket->so_label);
2543}
2544
2545void
2546mac_create_pipe(struct ucred *cred, struct pipe *pipe)
2547{
2548
2549	MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label);
2550}
2551
2552void
2553mac_create_socket_from_socket(struct socket *oldsocket,
2554    struct socket *newsocket)
2555{
2556
2557	MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label,
2558	    newsocket, &newsocket->so_label);
2559}
2560
2561static void
2562mac_relabel_socket(struct ucred *cred, struct socket *socket,
2563    struct label *newlabel)
2564{
2565
2566	MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel);
2567}
2568
2569static void
2570mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel)
2571{
2572
2573	MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel);
2574}
2575
2576void
2577mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket)
2578{
2579
2580	MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label,
2581	    socket, &socket->so_peerlabel);
2582}
2583
2584void
2585mac_set_socket_peer_from_socket(struct socket *oldsocket,
2586    struct socket *newsocket)
2587{
2588
2589	MAC_PERFORM(set_socket_peer_from_socket, oldsocket,
2590	    &oldsocket->so_label, newsocket, &newsocket->so_peerlabel);
2591}
2592
2593void
2594mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram)
2595{
2596
2597	MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label,
2598	    datagram, &datagram->m_pkthdr.label);
2599}
2600
2601void
2602mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment)
2603{
2604
2605	MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label,
2606	    fragment, &fragment->m_pkthdr.label);
2607}
2608
2609void
2610mac_create_ipq(struct mbuf *fragment, struct ipq *ipq)
2611{
2612
2613	MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq,
2614	    &ipq->ipq_label);
2615}
2616
2617void
2618mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf)
2619{
2620
2621	MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label,
2622	    newmbuf, &newmbuf->m_pkthdr.label);
2623}
2624
2625void
2626mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf)
2627{
2628
2629	MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf,
2630	    &mbuf->m_pkthdr.label);
2631}
2632
2633void
2634mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf)
2635{
2636
2637	MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf,
2638	    &mbuf->m_pkthdr.label);
2639}
2640
2641void
2642mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf)
2643{
2644
2645	MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf,
2646	    &mbuf->m_pkthdr.label);
2647}
2648
2649void
2650mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet,
2651    struct mbuf *newmbuf)
2652{
2653
2654	MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf,
2655	    &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf,
2656	    &newmbuf->m_pkthdr.label);
2657}
2658
2659void
2660mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf)
2661{
2662
2663	MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label,
2664	    newmbuf, &newmbuf->m_pkthdr.label);
2665}
2666
2667int
2668mac_fragment_match(struct mbuf *fragment, struct ipq *ipq)
2669{
2670	int result;
2671
2672	result = 1;
2673	MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label,
2674	    ipq, &ipq->ipq_label);
2675
2676	return (result);
2677}
2678
2679void
2680mac_update_ipq(struct mbuf *fragment, struct ipq *ipq)
2681{
2682
2683	MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq,
2684	    &ipq->ipq_label);
2685}
2686
2687void
2688mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf)
2689{
2690
2691	MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf,
2692	    &mbuf->m_pkthdr.label);
2693}
2694
2695void
2696mac_create_mount(struct ucred *cred, struct mount *mp)
2697{
2698
2699	MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel,
2700	    &mp->mnt_fslabel);
2701}
2702
2703void
2704mac_create_root_mount(struct ucred *cred, struct mount *mp)
2705{
2706
2707	MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel,
2708	    &mp->mnt_fslabel);
2709}
2710
2711int
2712mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet)
2713{
2714	int error;
2715
2716	if (!mac_enforce_network)
2717		return (0);
2718
2719	MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet,
2720	    &ifnet->if_label);
2721
2722	return (error);
2723}
2724
2725static int
2726mac_check_cred_relabel(struct ucred *cred, struct label *newlabel)
2727{
2728	int error;
2729
2730	MAC_CHECK(check_cred_relabel, cred, newlabel);
2731
2732	return (error);
2733}
2734
2735int
2736mac_check_cred_visible(struct ucred *u1, struct ucred *u2)
2737{
2738	int error;
2739
2740	if (!mac_enforce_process)
2741		return (0);
2742
2743	MAC_CHECK(check_cred_visible, u1, u2);
2744
2745	return (error);
2746}
2747
2748int
2749mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf)
2750{
2751	int error;
2752
2753	if (!mac_enforce_network)
2754		return (0);
2755
2756	KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr"));
2757	if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED))
2758		printf("%s%d: not initialized\n", ifnet->if_name,
2759		    ifnet->if_unit);
2760
2761	MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf,
2762	    &mbuf->m_pkthdr.label);
2763
2764	return (error);
2765}
2766
2767int
2768mac_check_mount_stat(struct ucred *cred, struct mount *mount)
2769{
2770	int error;
2771
2772	if (!mac_enforce_fs)
2773		return (0);
2774
2775	MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel);
2776
2777	return (error);
2778}
2779
2780int
2781mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd,
2782    void *data)
2783{
2784	int error;
2785
2786	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2787
2788	if (!mac_enforce_pipe)
2789		return (0);
2790
2791	MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data);
2792
2793	return (error);
2794}
2795
2796int
2797mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe)
2798{
2799	int error;
2800
2801	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2802
2803	if (!mac_enforce_pipe)
2804		return (0);
2805
2806	MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label);
2807
2808	return (error);
2809}
2810
2811int
2812mac_check_pipe_read(struct ucred *cred, struct pipe *pipe)
2813{
2814	int error;
2815
2816	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2817
2818	if (!mac_enforce_pipe)
2819		return (0);
2820
2821	MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label);
2822
2823	return (error);
2824}
2825
2826static int
2827mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
2828    struct label *newlabel)
2829{
2830	int error;
2831
2832	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2833
2834	if (!mac_enforce_pipe)
2835		return (0);
2836
2837	MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel);
2838
2839	return (error);
2840}
2841
2842int
2843mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe)
2844{
2845	int error;
2846
2847	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2848
2849	if (!mac_enforce_pipe)
2850		return (0);
2851
2852	MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label);
2853
2854	return (error);
2855}
2856
2857int
2858mac_check_pipe_write(struct ucred *cred, struct pipe *pipe)
2859{
2860	int error;
2861
2862	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2863
2864	if (!mac_enforce_pipe)
2865		return (0);
2866
2867	MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label);
2868
2869	return (error);
2870}
2871
2872int
2873mac_check_proc_debug(struct ucred *cred, struct proc *proc)
2874{
2875	int error;
2876
2877	PROC_LOCK_ASSERT(proc, MA_OWNED);
2878
2879	if (!mac_enforce_process)
2880		return (0);
2881
2882	MAC_CHECK(check_proc_debug, cred, proc);
2883
2884	return (error);
2885}
2886
2887int
2888mac_check_proc_sched(struct ucred *cred, struct proc *proc)
2889{
2890	int error;
2891
2892	PROC_LOCK_ASSERT(proc, MA_OWNED);
2893
2894	if (!mac_enforce_process)
2895		return (0);
2896
2897	MAC_CHECK(check_proc_sched, cred, proc);
2898
2899	return (error);
2900}
2901
2902int
2903mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
2904{
2905	int error;
2906
2907	PROC_LOCK_ASSERT(proc, MA_OWNED);
2908
2909	if (!mac_enforce_process)
2910		return (0);
2911
2912	MAC_CHECK(check_proc_signal, cred, proc, signum);
2913
2914	return (error);
2915}
2916
2917int
2918mac_check_socket_bind(struct ucred *ucred, struct socket *socket,
2919    struct sockaddr *sockaddr)
2920{
2921	int error;
2922
2923	if (!mac_enforce_socket)
2924		return (0);
2925
2926	MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label,
2927	    sockaddr);
2928
2929	return (error);
2930}
2931
2932int
2933mac_check_socket_connect(struct ucred *cred, struct socket *socket,
2934    struct sockaddr *sockaddr)
2935{
2936	int error;
2937
2938	if (!mac_enforce_socket)
2939		return (0);
2940
2941	MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label,
2942	    sockaddr);
2943
2944	return (error);
2945}
2946
2947int
2948mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf)
2949{
2950	int error;
2951
2952	if (!mac_enforce_socket)
2953		return (0);
2954
2955	MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf,
2956	    &mbuf->m_pkthdr.label);
2957
2958	return (error);
2959}
2960
2961int
2962mac_check_socket_listen(struct ucred *cred, struct socket *socket)
2963{
2964	int error;
2965
2966	if (!mac_enforce_socket)
2967		return (0);
2968
2969	MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label);
2970	return (error);
2971}
2972
2973int
2974mac_check_socket_receive(struct ucred *cred, struct socket *so)
2975{
2976	int error;
2977
2978	if (!mac_enforce_socket)
2979		return (0);
2980
2981	MAC_CHECK(check_socket_receive, cred, so, &so->so_label);
2982
2983	return (error);
2984}
2985
2986static int
2987mac_check_socket_relabel(struct ucred *cred, struct socket *socket,
2988    struct label *newlabel)
2989{
2990	int error;
2991
2992	MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label,
2993	    newlabel);
2994
2995	return (error);
2996}
2997
2998int
2999mac_check_socket_send(struct ucred *cred, struct socket *so)
3000{
3001	int error;
3002
3003	if (!mac_enforce_socket)
3004		return (0);
3005
3006	MAC_CHECK(check_socket_send, cred, so, &so->so_label);
3007
3008	return (error);
3009}
3010
3011int
3012mac_check_socket_visible(struct ucred *cred, struct socket *socket)
3013{
3014	int error;
3015
3016	if (!mac_enforce_socket)
3017		return (0);
3018
3019	MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label);
3020
3021	return (error);
3022}
3023
3024int
3025mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
3026    struct ifnet *ifnet)
3027{
3028	struct mac label;
3029	int error;
3030
3031	error = mac_externalize(&ifnet->if_label, &label);
3032	if (error)
3033		return (error);
3034
3035	return (copyout(&label, ifr->ifr_ifru.ifru_data, sizeof(label)));
3036}
3037
3038int
3039mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
3040    struct ifnet *ifnet)
3041{
3042	struct mac newlabel;
3043	struct label intlabel;
3044	int error;
3045
3046	error = copyin(ifr->ifr_ifru.ifru_data, &newlabel, sizeof(newlabel));
3047	if (error)
3048		return (error);
3049
3050	error = mac_internalize(&intlabel, &newlabel);
3051	if (error)
3052		return (error);
3053
3054	/*
3055	 * XXX: Note that this is a redundant privilege check, since
3056	 * policies impose this check themselves if required by the
3057	 * policy.  Eventually, this should go away.
3058	 */
3059	error = suser_cred(cred, 0);
3060	if (error)
3061		goto out;
3062
3063	MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label,
3064	    &intlabel);
3065	if (error)
3066		goto out;
3067
3068	MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel);
3069
3070out:
3071	mac_destroy_temp(&intlabel);
3072	return (error);
3073}
3074
3075void
3076mac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp)
3077{
3078
3079	MAC_PERFORM(create_devfs_vnode, de, &de->de_label, vp, &vp->v_label);
3080}
3081
3082void
3083mac_create_devfs_device(dev_t dev, struct devfs_dirent *de)
3084{
3085
3086	MAC_PERFORM(create_devfs_device, dev, de, &de->de_label);
3087}
3088
3089void
3090mac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
3091    struct devfs_dirent *de)
3092{
3093
3094	MAC_PERFORM(create_devfs_symlink, cred, dd, &dd->de_label, de,
3095	    &de->de_label);
3096}
3097
3098static int
3099mac_stdcreatevnode_ea(struct vnode *vp)
3100{
3101	int error;
3102
3103	MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label);
3104
3105	return (error);
3106}
3107
3108void
3109mac_create_devfs_directory(char *dirname, int dirnamelen,
3110    struct devfs_dirent *de)
3111{
3112
3113	MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de,
3114	    &de->de_label);
3115}
3116
3117/*
3118 * When a new vnode is created, this call will initialize its label.
3119 */
3120void
3121mac_create_vnode(struct ucred *cred, struct vnode *parent,
3122    struct vnode *child)
3123{
3124	int error;
3125
3126	ASSERT_VOP_LOCKED(parent, "mac_create_vnode");
3127	ASSERT_VOP_LOCKED(child, "mac_create_vnode");
3128
3129	error = vn_refreshlabel(parent, cred);
3130	if (error) {
3131		printf("mac_create_vnode: vn_refreshlabel returned %d\n",
3132		    error);
3133		printf("mac_create_vnode: using old vnode label\n");
3134	}
3135
3136	MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child,
3137	    &child->v_label);
3138}
3139
3140int
3141mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
3142    struct mac *extmac)
3143{
3144	struct label intlabel;
3145	int error;
3146
3147	error = mac_internalize(&intlabel, extmac);
3148	if (error)
3149		return (error);
3150
3151	mac_check_socket_relabel(cred, so, &intlabel);
3152	if (error) {
3153		mac_destroy_temp(&intlabel);
3154		return (error);
3155	}
3156
3157	mac_relabel_socket(cred, so, &intlabel);
3158
3159	mac_destroy_temp(&intlabel);
3160	return (0);
3161}
3162
3163int
3164mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label)
3165{
3166	int error;
3167
3168	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
3169
3170	error = mac_check_pipe_relabel(cred, pipe, label);
3171	if (error)
3172		return (error);
3173
3174	mac_relabel_pipe(cred, pipe, label);
3175
3176	return (0);
3177}
3178
3179int
3180mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
3181    struct mac *extmac)
3182{
3183
3184	return (mac_externalize(&so->so_label, extmac));
3185}
3186
3187int
3188mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
3189    struct mac *extmac)
3190{
3191
3192	return (mac_externalize(&so->so_peerlabel, extmac));
3193}
3194
3195/*
3196 * Implementation of VOP_SETLABEL() that relies on extended attributes
3197 * to store label data.  Can be referenced by filesystems supporting
3198 * extended attributes.
3199 */
3200int
3201vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
3202{
3203	struct vnode *vp = ap->a_vp;
3204	struct label *intlabel = ap->a_label;
3205	struct mac extmac;
3206	int error;
3207
3208	ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
3209
3210	/*
3211	 * XXX: Eventually call out to EA check/set calls here.
3212	 * Be particularly careful to avoid race conditions,
3213	 * consistency problems, and stability problems when
3214	 * dealing with multiple EAs.  In particular, we require
3215	 * the ability to write multiple EAs on the same file in
3216	 * a single transaction, which the current EA interface
3217	 * does not provide.
3218	 */
3219
3220	error = mac_externalize(intlabel, &extmac);
3221	if (error)
3222		return (error);
3223
3224	error = vn_extattr_set(vp, IO_NODELOCKED,
3225	    FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
3226	    sizeof(extmac), (char *)&extmac, curthread);
3227	if (error)
3228		return (error);
3229
3230	mac_relabel_vnode(ap->a_cred, vp, intlabel);
3231
3232	vp->v_vflag |= VV_CACHEDLABEL;
3233
3234	return (0);
3235}
3236
3237static int
3238vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred)
3239{
3240	int error;
3241
3242	if (vp->v_mount == NULL) {
3243		/* printf("vn_setlabel: null v_mount\n"); */
3244		if (vp->v_type != VNON)
3245			printf("vn_setlabel: null v_mount with non-VNON\n");
3246		return (EBADF);
3247	}
3248
3249	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
3250		return (EOPNOTSUPP);
3251
3252	/*
3253	 * Multi-phase commit.  First check the policies to confirm the
3254	 * change is OK.  Then commit via the filesystem.  Finally,
3255	 * update the actual vnode label.  Question: maybe the filesystem
3256	 * should update the vnode at the end as part of VOP_SETLABEL()?
3257	 */
3258	error = mac_check_vnode_relabel(cred, vp, intlabel);
3259	if (error)
3260		return (error);
3261
3262	/*
3263	 * VADMIN provides the opportunity for the filesystem to make
3264	 * decisions about who is and is not able to modify labels
3265	 * and protections on files.  This might not be right.  We can't
3266	 * assume VOP_SETLABEL() will do it, because we might implement
3267	 * that as part of vop_stdsetlabel_ea().
3268	 */
3269	error = VOP_ACCESS(vp, VADMIN, cred, curthread);
3270	if (error)
3271		return (error);
3272
3273	error = VOP_SETLABEL(vp, intlabel, cred, curthread);
3274	if (error)
3275		return (error);
3276
3277	return (0);
3278}
3279
3280/*
3281 * MPSAFE
3282 */
3283int
3284__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
3285{
3286	struct mac extmac;
3287	int error;
3288
3289	error = mac_externalize(&td->td_ucred->cr_label, &extmac);
3290	if (error == 0)
3291		error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac));
3292
3293	return (error);
3294}
3295
3296/*
3297 * MPSAFE
3298 */
3299int
3300__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
3301{
3302	struct ucred *newcred, *oldcred;
3303	struct proc *p;
3304	struct mac extmac;
3305	struct label intlabel;
3306	int error;
3307
3308	error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac));
3309	if (error)
3310		return (error);
3311
3312	error = mac_internalize(&intlabel, &extmac);
3313	if (error)
3314		return (error);
3315
3316	newcred = crget();
3317
3318	p = td->td_proc;
3319	PROC_LOCK(p);
3320	oldcred = p->p_ucred;
3321
3322	error = mac_check_cred_relabel(oldcred, &intlabel);
3323	if (error) {
3324		PROC_UNLOCK(p);
3325		mac_destroy_temp(&intlabel);
3326		crfree(newcred);
3327		return (error);
3328	}
3329
3330	setsugid(p);
3331	crcopy(newcred, oldcred);
3332	mac_relabel_cred(newcred, &intlabel);
3333	p->p_ucred = newcred;
3334
3335	/*
3336	 * Grab additional reference for use while revoking mmaps, prior
3337	 * to releasing the proc lock and sharing the cred.
3338	 */
3339	crhold(newcred);
3340	PROC_UNLOCK(p);
3341
3342	mtx_lock(&Giant);
3343	mac_cred_mmapped_drop_perms(td, newcred);
3344	mtx_unlock(&Giant);
3345
3346	crfree(newcred);	/* Free revocation reference. */
3347	crfree(oldcred);
3348	mac_destroy_temp(&intlabel);
3349	return (0);
3350}
3351
3352/*
3353 * MPSAFE
3354 */
3355int
3356__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
3357{
3358	struct file *fp;
3359	struct mac extmac;
3360	struct vnode *vp;
3361	struct pipe *pipe;
3362	int error;
3363
3364	mtx_lock(&Giant);
3365
3366	error = fget(td, SCARG(uap, fd), &fp);
3367	if (error)
3368		goto out;
3369
3370	switch (fp->f_type) {
3371	case DTYPE_FIFO:
3372	case DTYPE_VNODE:
3373		vp = (struct vnode *)fp->f_data;
3374
3375		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3376		error = vn_refreshlabel(vp, td->td_ucred);
3377		if (error == 0)
3378			error = mac_externalize(&vp->v_label, &extmac);
3379		VOP_UNLOCK(vp, 0, td);
3380		break;
3381	case DTYPE_PIPE:
3382		pipe = (struct pipe *)fp->f_data;
3383		error = mac_externalize(pipe->pipe_label, &extmac);
3384		break;
3385	default:
3386		error = EINVAL;
3387	}
3388
3389	if (error == 0)
3390		error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac));
3391
3392	fdrop(fp, td);
3393
3394out:
3395	mtx_unlock(&Giant);
3396	return (error);
3397}
3398
3399/*
3400 * MPSAFE
3401 */
3402int
3403__mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
3404{
3405	struct nameidata nd;
3406	struct mac extmac;
3407	int error;
3408
3409	mtx_lock(&Giant);
3410	NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE,
3411	    SCARG(uap, path_p), td);
3412	error = namei(&nd);
3413	if (error)
3414		goto out;
3415
3416	error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
3417	if (error == 0)
3418		error = mac_externalize(&nd.ni_vp->v_label, &extmac);
3419	NDFREE(&nd, 0);
3420	if (error)
3421		goto out;
3422
3423	error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac));
3424
3425out:
3426	mtx_unlock(&Giant);
3427	return (error);
3428}
3429
3430/*
3431 * MPSAFE
3432 */
3433int
3434__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
3435{
3436	struct file *fp;
3437	struct mac extmac;
3438	struct label intlabel;
3439	struct mount *mp;
3440	struct vnode *vp;
3441	struct pipe *pipe;
3442	int error;
3443
3444	mtx_lock(&Giant);
3445	error = fget(td, SCARG(uap, fd), &fp);
3446	if (error)
3447		goto out1;
3448
3449	error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac));
3450	if (error)
3451		goto out2;
3452
3453	error = mac_internalize(&intlabel, &extmac);
3454	if (error)
3455		goto out2;
3456
3457	switch (fp->f_type) {
3458	case DTYPE_FIFO:
3459	case DTYPE_VNODE:
3460		vp = (struct vnode *)fp->f_data;
3461		error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
3462		if (error != 0)
3463			break;
3464
3465		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3466		error = vn_setlabel(vp, &intlabel, td->td_ucred);
3467		VOP_UNLOCK(vp, 0, td);
3468		vn_finished_write(mp);
3469		mac_destroy_temp(&intlabel);
3470		break;
3471	case DTYPE_PIPE:
3472		pipe = (struct pipe *)fp->f_data;
3473		PIPE_LOCK(pipe);
3474		error = mac_pipe_label_set(td->td_ucred, pipe, &intlabel);
3475		PIPE_UNLOCK(pipe);
3476		break;
3477	default:
3478		error = EINVAL;
3479	}
3480
3481out2:
3482	fdrop(fp, td);
3483out1:
3484	mtx_unlock(&Giant);
3485	return (error);
3486}
3487
3488/*
3489 * MPSAFE
3490 */
3491int
3492__mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
3493{
3494	struct nameidata nd;
3495	struct mac extmac;
3496	struct label intlabel;
3497	struct mount *mp;
3498	int error;
3499
3500	mtx_lock(&Giant);
3501
3502	error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac));
3503	if (error)
3504		goto out;
3505
3506	error = mac_internalize(&intlabel, &extmac);
3507	if (error)
3508		goto out;
3509
3510	NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE,
3511	    SCARG(uap, path_p), td);
3512	error = namei(&nd);
3513	if (error)
3514		goto out2;
3515	error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
3516	if (error)
3517		goto out2;
3518
3519	error = vn_setlabel(nd.ni_vp, &intlabel, td->td_ucred);
3520
3521	vn_finished_write(mp);
3522out2:
3523	mac_destroy_temp(&intlabel);
3524	NDFREE(&nd, 0);
3525out:
3526	mtx_unlock(&Giant);
3527	return (error);
3528}
3529
3530int
3531mac_syscall(struct thread *td, struct mac_syscall_args *uap)
3532{
3533	struct mac_policy_conf *mpc;
3534	char target[MAC_MAX_POLICY_NAME];
3535	int error;
3536
3537	error = copyinstr(SCARG(uap, policy), target, sizeof(target), NULL);
3538	if (error)
3539		return (error);
3540
3541	error = ENOSYS;
3542	MAC_POLICY_LIST_BUSY();
3543	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {
3544		if (strcmp(mpc->mpc_name, target) == 0 &&
3545		    mpc->mpc_ops->mpo_syscall != NULL) {
3546			error = mpc->mpc_ops->mpo_syscall(td,
3547			    SCARG(uap, call), SCARG(uap, arg));
3548			goto out;
3549		}
3550	}
3551
3552out:
3553	MAC_POLICY_LIST_UNBUSY();
3554	return (error);
3555}
3556
3557SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL);
3558SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL);
3559
3560#else /* !MAC */
3561
3562int
3563__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
3564{
3565
3566	return (ENOSYS);
3567}
3568
3569int
3570__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
3571{
3572
3573	return (ENOSYS);
3574}
3575
3576int
3577__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
3578{
3579
3580	return (ENOSYS);
3581}
3582
3583int
3584__mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
3585{
3586
3587	return (ENOSYS);
3588}
3589
3590int
3591__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
3592{
3593
3594	return (ENOSYS);
3595}
3596
3597int
3598__mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
3599{
3600
3601	return (ENOSYS);
3602}
3603
3604int
3605mac_syscall(struct thread *td, struct mac_syscall_args *uap)
3606{
3607
3608	return (ENOSYS);
3609}
3610
3611#endif /* !MAC */
3612