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