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