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