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