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