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