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