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