mac_cred.c revision 105716
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 NAI Labs,
11 * the Security Research Division of Network Associates, Inc. under
12 * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
13 * 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 * 3. The names of the authors may not be used to endorse or promote
24 *    products derived from this software without specific prior written
25 *    permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 * $FreeBSD: head/sys/security/mac/mac_process.c 105716 2002-10-22 15:33:33Z rwatson $
40 */
41/*
42 * Developed by the TrustedBSD Project.
43 *
44 * Framework for extensible kernel access control.  Kernel and userland
45 * interface to the framework, policy registration and composition.
46 */
47
48#include "opt_mac.h"
49#include "opt_devfs.h"
50
51#include <sys/param.h>
52#include <sys/extattr.h>
53#include <sys/kernel.h>
54#include <sys/lock.h>
55#include <sys/malloc.h>
56#include <sys/mutex.h>
57#include <sys/mac.h>
58#include <sys/module.h>
59#include <sys/proc.h>
60#include <sys/systm.h>
61#include <sys/sysproto.h>
62#include <sys/sysent.h>
63#include <sys/vnode.h>
64#include <sys/mount.h>
65#include <sys/file.h>
66#include <sys/namei.h>
67#include <sys/socket.h>
68#include <sys/pipe.h>
69#include <sys/socketvar.h>
70#include <sys/sysctl.h>
71
72#include <vm/vm.h>
73#include <vm/pmap.h>
74#include <vm/vm_map.h>
75#include <vm/vm_object.h>
76
77#include <sys/mac_policy.h>
78
79#include <fs/devfs/devfs.h>
80
81#include <net/bpfdesc.h>
82#include <net/if.h>
83#include <net/if_var.h>
84
85#include <netinet/in.h>
86#include <netinet/ip_var.h>
87
88#ifdef MAC
89
90/*
91 * Declare that the kernel provides MAC support, version 1.  This permits
92 * modules to refuse to be loaded if the necessary support isn't present,
93 * even if it's pre-boot.
94 */
95MODULE_VERSION(kernel_mac_support, 1);
96
97SYSCTL_DECL(_security);
98
99SYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0,
100    "TrustedBSD MAC policy controls");
101
102#if MAC_MAX_POLICIES > 32
103#error "MAC_MAX_POLICIES too large"
104#endif
105
106static unsigned int mac_max_policies = MAC_MAX_POLICIES;
107static unsigned int mac_policy_offsets_free = (1 << MAC_MAX_POLICIES) - 1;
108SYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD,
109    &mac_max_policies, 0, "");
110
111static int	mac_late = 0;
112
113static int	mac_enforce_fs = 1;
114SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
115    &mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
116TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
117
118static int	mac_enforce_network = 1;
119SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
120    &mac_enforce_network, 0, "Enforce MAC policy on network packets");
121TUNABLE_INT("security.mac.enforce_network", &mac_enforce_network);
122
123static int	mac_enforce_pipe = 1;
124SYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW,
125    &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations");
126TUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe);
127
128static int	mac_enforce_process = 1;
129SYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW,
130    &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations");
131TUNABLE_INT("security.mac.enforce_process", &mac_enforce_process);
132
133static int	mac_enforce_socket = 1;
134SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
135    &mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
136TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
137
138static int     mac_enforce_vm = 1;
139SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
140    &mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
141TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm);
142
143static int	mac_label_size = sizeof(struct oldmac);
144SYSCTL_INT(_security_mac, OID_AUTO, label_size, CTLFLAG_RD,
145    &mac_label_size, 0, "Pre-compiled MAC label size");
146
147static int	mac_cache_fslabel_in_vnode = 1;
148SYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW,
149    &mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode");
150TUNABLE_INT("security.mac.cache_fslabel_in_vnode",
151    &mac_cache_fslabel_in_vnode);
152
153static int	mac_vnode_label_cache_hits = 0;
154SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_hits, CTLFLAG_RD,
155    &mac_vnode_label_cache_hits, 0, "Cache hits on vnode labels");
156static int	mac_vnode_label_cache_misses = 0;
157SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_misses, CTLFLAG_RD,
158    &mac_vnode_label_cache_misses, 0, "Cache misses on vnode labels");
159
160static int	mac_mmap_revocation = 1;
161SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW,
162    &mac_mmap_revocation, 0, "Revoke mmap access to files on subject "
163    "relabel");
164static int	mac_mmap_revocation_via_cow = 0;
165SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW,
166    &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via "
167    "copy-on-write semantics, or by removing all write access");
168
169#ifdef MAC_DEBUG
170SYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0,
171    "TrustedBSD MAC debug info");
172
173static int	mac_debug_label_fallback = 0;
174SYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW,
175    &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label"
176    "when label is corrupted.");
177TUNABLE_INT("security.mac.debug_label_fallback",
178    &mac_debug_label_fallback);
179
180SYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0,
181    "TrustedBSD MAC object counters");
182
183static unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs,
184    nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents,
185    nmacipqs, nmacpipes;
186
187SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD,
188    &nmacmbufs, 0, "number of mbufs in use");
189SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD,
190    &nmaccreds, 0, "number of ucreds in use");
191SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD,
192    &nmacifnets, 0, "number of ifnets in use");
193SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD,
194    &nmacipqs, 0, "number of ipqs in use");
195SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD,
196    &nmacbpfdescs, 0, "number of bpfdescs in use");
197SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD,
198    &nmacsockets, 0, "number of sockets in use");
199SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, pipes, CTLFLAG_RD,
200    &nmacpipes, 0, "number of pipes in use");
201SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD,
202    &nmacmounts, 0, "number of mounts in use");
203SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD,
204    &nmactemp, 0, "number of temporary labels in use");
205SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD,
206    &nmacvnodes, 0, "number of vnodes in use");
207SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD,
208    &nmacdevfsdirents, 0, "number of devfs dirents inuse");
209#endif
210
211static int	error_select(int error1, int error2);
212static int	mac_externalize_vnode_oldmac(struct label *label,
213		    struct oldmac *extmac);
214static int	mac_policy_register(struct mac_policy_conf *mpc);
215static int	mac_policy_unregister(struct mac_policy_conf *mpc);
216
217static int	mac_stdcreatevnode_ea(struct vnode *vp);
218static void	mac_check_vnode_mmap_downgrade(struct ucred *cred,
219		    struct vnode *vp, int *prot);
220static void	mac_cred_mmapped_drop_perms_recurse(struct thread *td,
221		    struct ucred *cred, struct vm_map *map);
222
223static void	mac_destroy_socket_label(struct label *label);
224
225MALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector");
226MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes");
227MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
228
229/*
230 * mac_policy_list_lock protects the consistency of 'mac_policy_list',
231 * the linked list of attached policy modules.  Read-only consumers of
232 * the list must acquire a shared lock for the duration of their use;
233 * writers must acquire an exclusive lock.  Note that for compound
234 * operations, locks should be held for the entire compound operation,
235 * and that this is not yet done for relabel requests.
236 */
237static struct mtx mac_policy_list_lock;
238static LIST_HEAD(, mac_policy_conf) mac_policy_list;
239static int mac_policy_list_busy;
240#define	MAC_POLICY_LIST_LOCKINIT()	mtx_init(&mac_policy_list_lock,	\
241	"mac_policy_list_lock", NULL, MTX_DEF);
242#define	MAC_POLICY_LIST_LOCK()	mtx_lock(&mac_policy_list_lock);
243#define	MAC_POLICY_LIST_UNLOCK()	mtx_unlock(&mac_policy_list_lock);
244
245#define	MAC_POLICY_LIST_BUSY() do {					\
246	MAC_POLICY_LIST_LOCK();						\
247	mac_policy_list_busy++;						\
248	MAC_POLICY_LIST_UNLOCK();					\
249} while (0)
250
251#define	MAC_POLICY_LIST_UNBUSY() do {					\
252	MAC_POLICY_LIST_LOCK();						\
253	mac_policy_list_busy--;						\
254	if (mac_policy_list_busy < 0)					\
255		panic("Extra mac_policy_list_busy--");			\
256	MAC_POLICY_LIST_UNLOCK();					\
257} while (0)
258
259/*
260 * MAC_CHECK performs the designated check by walking the policy
261 * module list and checking with each as to how it feels about the
262 * request.  Note that it returns its value via 'error' in the scope
263 * of the caller.
264 */
265#define	MAC_CHECK(check, args...) do {					\
266	struct mac_policy_conf *mpc;					\
267									\
268	error = 0;							\
269	MAC_POLICY_LIST_BUSY();						\
270	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {			\
271		if (mpc->mpc_ops->mpo_ ## check != NULL)		\
272			error = error_select(				\
273			    mpc->mpc_ops->mpo_ ## check (args),		\
274			    error);					\
275	}								\
276	MAC_POLICY_LIST_UNBUSY();					\
277} while (0)
278
279/*
280 * MAC_BOOLEAN performs the designated boolean composition by walking
281 * the module list, invoking each instance of the operation, and
282 * combining the results using the passed C operator.  Note that it
283 * returns its value via 'result' in the scope of the caller, which
284 * should be initialized by the caller in a meaningful way to get
285 * a meaningful result.
286 */
287#define	MAC_BOOLEAN(operation, composition, args...) do {		\
288	struct mac_policy_conf *mpc;					\
289									\
290	MAC_POLICY_LIST_BUSY();						\
291	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {			\
292		if (mpc->mpc_ops->mpo_ ## operation != NULL)		\
293			result = result composition			\
294			    mpc->mpc_ops->mpo_ ## operation (args);	\
295	}								\
296	MAC_POLICY_LIST_UNBUSY();					\
297} while (0)
298
299#define	MAC_EXTERNALIZE(type, label, elementlist, outbuf, 		\
300    outbuflen) do {							\
301	char *curptr, *curptr_start, *element_name, *element_temp;	\
302	size_t left, left_start, len;					\
303	int claimed, first, first_start, ignorenotfound;		\
304									\
305	error = 0;							\
306	element_temp = elementlist;					\
307	curptr = outbuf;						\
308	curptr[0] = '\0';						\
309	left = outbuflen;						\
310	first = 1;							\
311	while ((element_name = strsep(&element_temp, ",")) != NULL) {	\
312		curptr_start = curptr;					\
313		left_start = left;					\
314		first_start = first;					\
315		if (element_name[0] == '?') {				\
316			element_name++;					\
317			ignorenotfound = 1;				\
318		} else							\
319			ignorenotfound = 0;				\
320		claimed = 0;						\
321		if (first) {						\
322			len = snprintf(curptr, left, "%s/",		\
323			    element_name);				\
324			first = 0;					\
325		} else							\
326			len = snprintf(curptr, left, ",%s/",		\
327			    element_name);				\
328		if (len >= left) {					\
329			error = EINVAL;		/* XXXMAC: E2BIG */	\
330			break;						\
331		}							\
332		curptr += len;						\
333		left -= len;						\
334									\
335		MAC_CHECK(externalize_ ## type, label, element_name,	\
336		    curptr, left, &len, &claimed);			\
337		if (error)						\
338			break;						\
339		if (claimed == 1) {					\
340			if (len >= outbuflen) {				\
341				error = EINVAL;	/* XXXMAC: E2BIG */	\
342				break;					\
343			}						\
344			curptr += len;					\
345			left -= len;					\
346		} else if (claimed == 0 && ignorenotfound) {		\
347			/*						\
348			 * Revert addition of the label element		\
349			 * name.					\
350			 */						\
351			curptr = curptr_start;				\
352			*curptr = '\0';					\
353			left = left_start;				\
354			first = first_start;				\
355		} else {						\
356			error = EINVAL;		/* XXXMAC: ENOLABEL */	\
357			break;						\
358		}							\
359	}								\
360} while (0)
361
362#define	MAC_INTERNALIZE(type, label, instring) do {			\
363	char *element, *element_name, *element_data;			\
364	int claimed;							\
365									\
366	error = 0;							\
367	element = instring;						\
368	while ((element_name = strsep(&element, ",")) != NULL) {	\
369		element_data = element_name;				\
370		element_name = strsep(&element_data, "/");		\
371		if (element_data == NULL) {				\
372			error = EINVAL;					\
373			break;						\
374		}							\
375		claimed = 0;						\
376		MAC_CHECK(internalize_ ## type, label, element_name,	\
377		    element_data, &claimed);				\
378		if (error)						\
379			break;						\
380		if (claimed != 1) {					\
381			/* XXXMAC: Another error here? */		\
382			error = EINVAL;					\
383			break;						\
384		}							\
385	}								\
386} while (0)
387
388/*
389 * MAC_PERFORM performs the designated operation by walking the policy
390 * module list and invoking that operation for each policy.
391 */
392#define	MAC_PERFORM(operation, args...) do {				\
393	struct mac_policy_conf *mpc;					\
394									\
395	MAC_POLICY_LIST_BUSY();						\
396	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {			\
397		if (mpc->mpc_ops->mpo_ ## operation != NULL)		\
398			mpc->mpc_ops->mpo_ ## operation (args);		\
399	}								\
400	MAC_POLICY_LIST_UNBUSY();					\
401} while (0)
402
403/*
404 * Initialize the MAC subsystem, including appropriate SMP locks.
405 */
406static void
407mac_init(void)
408{
409
410	LIST_INIT(&mac_policy_list);
411	MAC_POLICY_LIST_LOCKINIT();
412}
413
414/*
415 * For the purposes of modules that want to know if they were loaded
416 * "early", set the mac_late flag once we've processed modules either
417 * linked into the kernel, or loaded before the kernel startup.
418 */
419static void
420mac_late_init(void)
421{
422
423	mac_late = 1;
424}
425
426/*
427 * Allow MAC policy modules to register during boot, etc.
428 */
429int
430mac_policy_modevent(module_t mod, int type, void *data)
431{
432	struct mac_policy_conf *mpc;
433	int error;
434
435	error = 0;
436	mpc = (struct mac_policy_conf *) data;
437
438	switch (type) {
439	case MOD_LOAD:
440		if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE &&
441		    mac_late) {
442			printf("mac_policy_modevent: can't load %s policy "
443			    "after booting\n", mpc->mpc_name);
444			error = EBUSY;
445			break;
446		}
447		error = mac_policy_register(mpc);
448		break;
449	case MOD_UNLOAD:
450		/* Don't unregister the module if it was never registered. */
451		if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED)
452		    != 0)
453			error = mac_policy_unregister(mpc);
454		else
455			error = 0;
456		break;
457	default:
458		break;
459	}
460
461	return (error);
462}
463
464static int
465mac_policy_register(struct mac_policy_conf *mpc)
466{
467	struct mac_policy_conf *tmpc;
468	struct mac_policy_op_entry *mpe;
469	int slot;
470
471	MALLOC(mpc->mpc_ops, struct mac_policy_ops *, sizeof(*mpc->mpc_ops),
472	    M_MACOPVEC, M_WAITOK | M_ZERO);
473	for (mpe = mpc->mpc_entries; mpe->mpe_constant != MAC_OP_LAST; mpe++) {
474		switch (mpe->mpe_constant) {
475		case MAC_OP_LAST:
476			/*
477			 * Doesn't actually happen, but this allows checking
478			 * that all enumerated values are handled.
479			 */
480			break;
481		case MAC_DESTROY:
482			mpc->mpc_ops->mpo_destroy =
483			    mpe->mpe_function;
484			break;
485		case MAC_INIT:
486			mpc->mpc_ops->mpo_init =
487			    mpe->mpe_function;
488			break;
489		case MAC_SYSCALL:
490			mpc->mpc_ops->mpo_syscall =
491			    mpe->mpe_function;
492			break;
493		case MAC_INIT_BPFDESC_LABEL:
494			mpc->mpc_ops->mpo_init_bpfdesc_label =
495			    mpe->mpe_function;
496			break;
497		case MAC_INIT_CRED_LABEL:
498			mpc->mpc_ops->mpo_init_cred_label =
499			    mpe->mpe_function;
500			break;
501		case MAC_INIT_DEVFSDIRENT_LABEL:
502			mpc->mpc_ops->mpo_init_devfsdirent_label =
503			    mpe->mpe_function;
504			break;
505		case MAC_INIT_IFNET_LABEL:
506			mpc->mpc_ops->mpo_init_ifnet_label =
507			    mpe->mpe_function;
508			break;
509		case MAC_INIT_IPQ_LABEL:
510			mpc->mpc_ops->mpo_init_ipq_label =
511			    mpe->mpe_function;
512			break;
513		case MAC_INIT_MBUF_LABEL:
514			mpc->mpc_ops->mpo_init_mbuf_label =
515			    mpe->mpe_function;
516			break;
517		case MAC_INIT_MOUNT_LABEL:
518			mpc->mpc_ops->mpo_init_mount_label =
519			    mpe->mpe_function;
520			break;
521		case MAC_INIT_MOUNT_FS_LABEL:
522			mpc->mpc_ops->mpo_init_mount_fs_label =
523			    mpe->mpe_function;
524			break;
525		case MAC_INIT_PIPE_LABEL:
526			mpc->mpc_ops->mpo_init_pipe_label =
527			    mpe->mpe_function;
528			break;
529		case MAC_INIT_SOCKET_LABEL:
530			mpc->mpc_ops->mpo_init_socket_label =
531			    mpe->mpe_function;
532			break;
533		case MAC_INIT_SOCKET_PEER_LABEL:
534			mpc->mpc_ops->mpo_init_socket_peer_label =
535			    mpe->mpe_function;
536			break;
537		case MAC_INIT_VNODE_LABEL:
538			mpc->mpc_ops->mpo_init_vnode_label =
539			    mpe->mpe_function;
540			break;
541		case MAC_DESTROY_BPFDESC_LABEL:
542			mpc->mpc_ops->mpo_destroy_bpfdesc_label =
543			    mpe->mpe_function;
544			break;
545		case MAC_DESTROY_CRED_LABEL:
546			mpc->mpc_ops->mpo_destroy_cred_label =
547			    mpe->mpe_function;
548			break;
549		case MAC_DESTROY_DEVFSDIRENT_LABEL:
550			mpc->mpc_ops->mpo_destroy_devfsdirent_label =
551			    mpe->mpe_function;
552			break;
553		case MAC_DESTROY_IFNET_LABEL:
554			mpc->mpc_ops->mpo_destroy_ifnet_label =
555			    mpe->mpe_function;
556			break;
557		case MAC_DESTROY_IPQ_LABEL:
558			mpc->mpc_ops->mpo_destroy_ipq_label =
559			    mpe->mpe_function;
560			break;
561		case MAC_DESTROY_MBUF_LABEL:
562			mpc->mpc_ops->mpo_destroy_mbuf_label =
563			    mpe->mpe_function;
564			break;
565		case MAC_DESTROY_MOUNT_LABEL:
566			mpc->mpc_ops->mpo_destroy_mount_label =
567			    mpe->mpe_function;
568			break;
569		case MAC_DESTROY_MOUNT_FS_LABEL:
570			mpc->mpc_ops->mpo_destroy_mount_fs_label =
571			    mpe->mpe_function;
572			break;
573		case MAC_DESTROY_PIPE_LABEL:
574			mpc->mpc_ops->mpo_destroy_pipe_label =
575			    mpe->mpe_function;
576			break;
577		case MAC_DESTROY_SOCKET_LABEL:
578			mpc->mpc_ops->mpo_destroy_socket_label =
579			    mpe->mpe_function;
580			break;
581		case MAC_DESTROY_SOCKET_PEER_LABEL:
582			mpc->mpc_ops->mpo_destroy_socket_peer_label =
583			    mpe->mpe_function;
584			break;
585		case MAC_DESTROY_VNODE_LABEL:
586			mpc->mpc_ops->mpo_destroy_vnode_label =
587			    mpe->mpe_function;
588			break;
589		case MAC_COPY_PIPE_LABEL:
590			mpc->mpc_ops->mpo_copy_pipe_label =
591			    mpe->mpe_function;
592			break;
593		case MAC_COPY_VNODE_LABEL:
594			mpc->mpc_ops->mpo_copy_vnode_label =
595			    mpe->mpe_function;
596			break;
597		case MAC_EXTERNALIZE_CRED_LABEL:
598			mpc->mpc_ops->mpo_externalize_cred_label =
599			    mpe->mpe_function;
600			break;
601		case MAC_EXTERNALIZE_IFNET_LABEL:
602			mpc->mpc_ops->mpo_externalize_ifnet_label =
603			    mpe->mpe_function;
604			break;
605		case MAC_EXTERNALIZE_PIPE_LABEL:
606			mpc->mpc_ops->mpo_externalize_pipe_label =
607			    mpe->mpe_function;
608			break;
609		case MAC_EXTERNALIZE_SOCKET_LABEL:
610			mpc->mpc_ops->mpo_externalize_socket_label =
611			    mpe->mpe_function;
612			break;
613		case MAC_EXTERNALIZE_SOCKET_PEER_LABEL:
614			mpc->mpc_ops->mpo_externalize_socket_peer_label =
615			    mpe->mpe_function;
616			break;
617		case MAC_EXTERNALIZE_VNODE_LABEL:
618			mpc->mpc_ops->mpo_externalize_vnode_label =
619			    mpe->mpe_function;
620			break;
621		case MAC_EXTERNALIZE_VNODE_OLDMAC:
622			mpc->mpc_ops->mpo_externalize_vnode_oldmac =
623			    mpe->mpe_function;
624			break;
625		case MAC_INTERNALIZE_CRED_LABEL:
626			mpc->mpc_ops->mpo_internalize_cred_label =
627			    mpe->mpe_function;
628			break;
629		case MAC_INTERNALIZE_IFNET_LABEL:
630			mpc->mpc_ops->mpo_internalize_ifnet_label =
631			    mpe->mpe_function;
632			break;
633		case MAC_INTERNALIZE_PIPE_LABEL:
634			mpc->mpc_ops->mpo_internalize_pipe_label =
635			    mpe->mpe_function;
636			break;
637		case MAC_INTERNALIZE_SOCKET_LABEL:
638			mpc->mpc_ops->mpo_internalize_socket_label =
639			    mpe->mpe_function;
640			break;
641		case MAC_INTERNALIZE_VNODE_LABEL:
642			mpc->mpc_ops->mpo_internalize_vnode_label =
643			    mpe->mpe_function;
644			break;
645		case MAC_CREATE_DEVFS_DEVICE:
646			mpc->mpc_ops->mpo_create_devfs_device =
647			    mpe->mpe_function;
648			break;
649		case MAC_CREATE_DEVFS_DIRECTORY:
650			mpc->mpc_ops->mpo_create_devfs_directory =
651			    mpe->mpe_function;
652			break;
653		case MAC_CREATE_DEVFS_SYMLINK:
654			mpc->mpc_ops->mpo_create_devfs_symlink =
655			    mpe->mpe_function;
656			break;
657		case MAC_CREATE_DEVFS_VNODE:
658			mpc->mpc_ops->mpo_create_devfs_vnode =
659			    mpe->mpe_function;
660			break;
661		case MAC_STDCREATEVNODE_EA:
662			mpc->mpc_ops->mpo_stdcreatevnode_ea =
663			    mpe->mpe_function;
664			break;
665		case MAC_CREATE_VNODE:
666			mpc->mpc_ops->mpo_create_vnode =
667			    mpe->mpe_function;
668			break;
669		case MAC_CREATE_MOUNT:
670			mpc->mpc_ops->mpo_create_mount =
671			    mpe->mpe_function;
672			break;
673		case MAC_CREATE_ROOT_MOUNT:
674			mpc->mpc_ops->mpo_create_root_mount =
675			    mpe->mpe_function;
676			break;
677		case MAC_RELABEL_VNODE:
678			mpc->mpc_ops->mpo_relabel_vnode =
679			    mpe->mpe_function;
680			break;
681		case MAC_UPDATE_DEVFSDIRENT:
682			mpc->mpc_ops->mpo_update_devfsdirent =
683			    mpe->mpe_function;
684			break;
685		case MAC_UPDATE_PROCFSVNODE:
686			mpc->mpc_ops->mpo_update_procfsvnode =
687			    mpe->mpe_function;
688			break;
689		case MAC_UPDATE_VNODE_FROM_EXTATTR:
690			mpc->mpc_ops->mpo_update_vnode_from_extattr =
691			    mpe->mpe_function;
692			break;
693		case MAC_UPDATE_VNODE_FROM_EXTERNALIZED:
694			mpc->mpc_ops->mpo_update_vnode_from_externalized =
695			    mpe->mpe_function;
696			break;
697		case MAC_UPDATE_VNODE_FROM_MOUNT:
698			mpc->mpc_ops->mpo_update_vnode_from_mount =
699			    mpe->mpe_function;
700			break;
701		case MAC_CREATE_MBUF_FROM_SOCKET:
702			mpc->mpc_ops->mpo_create_mbuf_from_socket =
703			    mpe->mpe_function;
704			break;
705		case MAC_CREATE_PIPE:
706			mpc->mpc_ops->mpo_create_pipe =
707			    mpe->mpe_function;
708			break;
709		case MAC_CREATE_SOCKET:
710			mpc->mpc_ops->mpo_create_socket =
711			    mpe->mpe_function;
712			break;
713		case MAC_CREATE_SOCKET_FROM_SOCKET:
714			mpc->mpc_ops->mpo_create_socket_from_socket =
715			    mpe->mpe_function;
716			break;
717		case MAC_RELABEL_PIPE:
718			mpc->mpc_ops->mpo_relabel_pipe =
719			    mpe->mpe_function;
720			break;
721		case MAC_RELABEL_SOCKET:
722			mpc->mpc_ops->mpo_relabel_socket =
723			    mpe->mpe_function;
724			break;
725		case MAC_SET_SOCKET_PEER_FROM_MBUF:
726			mpc->mpc_ops->mpo_set_socket_peer_from_mbuf =
727			    mpe->mpe_function;
728			break;
729		case MAC_SET_SOCKET_PEER_FROM_SOCKET:
730			mpc->mpc_ops->mpo_set_socket_peer_from_socket =
731			    mpe->mpe_function;
732			break;
733		case MAC_CREATE_BPFDESC:
734			mpc->mpc_ops->mpo_create_bpfdesc =
735			    mpe->mpe_function;
736			break;
737		case MAC_CREATE_DATAGRAM_FROM_IPQ:
738			mpc->mpc_ops->mpo_create_datagram_from_ipq =
739			    mpe->mpe_function;
740			break;
741		case MAC_CREATE_FRAGMENT:
742			mpc->mpc_ops->mpo_create_fragment =
743			    mpe->mpe_function;
744			break;
745		case MAC_CREATE_IFNET:
746			mpc->mpc_ops->mpo_create_ifnet =
747			    mpe->mpe_function;
748			break;
749		case MAC_CREATE_IPQ:
750			mpc->mpc_ops->mpo_create_ipq =
751			    mpe->mpe_function;
752			break;
753		case MAC_CREATE_MBUF_FROM_MBUF:
754			mpc->mpc_ops->mpo_create_mbuf_from_mbuf =
755			    mpe->mpe_function;
756			break;
757		case MAC_CREATE_MBUF_LINKLAYER:
758			mpc->mpc_ops->mpo_create_mbuf_linklayer =
759			    mpe->mpe_function;
760			break;
761		case MAC_CREATE_MBUF_FROM_BPFDESC:
762			mpc->mpc_ops->mpo_create_mbuf_from_bpfdesc =
763			    mpe->mpe_function;
764			break;
765		case MAC_CREATE_MBUF_FROM_IFNET:
766			mpc->mpc_ops->mpo_create_mbuf_from_ifnet =
767			    mpe->mpe_function;
768			break;
769		case MAC_CREATE_MBUF_MULTICAST_ENCAP:
770			mpc->mpc_ops->mpo_create_mbuf_multicast_encap =
771			    mpe->mpe_function;
772			break;
773		case MAC_CREATE_MBUF_NETLAYER:
774			mpc->mpc_ops->mpo_create_mbuf_netlayer =
775			    mpe->mpe_function;
776			break;
777		case MAC_FRAGMENT_MATCH:
778			mpc->mpc_ops->mpo_fragment_match =
779			    mpe->mpe_function;
780			break;
781		case MAC_RELABEL_IFNET:
782			mpc->mpc_ops->mpo_relabel_ifnet =
783			    mpe->mpe_function;
784			break;
785		case MAC_UPDATE_IPQ:
786			mpc->mpc_ops->mpo_update_ipq =
787			    mpe->mpe_function;
788			break;
789		case MAC_CREATE_CRED:
790			mpc->mpc_ops->mpo_create_cred =
791			    mpe->mpe_function;
792			break;
793		case MAC_EXECVE_TRANSITION:
794			mpc->mpc_ops->mpo_execve_transition =
795			    mpe->mpe_function;
796			break;
797		case MAC_EXECVE_WILL_TRANSITION:
798			mpc->mpc_ops->mpo_execve_will_transition =
799			    mpe->mpe_function;
800			break;
801		case MAC_CREATE_PROC0:
802			mpc->mpc_ops->mpo_create_proc0 =
803			    mpe->mpe_function;
804			break;
805		case MAC_CREATE_PROC1:
806			mpc->mpc_ops->mpo_create_proc1 =
807			    mpe->mpe_function;
808			break;
809		case MAC_RELABEL_CRED:
810			mpc->mpc_ops->mpo_relabel_cred =
811			    mpe->mpe_function;
812			break;
813		case MAC_THREAD_USERRET:
814			mpc->mpc_ops->mpo_thread_userret =
815			    mpe->mpe_function;
816			break;
817		case MAC_CHECK_BPFDESC_RECEIVE:
818			mpc->mpc_ops->mpo_check_bpfdesc_receive =
819			    mpe->mpe_function;
820			break;
821		case MAC_CHECK_CRED_RELABEL:
822			mpc->mpc_ops->mpo_check_cred_relabel =
823			    mpe->mpe_function;
824			break;
825		case MAC_CHECK_CRED_VISIBLE:
826			mpc->mpc_ops->mpo_check_cred_visible =
827			    mpe->mpe_function;
828			break;
829		case MAC_CHECK_IFNET_RELABEL:
830			mpc->mpc_ops->mpo_check_ifnet_relabel =
831			    mpe->mpe_function;
832			break;
833		case MAC_CHECK_IFNET_TRANSMIT:
834			mpc->mpc_ops->mpo_check_ifnet_transmit =
835			    mpe->mpe_function;
836			break;
837		case MAC_CHECK_MOUNT_STAT:
838			mpc->mpc_ops->mpo_check_mount_stat =
839			    mpe->mpe_function;
840			break;
841		case MAC_CHECK_PIPE_IOCTL:
842			mpc->mpc_ops->mpo_check_pipe_ioctl =
843			    mpe->mpe_function;
844			break;
845		case MAC_CHECK_PIPE_POLL:
846			mpc->mpc_ops->mpo_check_pipe_poll =
847			    mpe->mpe_function;
848			break;
849		case MAC_CHECK_PIPE_READ:
850			mpc->mpc_ops->mpo_check_pipe_read =
851			    mpe->mpe_function;
852			break;
853		case MAC_CHECK_PIPE_RELABEL:
854			mpc->mpc_ops->mpo_check_pipe_relabel =
855			    mpe->mpe_function;
856			break;
857		case MAC_CHECK_PIPE_STAT:
858			mpc->mpc_ops->mpo_check_pipe_stat =
859			    mpe->mpe_function;
860			break;
861		case MAC_CHECK_PIPE_WRITE:
862			mpc->mpc_ops->mpo_check_pipe_write =
863			    mpe->mpe_function;
864			break;
865		case MAC_CHECK_PROC_DEBUG:
866			mpc->mpc_ops->mpo_check_proc_debug =
867			    mpe->mpe_function;
868			break;
869		case MAC_CHECK_PROC_SCHED:
870			mpc->mpc_ops->mpo_check_proc_sched =
871			    mpe->mpe_function;
872			break;
873		case MAC_CHECK_PROC_SIGNAL:
874			mpc->mpc_ops->mpo_check_proc_signal =
875			    mpe->mpe_function;
876			break;
877		case MAC_CHECK_SOCKET_BIND:
878			mpc->mpc_ops->mpo_check_socket_bind =
879			    mpe->mpe_function;
880			break;
881		case MAC_CHECK_SOCKET_CONNECT:
882			mpc->mpc_ops->mpo_check_socket_connect =
883			    mpe->mpe_function;
884			break;
885		case MAC_CHECK_SOCKET_DELIVER:
886			mpc->mpc_ops->mpo_check_socket_deliver =
887			    mpe->mpe_function;
888			break;
889		case MAC_CHECK_SOCKET_LISTEN:
890			mpc->mpc_ops->mpo_check_socket_listen =
891			    mpe->mpe_function;
892			break;
893		case MAC_CHECK_SOCKET_RECEIVE:
894			mpc->mpc_ops->mpo_check_socket_receive =
895			    mpe->mpe_function;
896			break;
897		case MAC_CHECK_SOCKET_RELABEL:
898			mpc->mpc_ops->mpo_check_socket_relabel =
899			    mpe->mpe_function;
900			break;
901		case MAC_CHECK_SOCKET_SEND:
902			mpc->mpc_ops->mpo_check_socket_send =
903			    mpe->mpe_function;
904			break;
905		case MAC_CHECK_SOCKET_VISIBLE:
906			mpc->mpc_ops->mpo_check_socket_visible =
907			    mpe->mpe_function;
908			break;
909		case MAC_CHECK_VNODE_ACCESS:
910			mpc->mpc_ops->mpo_check_vnode_access =
911			    mpe->mpe_function;
912			break;
913		case MAC_CHECK_VNODE_CHDIR:
914			mpc->mpc_ops->mpo_check_vnode_chdir =
915			    mpe->mpe_function;
916			break;
917		case MAC_CHECK_VNODE_CHROOT:
918			mpc->mpc_ops->mpo_check_vnode_chroot =
919			    mpe->mpe_function;
920			break;
921		case MAC_CHECK_VNODE_CREATE:
922			mpc->mpc_ops->mpo_check_vnode_create =
923			    mpe->mpe_function;
924			break;
925		case MAC_CHECK_VNODE_DELETE:
926			mpc->mpc_ops->mpo_check_vnode_delete =
927			    mpe->mpe_function;
928			break;
929		case MAC_CHECK_VNODE_DELETEACL:
930			mpc->mpc_ops->mpo_check_vnode_deleteacl =
931			    mpe->mpe_function;
932			break;
933		case MAC_CHECK_VNODE_EXEC:
934			mpc->mpc_ops->mpo_check_vnode_exec =
935			    mpe->mpe_function;
936			break;
937		case MAC_CHECK_VNODE_GETACL:
938			mpc->mpc_ops->mpo_check_vnode_getacl =
939			    mpe->mpe_function;
940			break;
941		case MAC_CHECK_VNODE_GETEXTATTR:
942			mpc->mpc_ops->mpo_check_vnode_getextattr =
943			    mpe->mpe_function;
944			break;
945		case MAC_CHECK_VNODE_LINK:
946			mpc->mpc_ops->mpo_check_vnode_link =
947			    mpe->mpe_function;
948			break;
949		case MAC_CHECK_VNODE_LOOKUP:
950			mpc->mpc_ops->mpo_check_vnode_lookup =
951			    mpe->mpe_function;
952			break;
953		case MAC_CHECK_VNODE_MMAP:
954			mpc->mpc_ops->mpo_check_vnode_mmap =
955			    mpe->mpe_function;
956			break;
957		case MAC_CHECK_VNODE_MMAP_DOWNGRADE:
958			mpc->mpc_ops->mpo_check_vnode_mmap_downgrade =
959			    mpe->mpe_function;
960			break;
961		case MAC_CHECK_VNODE_MPROTECT:
962			mpc->mpc_ops->mpo_check_vnode_mprotect =
963			    mpe->mpe_function;
964			break;
965		case MAC_CHECK_VNODE_OPEN:
966			mpc->mpc_ops->mpo_check_vnode_open =
967			    mpe->mpe_function;
968			break;
969		case MAC_CHECK_VNODE_POLL:
970			mpc->mpc_ops->mpo_check_vnode_poll =
971			    mpe->mpe_function;
972			break;
973		case MAC_CHECK_VNODE_READ:
974			mpc->mpc_ops->mpo_check_vnode_read =
975			    mpe->mpe_function;
976			break;
977		case MAC_CHECK_VNODE_READDIR:
978			mpc->mpc_ops->mpo_check_vnode_readdir =
979			    mpe->mpe_function;
980			break;
981		case MAC_CHECK_VNODE_READLINK:
982			mpc->mpc_ops->mpo_check_vnode_readlink =
983			    mpe->mpe_function;
984			break;
985		case MAC_CHECK_VNODE_RELABEL:
986			mpc->mpc_ops->mpo_check_vnode_relabel =
987			    mpe->mpe_function;
988			break;
989		case MAC_CHECK_VNODE_RENAME_FROM:
990			mpc->mpc_ops->mpo_check_vnode_rename_from =
991			    mpe->mpe_function;
992			break;
993		case MAC_CHECK_VNODE_RENAME_TO:
994			mpc->mpc_ops->mpo_check_vnode_rename_to =
995			    mpe->mpe_function;
996			break;
997		case MAC_CHECK_VNODE_REVOKE:
998			mpc->mpc_ops->mpo_check_vnode_revoke =
999			    mpe->mpe_function;
1000			break;
1001		case MAC_CHECK_VNODE_SETACL:
1002			mpc->mpc_ops->mpo_check_vnode_setacl =
1003			    mpe->mpe_function;
1004			break;
1005		case MAC_CHECK_VNODE_SETEXTATTR:
1006			mpc->mpc_ops->mpo_check_vnode_setextattr =
1007			    mpe->mpe_function;
1008			break;
1009		case MAC_CHECK_VNODE_SETFLAGS:
1010			mpc->mpc_ops->mpo_check_vnode_setflags =
1011			    mpe->mpe_function;
1012			break;
1013		case MAC_CHECK_VNODE_SETMODE:
1014			mpc->mpc_ops->mpo_check_vnode_setmode =
1015			    mpe->mpe_function;
1016			break;
1017		case MAC_CHECK_VNODE_SETOWNER:
1018			mpc->mpc_ops->mpo_check_vnode_setowner =
1019			    mpe->mpe_function;
1020			break;
1021		case MAC_CHECK_VNODE_SETUTIMES:
1022			mpc->mpc_ops->mpo_check_vnode_setutimes =
1023			    mpe->mpe_function;
1024			break;
1025		case MAC_CHECK_VNODE_STAT:
1026			mpc->mpc_ops->mpo_check_vnode_stat =
1027			    mpe->mpe_function;
1028			break;
1029		case MAC_CHECK_VNODE_WRITE:
1030			mpc->mpc_ops->mpo_check_vnode_write =
1031			    mpe->mpe_function;
1032			break;
1033/*
1034		default:
1035			printf("MAC policy `%s': unknown operation %d\n",
1036			    mpc->mpc_name, mpe->mpe_constant);
1037			return (EINVAL);
1038*/
1039		}
1040	}
1041	MAC_POLICY_LIST_LOCK();
1042	if (mac_policy_list_busy > 0) {
1043		MAC_POLICY_LIST_UNLOCK();
1044		FREE(mpc->mpc_ops, M_MACOPVEC);
1045		mpc->mpc_ops = NULL;
1046		return (EBUSY);
1047	}
1048	LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) {
1049		if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) {
1050			MAC_POLICY_LIST_UNLOCK();
1051			FREE(mpc->mpc_ops, M_MACOPVEC);
1052			mpc->mpc_ops = NULL;
1053			return (EEXIST);
1054		}
1055	}
1056	if (mpc->mpc_field_off != NULL) {
1057		slot = ffs(mac_policy_offsets_free);
1058		if (slot == 0) {
1059			MAC_POLICY_LIST_UNLOCK();
1060			FREE(mpc->mpc_ops, M_MACOPVEC);
1061			mpc->mpc_ops = NULL;
1062			return (ENOMEM);
1063		}
1064		slot--;
1065		mac_policy_offsets_free &= ~(1 << slot);
1066		*mpc->mpc_field_off = slot;
1067	}
1068	mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED;
1069	LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list);
1070
1071	/* Per-policy initialization. */
1072	if (mpc->mpc_ops->mpo_init != NULL)
1073		(*(mpc->mpc_ops->mpo_init))(mpc);
1074	MAC_POLICY_LIST_UNLOCK();
1075
1076	printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname,
1077	    mpc->mpc_name);
1078
1079	return (0);
1080}
1081
1082static int
1083mac_policy_unregister(struct mac_policy_conf *mpc)
1084{
1085
1086	/*
1087	 * If we fail the load, we may get a request to unload.  Check
1088	 * to see if we did the run-time registration, and if not,
1089	 * silently succeed.
1090	 */
1091	MAC_POLICY_LIST_LOCK();
1092	if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) {
1093		MAC_POLICY_LIST_UNLOCK();
1094		return (0);
1095	}
1096#if 0
1097	/*
1098	 * Don't allow unloading modules with private data.
1099	 */
1100	if (mpc->mpc_field_off != NULL) {
1101		MAC_POLICY_LIST_UNLOCK();
1102		return (EBUSY);
1103	}
1104#endif
1105	/*
1106	 * Only allow the unload to proceed if the module is unloadable
1107	 * by its own definition.
1108	 */
1109	if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) {
1110		MAC_POLICY_LIST_UNLOCK();
1111		return (EBUSY);
1112	}
1113	/*
1114	 * Right now, we EBUSY if the list is in use.  In the future,
1115	 * for reliability reasons, we might want to sleep and wakeup
1116	 * later to try again.
1117	 */
1118	if (mac_policy_list_busy > 0) {
1119		MAC_POLICY_LIST_UNLOCK();
1120		return (EBUSY);
1121	}
1122	if (mpc->mpc_ops->mpo_destroy != NULL)
1123		(*(mpc->mpc_ops->mpo_destroy))(mpc);
1124
1125	LIST_REMOVE(mpc, mpc_list);
1126	MAC_POLICY_LIST_UNLOCK();
1127
1128	FREE(mpc->mpc_ops, M_MACOPVEC);
1129	mpc->mpc_ops = NULL;
1130	mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED;
1131
1132	printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname,
1133	    mpc->mpc_name);
1134
1135	return (0);
1136}
1137
1138/*
1139 * Define an error value precedence, and given two arguments, selects the
1140 * value with the higher precedence.
1141 */
1142static int
1143error_select(int error1, int error2)
1144{
1145
1146	/* Certain decision-making errors take top priority. */
1147	if (error1 == EDEADLK || error2 == EDEADLK)
1148		return (EDEADLK);
1149
1150	/* Invalid arguments should be reported where possible. */
1151	if (error1 == EINVAL || error2 == EINVAL)
1152		return (EINVAL);
1153
1154	/* Precedence goes to "visibility", with both process and file. */
1155	if (error1 == ESRCH || error2 == ESRCH)
1156		return (ESRCH);
1157
1158	if (error1 == ENOENT || error2 == ENOENT)
1159		return (ENOENT);
1160
1161	/* Precedence goes to DAC/MAC protections. */
1162	if (error1 == EACCES || error2 == EACCES)
1163		return (EACCES);
1164
1165	/* Precedence goes to privilege. */
1166	if (error1 == EPERM || error2 == EPERM)
1167		return (EPERM);
1168
1169	/* Precedence goes to error over success; otherwise, arbitrary. */
1170	if (error1 != 0)
1171		return (error1);
1172	return (error2);
1173}
1174
1175static void
1176mac_init_label(struct label *label)
1177{
1178
1179	bzero(label, sizeof(*label));
1180	label->l_flags = MAC_FLAG_INITIALIZED;
1181}
1182
1183static void
1184mac_destroy_label(struct label *label)
1185{
1186
1187	KASSERT(label->l_flags & MAC_FLAG_INITIALIZED,
1188	    ("destroying uninitialized label"));
1189
1190	bzero(label, sizeof(*label));
1191	/* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */
1192}
1193
1194void
1195mac_init_bpfdesc(struct bpf_d *bpf_d)
1196{
1197
1198	mac_init_label(&bpf_d->bd_label);
1199	MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label);
1200#ifdef MAC_DEBUG
1201	atomic_add_int(&nmacbpfdescs, 1);
1202#endif
1203}
1204
1205static void
1206mac_init_cred_label(struct label *label)
1207{
1208
1209	mac_init_label(label);
1210	MAC_PERFORM(init_cred_label, label);
1211#ifdef MAC_DEBUG
1212	atomic_add_int(&nmaccreds, 1);
1213#endif
1214}
1215
1216void
1217mac_init_cred(struct ucred *cred)
1218{
1219
1220	mac_init_cred_label(&cred->cr_label);
1221}
1222
1223void
1224mac_init_devfsdirent(struct devfs_dirent *de)
1225{
1226
1227	mac_init_label(&de->de_label);
1228	MAC_PERFORM(init_devfsdirent_label, &de->de_label);
1229#ifdef MAC_DEBUG
1230	atomic_add_int(&nmacdevfsdirents, 1);
1231#endif
1232}
1233
1234static void
1235mac_init_ifnet_label(struct label *label)
1236{
1237
1238	mac_init_label(label);
1239	MAC_PERFORM(init_ifnet_label, label);
1240#ifdef MAC_DEBUG
1241	atomic_add_int(&nmacifnets, 1);
1242#endif
1243}
1244
1245void
1246mac_init_ifnet(struct ifnet *ifp)
1247{
1248
1249	mac_init_ifnet_label(&ifp->if_label);
1250}
1251
1252void
1253mac_init_ipq(struct ipq *ipq)
1254{
1255
1256	mac_init_label(&ipq->ipq_label);
1257	MAC_PERFORM(init_ipq_label, &ipq->ipq_label);
1258#ifdef MAC_DEBUG
1259	atomic_add_int(&nmacipqs, 1);
1260#endif
1261}
1262
1263int
1264mac_init_mbuf(struct mbuf *m, int flag)
1265{
1266	int error;
1267
1268	KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf"));
1269
1270	mac_init_label(&m->m_pkthdr.label);
1271
1272	MAC_CHECK(init_mbuf_label, &m->m_pkthdr.label, flag);
1273	if (error) {
1274		MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label);
1275		mac_destroy_label(&m->m_pkthdr.label);
1276	}
1277
1278#ifdef MAC_DEBUG
1279	if (error == 0)
1280		atomic_add_int(&nmacmbufs, 1);
1281#endif
1282	return (error);
1283}
1284
1285void
1286mac_init_mount(struct mount *mp)
1287{
1288
1289	mac_init_label(&mp->mnt_mntlabel);
1290	mac_init_label(&mp->mnt_fslabel);
1291	MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel);
1292	MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel);
1293#ifdef MAC_DEBUG
1294	atomic_add_int(&nmacmounts, 1);
1295#endif
1296}
1297
1298static void
1299mac_init_pipe_label(struct label *label)
1300{
1301
1302	mac_init_label(label);
1303	MAC_PERFORM(init_pipe_label, label);
1304#ifdef MAC_DEBUG
1305	atomic_add_int(&nmacpipes, 1);
1306#endif
1307}
1308
1309void
1310mac_init_pipe(struct pipe *pipe)
1311{
1312	struct label *label;
1313
1314	label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK);
1315	pipe->pipe_label = label;
1316	pipe->pipe_peer->pipe_label = label;
1317	mac_init_pipe_label(label);
1318}
1319
1320static int
1321mac_init_socket_label(struct label *label, int flag)
1322{
1323	int error;
1324
1325	mac_init_label(label);
1326
1327	MAC_CHECK(init_socket_label, label, flag);
1328	if (error) {
1329		MAC_PERFORM(destroy_socket_label, label);
1330		mac_destroy_label(label);
1331	}
1332
1333#ifdef MAC_DEBUG
1334	if (error == 0)
1335		atomic_add_int(&nmacsockets, 1);
1336#endif
1337
1338	return (error);
1339}
1340
1341static int
1342mac_init_socket_peer_label(struct label *label, int flag)
1343{
1344	int error;
1345
1346	mac_init_label(label);
1347
1348	MAC_CHECK(init_socket_peer_label, label, flag);
1349	if (error) {
1350		MAC_PERFORM(destroy_socket_label, label);
1351		mac_destroy_label(label);
1352	}
1353
1354	return (error);
1355}
1356
1357int
1358mac_init_socket(struct socket *socket, int flag)
1359{
1360	int error;
1361
1362	error = mac_init_socket_label(&socket->so_label, flag);
1363	if (error)
1364		return (error);
1365
1366	error = mac_init_socket_peer_label(&socket->so_peerlabel, flag);
1367	if (error)
1368		mac_destroy_socket_label(&socket->so_label);
1369
1370	return (error);
1371}
1372
1373static void
1374mac_init_vnode_label(struct label *label)
1375{
1376
1377	mac_init_label(label);
1378	MAC_PERFORM(init_vnode_label, label);
1379#ifdef MAC_DEBUG
1380	atomic_add_int(&nmacvnodes, 1);
1381#endif
1382}
1383
1384void
1385mac_init_vnode(struct vnode *vp)
1386{
1387
1388	mac_init_vnode_label(&vp->v_label);
1389}
1390
1391void
1392mac_destroy_bpfdesc(struct bpf_d *bpf_d)
1393{
1394
1395	MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label);
1396	mac_destroy_label(&bpf_d->bd_label);
1397#ifdef MAC_DEBUG
1398	atomic_subtract_int(&nmacbpfdescs, 1);
1399#endif
1400}
1401
1402static void
1403mac_destroy_cred_label(struct label *label)
1404{
1405
1406	MAC_PERFORM(destroy_cred_label, label);
1407	mac_destroy_label(label);
1408#ifdef MAC_DEBUG
1409	atomic_subtract_int(&nmaccreds, 1);
1410#endif
1411}
1412
1413void
1414mac_destroy_cred(struct ucred *cred)
1415{
1416
1417	mac_destroy_cred_label(&cred->cr_label);
1418}
1419
1420void
1421mac_destroy_devfsdirent(struct devfs_dirent *de)
1422{
1423
1424	MAC_PERFORM(destroy_devfsdirent_label, &de->de_label);
1425	mac_destroy_label(&de->de_label);
1426#ifdef MAC_DEBUG
1427	atomic_subtract_int(&nmacdevfsdirents, 1);
1428#endif
1429}
1430
1431static void
1432mac_destroy_ifnet_label(struct label *label)
1433{
1434
1435	MAC_PERFORM(destroy_ifnet_label, label);
1436	mac_destroy_label(label);
1437#ifdef MAC_DEBUG
1438	atomic_subtract_int(&nmacifnets, 1);
1439#endif
1440}
1441
1442void
1443mac_destroy_ifnet(struct ifnet *ifp)
1444{
1445
1446	mac_destroy_ifnet_label(&ifp->if_label);
1447}
1448
1449void
1450mac_destroy_ipq(struct ipq *ipq)
1451{
1452
1453	MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label);
1454	mac_destroy_label(&ipq->ipq_label);
1455#ifdef MAC_DEBUG
1456	atomic_subtract_int(&nmacipqs, 1);
1457#endif
1458}
1459
1460void
1461mac_destroy_mbuf(struct mbuf *m)
1462{
1463
1464	MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label);
1465	mac_destroy_label(&m->m_pkthdr.label);
1466#ifdef MAC_DEBUG
1467	atomic_subtract_int(&nmacmbufs, 1);
1468#endif
1469}
1470
1471void
1472mac_destroy_mount(struct mount *mp)
1473{
1474
1475	MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel);
1476	MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel);
1477	mac_destroy_label(&mp->mnt_fslabel);
1478	mac_destroy_label(&mp->mnt_mntlabel);
1479#ifdef MAC_DEBUG
1480	atomic_subtract_int(&nmacmounts, 1);
1481#endif
1482}
1483
1484static void
1485mac_destroy_pipe_label(struct label *label)
1486{
1487
1488	MAC_PERFORM(destroy_pipe_label, label);
1489	mac_destroy_label(label);
1490#ifdef MAC_DEBUG
1491	atomic_subtract_int(&nmacpipes, 1);
1492#endif
1493}
1494
1495void
1496mac_destroy_pipe(struct pipe *pipe)
1497{
1498
1499	mac_destroy_pipe_label(pipe->pipe_label);
1500	free(pipe->pipe_label, M_MACPIPELABEL);
1501}
1502
1503static void
1504mac_destroy_socket_label(struct label *label)
1505{
1506
1507	MAC_PERFORM(destroy_socket_label, label);
1508	mac_destroy_label(label);
1509#ifdef MAC_DEBUG
1510	atomic_subtract_int(&nmacsockets, 1);
1511#endif
1512}
1513
1514static void
1515mac_destroy_socket_peer_label(struct label *label)
1516{
1517
1518	MAC_PERFORM(destroy_socket_peer_label, label);
1519	mac_destroy_label(label);
1520}
1521
1522void
1523mac_destroy_socket(struct socket *socket)
1524{
1525
1526	mac_destroy_socket_label(&socket->so_label);
1527	mac_destroy_socket_peer_label(&socket->so_peerlabel);
1528}
1529
1530static void
1531mac_destroy_vnode_label(struct label *label)
1532{
1533
1534	MAC_PERFORM(destroy_vnode_label, label);
1535	mac_destroy_label(label);
1536#ifdef MAC_DEBUG
1537	atomic_subtract_int(&nmacvnodes, 1);
1538#endif
1539}
1540
1541void
1542mac_destroy_vnode(struct vnode *vp)
1543{
1544
1545	mac_destroy_vnode_label(&vp->v_label);
1546}
1547
1548static void
1549mac_copy_pipe_label(struct label *src, struct label *dest)
1550{
1551
1552	MAC_PERFORM(copy_pipe_label, src, dest);
1553}
1554
1555static void
1556mac_copy_vnode_label(struct label *src, struct label *dest)
1557{
1558
1559	MAC_PERFORM(copy_vnode_label, src, dest);
1560}
1561
1562static int
1563mac_check_structmac_consistent(struct mac *mac)
1564{
1565
1566	if (mac->m_buflen > MAC_MAX_LABEL_BUF_LEN)
1567		return (EINVAL);
1568
1569	return (0);
1570}
1571
1572static int
1573mac_externalize_cred_label(struct label *label, char *elements,
1574    char *outbuf, size_t outbuflen, int flags)
1575{
1576	int error;
1577
1578	MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen);
1579
1580	return (error);
1581}
1582
1583static int
1584mac_externalize_ifnet_label(struct label *label, char *elements,
1585    char *outbuf, size_t outbuflen, int flags)
1586{
1587	int error;
1588
1589	MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen);
1590
1591	return (error);
1592}
1593
1594static int
1595mac_externalize_pipe_label(struct label *label, char *elements,
1596    char *outbuf, size_t outbuflen, int flags)
1597{
1598	int error;
1599
1600	MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen);
1601
1602	return (error);
1603}
1604
1605static int
1606mac_externalize_socket_label(struct label *label, char *elements,
1607    char *outbuf, size_t outbuflen, int flags)
1608{
1609	int error;
1610
1611	MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen);
1612
1613	return (error);
1614}
1615
1616static int
1617mac_externalize_socket_peer_label(struct label *label, char *elements,
1618    char *outbuf, size_t outbuflen, int flags)
1619{
1620	int error;
1621
1622	MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen);
1623
1624	return (error);
1625}
1626
1627static int
1628mac_externalize_vnode_label(struct label *label, char *elements,
1629    char *outbuf, size_t outbuflen, int flags)
1630{
1631	int error;
1632
1633	MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen);
1634
1635	return (error);
1636}
1637
1638static int
1639mac_externalize_vnode_oldmac(struct label *label, struct oldmac *extmac)
1640{
1641	int error;
1642
1643	MAC_CHECK(externalize_vnode_oldmac, label, extmac);
1644
1645	return (error);
1646}
1647
1648static int
1649mac_internalize_cred_label(struct label *label, char *string)
1650{
1651	int error;
1652
1653	MAC_INTERNALIZE(cred_label, label, string);
1654
1655	return (error);
1656}
1657
1658static int
1659mac_internalize_ifnet_label(struct label *label, char *string)
1660{
1661	int error;
1662
1663	MAC_INTERNALIZE(ifnet_label, label, string);
1664
1665	return (error);
1666}
1667
1668static int
1669mac_internalize_pipe_label(struct label *label, char *string)
1670{
1671	int error;
1672
1673	MAC_INTERNALIZE(pipe_label, label, string);
1674
1675	return (error);
1676}
1677
1678static int
1679mac_internalize_socket_label(struct label *label, char *string)
1680{
1681	int error;
1682
1683	MAC_INTERNALIZE(socket_label, label, string);
1684
1685	return (error);
1686}
1687
1688static int
1689mac_internalize_vnode_label(struct label *label, char *string)
1690{
1691	int error;
1692
1693	MAC_INTERNALIZE(vnode_label, label, string);
1694
1695	return (error);
1696}
1697
1698/*
1699 * Initialize MAC label for the first kernel process, from which other
1700 * kernel processes and threads are spawned.
1701 */
1702void
1703mac_create_proc0(struct ucred *cred)
1704{
1705
1706	MAC_PERFORM(create_proc0, cred);
1707}
1708
1709/*
1710 * Initialize MAC label for the first userland process, from which other
1711 * userland processes and threads are spawned.
1712 */
1713void
1714mac_create_proc1(struct ucred *cred)
1715{
1716
1717	MAC_PERFORM(create_proc1, cred);
1718}
1719
1720void
1721mac_thread_userret(struct thread *td)
1722{
1723
1724	MAC_PERFORM(thread_userret, td);
1725}
1726
1727/*
1728 * When a new process is created, its label must be initialized.  Generally,
1729 * this involves inheritence from the parent process, modulo possible
1730 * deltas.  This function allows that processing to take place.
1731 */
1732void
1733mac_create_cred(struct ucred *parent_cred, struct ucred *child_cred)
1734{
1735
1736	MAC_PERFORM(create_cred, parent_cred, child_cred);
1737}
1738
1739void
1740mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp)
1741{
1742
1743	MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label);
1744}
1745
1746void
1747mac_update_procfsvnode(struct vnode *vp, struct ucred *cred)
1748{
1749
1750	MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred);
1751}
1752
1753/*
1754 * Support callout for policies that manage their own externalization
1755 * using extended attributes.
1756 */
1757static int
1758mac_update_vnode_from_extattr(struct vnode *vp, struct mount *mp)
1759{
1760	int error;
1761
1762	MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp,
1763	    &mp->mnt_fslabel);
1764
1765	return (error);
1766}
1767
1768/*
1769 * Given an externalized mac label, internalize it and stamp it on a
1770 * vnode.
1771 */
1772static int
1773mac_update_vnode_from_externalized(struct vnode *vp, struct oldmac *extmac)
1774{
1775	int error;
1776
1777	MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac);
1778
1779	return (error);
1780}
1781
1782/*
1783 * Call out to individual policies to update the label in a vnode from
1784 * the mountpoint.
1785 */
1786void
1787mac_update_vnode_from_mount(struct vnode *vp, struct mount *mp)
1788{
1789
1790	MAC_PERFORM(update_vnode_from_mount, vp, &vp->v_label, mp,
1791	    &mp->mnt_fslabel);
1792
1793	ASSERT_VOP_LOCKED(vp, "mac_update_vnode_from_mount");
1794	if (mac_cache_fslabel_in_vnode)
1795		vp->v_vflag |= VV_CACHEDLABEL;
1796}
1797
1798/*
1799 * Implementation of VOP_REFRESHLABEL() that relies on extended attributes
1800 * to store label data.  Can be referenced by filesystems supporting
1801 * extended attributes.
1802 */
1803int
1804vop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap)
1805{
1806	struct vnode *vp = ap->a_vp;
1807	struct oldmac extmac;
1808	int buflen, error;
1809
1810	ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea");
1811
1812	/*
1813	 * Call out to external policies first.  Order doesn't really
1814	 * matter, as long as failure of one assures failure of all.
1815	 */
1816	error = mac_update_vnode_from_extattr(vp, vp->v_mount);
1817	if (error)
1818		return (error);
1819
1820	buflen = sizeof(extmac);
1821	error = vn_extattr_get(vp, IO_NODELOCKED,
1822	    FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, &buflen,
1823	    (char *)&extmac, curthread);
1824	switch (error) {
1825	case 0:
1826		/* Got it */
1827		break;
1828
1829	case ENOATTR:
1830		/*
1831		 * Use the label from the mount point.
1832		 */
1833		mac_update_vnode_from_mount(vp, vp->v_mount);
1834		return (0);
1835
1836	case EOPNOTSUPP:
1837	default:
1838		/* Fail horribly. */
1839		return (error);
1840	}
1841
1842	if (buflen != sizeof(extmac))
1843		error = EPERM;		/* Fail very closed. */
1844	if (error == 0)
1845		error = mac_update_vnode_from_externalized(vp, &extmac);
1846	if (error == 0)
1847		vp->v_vflag |= VV_CACHEDLABEL;
1848	else {
1849		struct vattr va;
1850
1851		printf("Corrupted label on %s",
1852		    vp->v_mount->mnt_stat.f_mntonname);
1853		if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread) == 0)
1854			printf(" inum %ld", va.va_fileid);
1855#ifdef MAC_DEBUG
1856		if (mac_debug_label_fallback) {
1857			printf(", falling back.\n");
1858			mac_update_vnode_from_mount(vp, vp->v_mount);
1859			error = 0;
1860		} else {
1861#endif
1862			printf(".\n");
1863			error = EPERM;
1864#ifdef MAC_DEBUG
1865		}
1866#endif
1867	}
1868
1869	return (error);
1870}
1871
1872/*
1873 * Make sure the vnode label is up-to-date.  If EOPNOTSUPP, then we handle
1874 * the labeling activity outselves.  Filesystems should be careful not
1875 * to change their minds regarding whether they support vop_refreshlabel()
1876 * for a vnode or not.  Don't cache the vnode here, allow the file
1877 * system code to determine if it's safe to cache.  If we update from
1878 * the mount, don't cache since a change to the mount label should affect
1879 * all vnodes.
1880 */
1881static int
1882vn_refreshlabel(struct vnode *vp, struct ucred *cred)
1883{
1884	int error;
1885
1886	ASSERT_VOP_LOCKED(vp, "vn_refreshlabel");
1887
1888	if (vp->v_mount == NULL) {
1889/*
1890		Eventually, we probably want to special-case refreshing
1891		of deadfs vnodes, and if there's a lock-free race somewhere,
1892		that case might be handled here.
1893
1894		mac_update_vnode_deadfs(vp);
1895		return (0);
1896 */
1897		/* printf("vn_refreshlabel: null v_mount\n"); */
1898		if (vp->v_type != VNON)
1899			printf(
1900			    "vn_refreshlabel: null v_mount with non-VNON\n");
1901		return (EBADF);
1902	}
1903
1904	if (vp->v_vflag & VV_CACHEDLABEL) {
1905		mac_vnode_label_cache_hits++;
1906		return (0);
1907	} else
1908		mac_vnode_label_cache_misses++;
1909
1910	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
1911		mac_update_vnode_from_mount(vp, vp->v_mount);
1912		return (0);
1913	}
1914
1915	error = VOP_REFRESHLABEL(vp, cred, curthread);
1916	switch (error) {
1917	case EOPNOTSUPP:
1918		/*
1919		 * If labels are not supported on this vnode, fall back to
1920		 * the label in the mount and propagate it to the vnode.
1921		 * There should probably be some sort of policy/flag/decision
1922		 * about doing this.
1923		 */
1924		mac_update_vnode_from_mount(vp, vp->v_mount);
1925		error = 0;
1926	default:
1927		return (error);
1928	}
1929}
1930
1931/*
1932 * Helper function for file systems using the vop_std*_ea() calls.  This
1933 * function must be called after EA service is available for the vnode,
1934 * but before it's hooked up to the namespace so that the node persists
1935 * if there's a crash, or before it can be accessed.  On successful
1936 * commit of the label to disk (etc), do cache the label.
1937 */
1938int
1939vop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp, struct ucred *cred)
1940{
1941	struct oldmac extmac;
1942	int error;
1943
1944	ASSERT_VOP_LOCKED(tvp, "vop_stdcreatevnode_ea");
1945	if ((dvp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
1946		mac_update_vnode_from_mount(tvp, tvp->v_mount);
1947	} else {
1948		error = vn_refreshlabel(dvp, cred);
1949		if (error)
1950			return (error);
1951
1952		/*
1953		 * Stick the label in the vnode.  Then try to write to
1954		 * disk.  If we fail, return a failure to abort the
1955		 * create operation.  Really, this failure shouldn't
1956		 * happen except in fairly unusual circumstances (out
1957		 * of disk, etc).
1958		 */
1959		mac_create_vnode(cred, dvp, tvp);
1960
1961		error = mac_stdcreatevnode_ea(tvp);
1962		if (error)
1963			return (error);
1964
1965		/*
1966		 * XXX: Eventually this will go away and all policies will
1967		 * directly manage their extended attributes.
1968		 */
1969		error = mac_externalize_vnode_oldmac(&tvp->v_label, &extmac);
1970		if (error)
1971			return (error);
1972
1973		error = vn_extattr_set(tvp, IO_NODELOCKED,
1974		    FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
1975		    sizeof(extmac), (char *)&extmac, curthread);
1976		if (error == 0)
1977			tvp->v_vflag |= VV_CACHEDLABEL;
1978		else {
1979#if 0
1980			/*
1981			 * In theory, we could have fall-back behavior here.
1982			 * It would probably be incorrect.
1983			 */
1984#endif
1985			return (error);
1986		}
1987	}
1988
1989	return (0);
1990}
1991
1992void
1993mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp)
1994{
1995	int error;
1996
1997	ASSERT_VOP_LOCKED(vp, "mac_execve_transition");
1998
1999	error = vn_refreshlabel(vp, old);
2000	if (error) {
2001		printf("mac_execve_transition: vn_refreshlabel returned %d\n",
2002		    error);
2003		printf("mac_execve_transition: using old vnode label\n");
2004	}
2005
2006	MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label);
2007}
2008
2009int
2010mac_execve_will_transition(struct ucred *old, struct vnode *vp)
2011{
2012	int error, result;
2013
2014	error = vn_refreshlabel(vp, old);
2015	if (error)
2016		return (error);
2017
2018	result = 0;
2019	MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label);
2020
2021	return (result);
2022}
2023
2024int
2025mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags)
2026{
2027	int error;
2028
2029	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access");
2030
2031	if (!mac_enforce_fs)
2032		return (0);
2033
2034	error = vn_refreshlabel(vp, cred);
2035	if (error)
2036		return (error);
2037
2038	MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags);
2039	return (error);
2040}
2041
2042int
2043mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp)
2044{
2045	int error;
2046
2047	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir");
2048
2049	if (!mac_enforce_fs)
2050		return (0);
2051
2052	error = vn_refreshlabel(dvp, cred);
2053	if (error)
2054		return (error);
2055
2056	MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label);
2057	return (error);
2058}
2059
2060int
2061mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp)
2062{
2063	int error;
2064
2065	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot");
2066
2067	if (!mac_enforce_fs)
2068		return (0);
2069
2070	error = vn_refreshlabel(dvp, cred);
2071	if (error)
2072		return (error);
2073
2074	MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label);
2075	return (error);
2076}
2077
2078int
2079mac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2080    struct componentname *cnp, struct vattr *vap)
2081{
2082	int error;
2083
2084	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create");
2085
2086	if (!mac_enforce_fs)
2087		return (0);
2088
2089	error = vn_refreshlabel(dvp, cred);
2090	if (error)
2091		return (error);
2092
2093	MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap);
2094	return (error);
2095}
2096
2097int
2098mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp,
2099    struct componentname *cnp)
2100{
2101	int error;
2102
2103	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete");
2104	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete");
2105
2106	if (!mac_enforce_fs)
2107		return (0);
2108
2109	error = vn_refreshlabel(dvp, cred);
2110	if (error)
2111		return (error);
2112	error = vn_refreshlabel(vp, cred);
2113	if (error)
2114		return (error);
2115
2116	MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp,
2117	    &vp->v_label, cnp);
2118	return (error);
2119}
2120
2121int
2122mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2123    acl_type_t type)
2124{
2125	int error;
2126
2127	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl");
2128
2129	if (!mac_enforce_fs)
2130		return (0);
2131
2132	error = vn_refreshlabel(vp, cred);
2133	if (error)
2134		return (error);
2135
2136	MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type);
2137	return (error);
2138}
2139
2140int
2141mac_check_vnode_exec(struct ucred *cred, struct vnode *vp)
2142{
2143	int error;
2144
2145	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec");
2146
2147	if (!mac_enforce_process && !mac_enforce_fs)
2148		return (0);
2149
2150	error = vn_refreshlabel(vp, cred);
2151	if (error)
2152		return (error);
2153	MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label);
2154
2155	return (error);
2156}
2157
2158int
2159mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
2160{
2161	int error;
2162
2163	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl");
2164
2165	if (!mac_enforce_fs)
2166		return (0);
2167
2168	error = vn_refreshlabel(vp, cred);
2169	if (error)
2170		return (error);
2171
2172	MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type);
2173	return (error);
2174}
2175
2176int
2177mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2178    int attrnamespace, const char *name, struct uio *uio)
2179{
2180	int error;
2181
2182	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr");
2183
2184	if (!mac_enforce_fs)
2185		return (0);
2186
2187	error = vn_refreshlabel(vp, cred);
2188	if (error)
2189		return (error);
2190
2191	MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label,
2192	    attrnamespace, name, uio);
2193	return (error);
2194}
2195
2196int
2197mac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2198    struct vnode *vp, struct componentname *cnp)
2199{
2200	int error;
2201
2202	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link");
2203	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link");
2204
2205	if (!mac_enforce_fs)
2206		return (0);
2207
2208	error = vn_refreshlabel(dvp, cred);
2209	if (error)
2210		return (error);
2211
2212	error = vn_refreshlabel(vp, cred);
2213	if (error)
2214		return (error);
2215
2216	MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp,
2217	    &vp->v_label, cnp);
2218	return (error);
2219}
2220
2221int
2222mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2223    struct componentname *cnp)
2224{
2225	int error;
2226
2227	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup");
2228
2229	if (!mac_enforce_fs)
2230		return (0);
2231
2232	error = vn_refreshlabel(dvp, cred);
2233	if (error)
2234		return (error);
2235
2236	MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp);
2237	return (error);
2238}
2239
2240int
2241mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot)
2242{
2243	int error;
2244
2245	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap");
2246
2247	if (!mac_enforce_fs || !mac_enforce_vm)
2248		return (0);
2249
2250	error = vn_refreshlabel(vp, cred);
2251	if (error)
2252		return (error);
2253
2254	MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot);
2255	return (error);
2256}
2257
2258void
2259mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot)
2260{
2261	int result = *prot;
2262
2263	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade");
2264
2265	if (!mac_enforce_fs || !mac_enforce_vm)
2266		return;
2267
2268	MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label,
2269	    &result);
2270
2271	*prot = result;
2272}
2273
2274int
2275mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot)
2276{
2277	int error;
2278
2279	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect");
2280
2281	if (!mac_enforce_fs || !mac_enforce_vm)
2282		return (0);
2283
2284	error = vn_refreshlabel(vp, cred);
2285	if (error)
2286		return (error);
2287
2288	MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot);
2289	return (error);
2290}
2291
2292int
2293mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode)
2294{
2295	int error;
2296
2297	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open");
2298
2299	if (!mac_enforce_fs)
2300		return (0);
2301
2302	error = vn_refreshlabel(vp, cred);
2303	if (error)
2304		return (error);
2305
2306	MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode);
2307	return (error);
2308}
2309
2310int
2311mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2312    struct vnode *vp)
2313{
2314	int error;
2315
2316	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll");
2317
2318	if (!mac_enforce_fs)
2319		return (0);
2320
2321	error = vn_refreshlabel(vp, active_cred);
2322	if (error)
2323		return (error);
2324
2325	MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp,
2326	    &vp->v_label);
2327
2328	return (error);
2329}
2330
2331int
2332mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2333    struct vnode *vp)
2334{
2335	int error;
2336
2337	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read");
2338
2339	if (!mac_enforce_fs)
2340		return (0);
2341
2342	error = vn_refreshlabel(vp, active_cred);
2343	if (error)
2344		return (error);
2345
2346	MAC_CHECK(check_vnode_read, active_cred, file_cred, vp,
2347	    &vp->v_label);
2348
2349	return (error);
2350}
2351
2352int
2353mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp)
2354{
2355	int error;
2356
2357	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir");
2358
2359	if (!mac_enforce_fs)
2360		return (0);
2361
2362	error = vn_refreshlabel(dvp, cred);
2363	if (error)
2364		return (error);
2365
2366	MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label);
2367	return (error);
2368}
2369
2370int
2371mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp)
2372{
2373	int error;
2374
2375	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink");
2376
2377	if (!mac_enforce_fs)
2378		return (0);
2379
2380	error = vn_refreshlabel(vp, cred);
2381	if (error)
2382		return (error);
2383
2384	MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label);
2385	return (error);
2386}
2387
2388static int
2389mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2390    struct label *newlabel)
2391{
2392	int error;
2393
2394	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel");
2395
2396	error = vn_refreshlabel(vp, cred);
2397	if (error)
2398		return (error);
2399
2400	MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel);
2401
2402	return (error);
2403}
2404
2405int
2406mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2407    struct vnode *vp, struct componentname *cnp)
2408{
2409	int error;
2410
2411	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from");
2412	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from");
2413
2414	if (!mac_enforce_fs)
2415		return (0);
2416
2417	error = vn_refreshlabel(dvp, cred);
2418	if (error)
2419		return (error);
2420	error = vn_refreshlabel(vp, cred);
2421	if (error)
2422		return (error);
2423
2424	MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp,
2425	    &vp->v_label, cnp);
2426	return (error);
2427}
2428
2429int
2430mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2431    struct vnode *vp, int samedir, struct componentname *cnp)
2432{
2433	int error;
2434
2435	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to");
2436	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to");
2437
2438	if (!mac_enforce_fs)
2439		return (0);
2440
2441	error = vn_refreshlabel(dvp, cred);
2442	if (error)
2443		return (error);
2444	if (vp != NULL) {
2445		error = vn_refreshlabel(vp, cred);
2446		if (error)
2447			return (error);
2448	}
2449	MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp,
2450	    vp != NULL ? &vp->v_label : NULL, samedir, cnp);
2451	return (error);
2452}
2453
2454int
2455mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp)
2456{
2457	int error;
2458
2459	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke");
2460
2461	if (!mac_enforce_fs)
2462		return (0);
2463
2464	error = vn_refreshlabel(vp, cred);
2465	if (error)
2466		return (error);
2467
2468	MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label);
2469	return (error);
2470}
2471
2472int
2473mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
2474    struct acl *acl)
2475{
2476	int error;
2477
2478	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl");
2479
2480	if (!mac_enforce_fs)
2481		return (0);
2482
2483	error = vn_refreshlabel(vp, cred);
2484	if (error)
2485		return (error);
2486
2487	MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl);
2488	return (error);
2489}
2490
2491int
2492mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2493    int attrnamespace, const char *name, struct uio *uio)
2494{
2495	int error;
2496
2497	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr");
2498
2499	if (!mac_enforce_fs)
2500		return (0);
2501
2502	error = vn_refreshlabel(vp, cred);
2503	if (error)
2504		return (error);
2505
2506	MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label,
2507	    attrnamespace, name, uio);
2508	return (error);
2509}
2510
2511int
2512mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
2513{
2514	int error;
2515
2516	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags");
2517
2518	if (!mac_enforce_fs)
2519		return (0);
2520
2521	error = vn_refreshlabel(vp, cred);
2522	if (error)
2523		return (error);
2524
2525	MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags);
2526	return (error);
2527}
2528
2529int
2530mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
2531{
2532	int error;
2533
2534	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode");
2535
2536	if (!mac_enforce_fs)
2537		return (0);
2538
2539	error = vn_refreshlabel(vp, cred);
2540	if (error)
2541		return (error);
2542
2543	MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode);
2544	return (error);
2545}
2546
2547int
2548mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
2549    gid_t gid)
2550{
2551	int error;
2552
2553	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner");
2554
2555	if (!mac_enforce_fs)
2556		return (0);
2557
2558	error = vn_refreshlabel(vp, cred);
2559	if (error)
2560		return (error);
2561
2562	MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid);
2563	return (error);
2564}
2565
2566int
2567mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2568    struct timespec atime, struct timespec mtime)
2569{
2570	int error;
2571
2572	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes");
2573
2574	if (!mac_enforce_fs)
2575		return (0);
2576
2577	error = vn_refreshlabel(vp, cred);
2578	if (error)
2579		return (error);
2580
2581	MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime,
2582	    mtime);
2583	return (error);
2584}
2585
2586int
2587mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2588    struct vnode *vp)
2589{
2590	int error;
2591
2592	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat");
2593
2594	if (!mac_enforce_fs)
2595		return (0);
2596
2597	error = vn_refreshlabel(vp, active_cred);
2598	if (error)
2599		return (error);
2600
2601	MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp,
2602	    &vp->v_label);
2603	return (error);
2604}
2605
2606int
2607mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
2608    struct vnode *vp)
2609{
2610	int error;
2611
2612	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write");
2613
2614	if (!mac_enforce_fs)
2615		return (0);
2616
2617	error = vn_refreshlabel(vp, active_cred);
2618	if (error)
2619		return (error);
2620
2621	MAC_CHECK(check_vnode_write, active_cred, file_cred, vp,
2622	    &vp->v_label);
2623
2624	return (error);
2625}
2626
2627/*
2628 * When relabeling a process, call out to the policies for the maximum
2629 * permission allowed for each object type we know about in its
2630 * memory space, and revoke access (in the least surprising ways we
2631 * know) when necessary.  The process lock is not held here.
2632 */
2633static void
2634mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred)
2635{
2636
2637	/* XXX freeze all other threads */
2638	mac_cred_mmapped_drop_perms_recurse(td, cred,
2639	    &td->td_proc->p_vmspace->vm_map);
2640	/* XXX allow other threads to continue */
2641}
2642
2643static __inline const char *
2644prot2str(vm_prot_t prot)
2645{
2646
2647	switch (prot & VM_PROT_ALL) {
2648	case VM_PROT_READ:
2649		return ("r--");
2650	case VM_PROT_READ | VM_PROT_WRITE:
2651		return ("rw-");
2652	case VM_PROT_READ | VM_PROT_EXECUTE:
2653		return ("r-x");
2654	case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
2655		return ("rwx");
2656	case VM_PROT_WRITE:
2657		return ("-w-");
2658	case VM_PROT_EXECUTE:
2659		return ("--x");
2660	case VM_PROT_WRITE | VM_PROT_EXECUTE:
2661		return ("-wx");
2662	default:
2663		return ("---");
2664	}
2665}
2666
2667static void
2668mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred,
2669    struct vm_map *map)
2670{
2671	struct vm_map_entry *vme;
2672	int result;
2673	vm_prot_t revokeperms;
2674	vm_object_t object;
2675	vm_ooffset_t offset;
2676	struct vnode *vp;
2677
2678	if (!mac_mmap_revocation)
2679		return;
2680
2681	vm_map_lock_read(map);
2682	for (vme = map->header.next; vme != &map->header; vme = vme->next) {
2683		if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) {
2684			mac_cred_mmapped_drop_perms_recurse(td, cred,
2685			    vme->object.sub_map);
2686			continue;
2687		}
2688		/*
2689		 * Skip over entries that obviously are not shared.
2690		 */
2691		if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) ||
2692		    !vme->max_protection)
2693			continue;
2694		/*
2695		 * Drill down to the deepest backing object.
2696		 */
2697		offset = vme->offset;
2698		object = vme->object.vm_object;
2699		if (object == NULL)
2700			continue;
2701		while (object->backing_object != NULL) {
2702			object = object->backing_object;
2703			offset += object->backing_object_offset;
2704		}
2705		/*
2706		 * At the moment, vm_maps and objects aren't considered
2707		 * by the MAC system, so only things with backing by a
2708		 * normal object (read: vnodes) are checked.
2709		 */
2710		if (object->type != OBJT_VNODE)
2711			continue;
2712		vp = (struct vnode *)object->handle;
2713		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2714		result = vme->max_protection;
2715		mac_check_vnode_mmap_downgrade(cred, vp, &result);
2716		VOP_UNLOCK(vp, 0, td);
2717		/*
2718		 * Find out what maximum protection we may be allowing
2719		 * now but a policy needs to get removed.
2720		 */
2721		revokeperms = vme->max_protection & ~result;
2722		if (!revokeperms)
2723			continue;
2724		printf("pid %ld: revoking %s perms from %#lx:%ld "
2725		    "(max %s/cur %s)\n", (long)td->td_proc->p_pid,
2726		    prot2str(revokeperms), (u_long)vme->start,
2727		    (long)(vme->end - vme->start),
2728		    prot2str(vme->max_protection), prot2str(vme->protection));
2729		vm_map_lock_upgrade(map);
2730		/*
2731		 * This is the really simple case: if a map has more
2732		 * max_protection than is allowed, but it's not being
2733		 * actually used (that is, the current protection is
2734		 * still allowed), we can just wipe it out and do
2735		 * nothing more.
2736		 */
2737		if ((vme->protection & revokeperms) == 0) {
2738			vme->max_protection -= revokeperms;
2739		} else {
2740			if (revokeperms & VM_PROT_WRITE) {
2741				/*
2742				 * In the more complicated case, flush out all
2743				 * pending changes to the object then turn it
2744				 * copy-on-write.
2745				 */
2746				vm_object_reference(object);
2747				vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2748				vm_object_page_clean(object,
2749				    OFF_TO_IDX(offset),
2750				    OFF_TO_IDX(offset + vme->end - vme->start +
2751					PAGE_MASK),
2752				    OBJPC_SYNC);
2753				VOP_UNLOCK(vp, 0, td);
2754				vm_object_deallocate(object);
2755				/*
2756				 * Why bother if there's no read permissions
2757				 * anymore?  For the rest, we need to leave
2758				 * the write permissions on for COW, or
2759				 * remove them entirely if configured to.
2760				 */
2761				if (!mac_mmap_revocation_via_cow) {
2762					vme->max_protection &= ~VM_PROT_WRITE;
2763					vme->protection &= ~VM_PROT_WRITE;
2764				} if ((revokeperms & VM_PROT_READ) == 0)
2765					vme->eflags |= MAP_ENTRY_COW |
2766					    MAP_ENTRY_NEEDS_COPY;
2767			}
2768			if (revokeperms & VM_PROT_EXECUTE) {
2769				vme->max_protection &= ~VM_PROT_EXECUTE;
2770				vme->protection &= ~VM_PROT_EXECUTE;
2771			}
2772			if (revokeperms & VM_PROT_READ) {
2773				vme->max_protection = 0;
2774				vme->protection = 0;
2775			}
2776			pmap_protect(map->pmap, vme->start, vme->end,
2777			    vme->protection & ~revokeperms);
2778			vm_map_simplify_entry(map, vme);
2779		}
2780		vm_map_lock_downgrade(map);
2781	}
2782	vm_map_unlock_read(map);
2783}
2784
2785/*
2786 * When the subject's label changes, it may require revocation of privilege
2787 * to mapped objects.  This can't be done on-the-fly later with a unified
2788 * buffer cache.
2789 */
2790static void
2791mac_relabel_cred(struct ucred *cred, struct label *newlabel)
2792{
2793
2794	MAC_PERFORM(relabel_cred, cred, newlabel);
2795}
2796
2797void
2798mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel)
2799{
2800
2801	MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel);
2802}
2803
2804void
2805mac_create_ifnet(struct ifnet *ifnet)
2806{
2807
2808	MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label);
2809}
2810
2811void
2812mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d)
2813{
2814
2815	MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label);
2816}
2817
2818void
2819mac_create_socket(struct ucred *cred, struct socket *socket)
2820{
2821
2822	MAC_PERFORM(create_socket, cred, socket, &socket->so_label);
2823}
2824
2825void
2826mac_create_pipe(struct ucred *cred, struct pipe *pipe)
2827{
2828
2829	MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label);
2830}
2831
2832void
2833mac_create_socket_from_socket(struct socket *oldsocket,
2834    struct socket *newsocket)
2835{
2836
2837	MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label,
2838	    newsocket, &newsocket->so_label);
2839}
2840
2841static void
2842mac_relabel_socket(struct ucred *cred, struct socket *socket,
2843    struct label *newlabel)
2844{
2845
2846	MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel);
2847}
2848
2849static void
2850mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel)
2851{
2852
2853	MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel);
2854}
2855
2856void
2857mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket)
2858{
2859
2860	MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label,
2861	    socket, &socket->so_peerlabel);
2862}
2863
2864void
2865mac_set_socket_peer_from_socket(struct socket *oldsocket,
2866    struct socket *newsocket)
2867{
2868
2869	MAC_PERFORM(set_socket_peer_from_socket, oldsocket,
2870	    &oldsocket->so_label, newsocket, &newsocket->so_peerlabel);
2871}
2872
2873void
2874mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram)
2875{
2876
2877	MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label,
2878	    datagram, &datagram->m_pkthdr.label);
2879}
2880
2881void
2882mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment)
2883{
2884
2885	MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label,
2886	    fragment, &fragment->m_pkthdr.label);
2887}
2888
2889void
2890mac_create_ipq(struct mbuf *fragment, struct ipq *ipq)
2891{
2892
2893	MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq,
2894	    &ipq->ipq_label);
2895}
2896
2897void
2898mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf)
2899{
2900
2901	MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label,
2902	    newmbuf, &newmbuf->m_pkthdr.label);
2903}
2904
2905void
2906mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf)
2907{
2908
2909	MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf,
2910	    &mbuf->m_pkthdr.label);
2911}
2912
2913void
2914mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf)
2915{
2916
2917	MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf,
2918	    &mbuf->m_pkthdr.label);
2919}
2920
2921void
2922mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf)
2923{
2924
2925	MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf,
2926	    &mbuf->m_pkthdr.label);
2927}
2928
2929void
2930mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet,
2931    struct mbuf *newmbuf)
2932{
2933
2934	MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf,
2935	    &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf,
2936	    &newmbuf->m_pkthdr.label);
2937}
2938
2939void
2940mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf)
2941{
2942
2943	MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label,
2944	    newmbuf, &newmbuf->m_pkthdr.label);
2945}
2946
2947int
2948mac_fragment_match(struct mbuf *fragment, struct ipq *ipq)
2949{
2950	int result;
2951
2952	result = 1;
2953	MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label,
2954	    ipq, &ipq->ipq_label);
2955
2956	return (result);
2957}
2958
2959void
2960mac_update_ipq(struct mbuf *fragment, struct ipq *ipq)
2961{
2962
2963	MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq,
2964	    &ipq->ipq_label);
2965}
2966
2967void
2968mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf)
2969{
2970
2971	MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf,
2972	    &mbuf->m_pkthdr.label);
2973}
2974
2975void
2976mac_create_mount(struct ucred *cred, struct mount *mp)
2977{
2978
2979	MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel,
2980	    &mp->mnt_fslabel);
2981}
2982
2983void
2984mac_create_root_mount(struct ucred *cred, struct mount *mp)
2985{
2986
2987	MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel,
2988	    &mp->mnt_fslabel);
2989}
2990
2991int
2992mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet)
2993{
2994	int error;
2995
2996	if (!mac_enforce_network)
2997		return (0);
2998
2999	MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet,
3000	    &ifnet->if_label);
3001
3002	return (error);
3003}
3004
3005static int
3006mac_check_cred_relabel(struct ucred *cred, struct label *newlabel)
3007{
3008	int error;
3009
3010	MAC_CHECK(check_cred_relabel, cred, newlabel);
3011
3012	return (error);
3013}
3014
3015int
3016mac_check_cred_visible(struct ucred *u1, struct ucred *u2)
3017{
3018	int error;
3019
3020	if (!mac_enforce_process)
3021		return (0);
3022
3023	MAC_CHECK(check_cred_visible, u1, u2);
3024
3025	return (error);
3026}
3027
3028int
3029mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf)
3030{
3031	int error;
3032
3033	if (!mac_enforce_network)
3034		return (0);
3035
3036	KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr"));
3037	if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED))
3038		if_printf(ifnet, "not initialized\n");
3039
3040	MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf,
3041	    &mbuf->m_pkthdr.label);
3042
3043	return (error);
3044}
3045
3046int
3047mac_check_mount_stat(struct ucred *cred, struct mount *mount)
3048{
3049	int error;
3050
3051	if (!mac_enforce_fs)
3052		return (0);
3053
3054	MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel);
3055
3056	return (error);
3057}
3058
3059int
3060mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd,
3061    void *data)
3062{
3063	int error;
3064
3065	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
3066
3067	if (!mac_enforce_pipe)
3068		return (0);
3069
3070	MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data);
3071
3072	return (error);
3073}
3074
3075int
3076mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe)
3077{
3078	int error;
3079
3080	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
3081
3082	if (!mac_enforce_pipe)
3083		return (0);
3084
3085	MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label);
3086
3087	return (error);
3088}
3089
3090int
3091mac_check_pipe_read(struct ucred *cred, struct pipe *pipe)
3092{
3093	int error;
3094
3095	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
3096
3097	if (!mac_enforce_pipe)
3098		return (0);
3099
3100	MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label);
3101
3102	return (error);
3103}
3104
3105static int
3106mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
3107    struct label *newlabel)
3108{
3109	int error;
3110
3111	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
3112
3113	if (!mac_enforce_pipe)
3114		return (0);
3115
3116	MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel);
3117
3118	return (error);
3119}
3120
3121int
3122mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe)
3123{
3124	int error;
3125
3126	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
3127
3128	if (!mac_enforce_pipe)
3129		return (0);
3130
3131	MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label);
3132
3133	return (error);
3134}
3135
3136int
3137mac_check_pipe_write(struct ucred *cred, struct pipe *pipe)
3138{
3139	int error;
3140
3141	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
3142
3143	if (!mac_enforce_pipe)
3144		return (0);
3145
3146	MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label);
3147
3148	return (error);
3149}
3150
3151int
3152mac_check_proc_debug(struct ucred *cred, struct proc *proc)
3153{
3154	int error;
3155
3156	PROC_LOCK_ASSERT(proc, MA_OWNED);
3157
3158	if (!mac_enforce_process)
3159		return (0);
3160
3161	MAC_CHECK(check_proc_debug, cred, proc);
3162
3163	return (error);
3164}
3165
3166int
3167mac_check_proc_sched(struct ucred *cred, struct proc *proc)
3168{
3169	int error;
3170
3171	PROC_LOCK_ASSERT(proc, MA_OWNED);
3172
3173	if (!mac_enforce_process)
3174		return (0);
3175
3176	MAC_CHECK(check_proc_sched, cred, proc);
3177
3178	return (error);
3179}
3180
3181int
3182mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
3183{
3184	int error;
3185
3186	PROC_LOCK_ASSERT(proc, MA_OWNED);
3187
3188	if (!mac_enforce_process)
3189		return (0);
3190
3191	MAC_CHECK(check_proc_signal, cred, proc, signum);
3192
3193	return (error);
3194}
3195
3196int
3197mac_check_socket_bind(struct ucred *ucred, struct socket *socket,
3198    struct sockaddr *sockaddr)
3199{
3200	int error;
3201
3202	if (!mac_enforce_socket)
3203		return (0);
3204
3205	MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label,
3206	    sockaddr);
3207
3208	return (error);
3209}
3210
3211int
3212mac_check_socket_connect(struct ucred *cred, struct socket *socket,
3213    struct sockaddr *sockaddr)
3214{
3215	int error;
3216
3217	if (!mac_enforce_socket)
3218		return (0);
3219
3220	MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label,
3221	    sockaddr);
3222
3223	return (error);
3224}
3225
3226int
3227mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf)
3228{
3229	int error;
3230
3231	if (!mac_enforce_socket)
3232		return (0);
3233
3234	MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf,
3235	    &mbuf->m_pkthdr.label);
3236
3237	return (error);
3238}
3239
3240int
3241mac_check_socket_listen(struct ucred *cred, struct socket *socket)
3242{
3243	int error;
3244
3245	if (!mac_enforce_socket)
3246		return (0);
3247
3248	MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label);
3249	return (error);
3250}
3251
3252int
3253mac_check_socket_receive(struct ucred *cred, struct socket *so)
3254{
3255	int error;
3256
3257	if (!mac_enforce_socket)
3258		return (0);
3259
3260	MAC_CHECK(check_socket_receive, cred, so, &so->so_label);
3261
3262	return (error);
3263}
3264
3265static int
3266mac_check_socket_relabel(struct ucred *cred, struct socket *socket,
3267    struct label *newlabel)
3268{
3269	int error;
3270
3271	MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label,
3272	    newlabel);
3273
3274	return (error);
3275}
3276
3277int
3278mac_check_socket_send(struct ucred *cred, struct socket *so)
3279{
3280	int error;
3281
3282	if (!mac_enforce_socket)
3283		return (0);
3284
3285	MAC_CHECK(check_socket_send, cred, so, &so->so_label);
3286
3287	return (error);
3288}
3289
3290int
3291mac_check_socket_visible(struct ucred *cred, struct socket *socket)
3292{
3293	int error;
3294
3295	if (!mac_enforce_socket)
3296		return (0);
3297
3298	MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label);
3299
3300	return (error);
3301}
3302
3303int
3304mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
3305    struct ifnet *ifnet)
3306{
3307	char *elements, *buffer;
3308	struct mac mac;
3309	int error;
3310
3311	error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
3312	if (error)
3313		return (error);
3314
3315	error = mac_check_structmac_consistent(&mac);
3316	if (error)
3317		return (error);
3318
3319	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3320
3321	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
3322	if (error) {
3323		free(elements, M_MACTEMP);
3324		return (error);
3325	}
3326
3327	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3328
3329	error = mac_externalize_ifnet_label(&ifnet->if_label, elements,
3330	    buffer, mac.m_buflen, M_WAITOK);
3331	if (error == 0)
3332		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
3333
3334	free(buffer, M_MACTEMP);
3335	free(elements, M_MACTEMP);
3336
3337	return (error);
3338}
3339
3340int
3341mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
3342    struct ifnet *ifnet)
3343{
3344	struct label intlabel;
3345	struct mac mac;
3346	char *buffer;
3347	int error;
3348
3349	error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
3350	if (error)
3351		return (error);
3352
3353	error = mac_check_structmac_consistent(&mac);
3354	if (error)
3355		return (error);
3356
3357	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3358
3359	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
3360	if (error) {
3361		free(buffer, M_MACTEMP);
3362		return (error);
3363	}
3364
3365	mac_init_ifnet_label(&intlabel);
3366	error = mac_internalize_ifnet_label(&intlabel, buffer);
3367	free(buffer, M_MACTEMP);
3368	if (error) {
3369		mac_destroy_ifnet_label(&intlabel);
3370		return (error);
3371	}
3372
3373	/*
3374	 * XXX: Note that this is a redundant privilege check, since
3375	 * policies impose this check themselves if required by the
3376	 * policy.  Eventually, this should go away.
3377	 */
3378	error = suser_cred(cred, 0);
3379	if (error) {
3380		mac_destroy_ifnet_label(&intlabel);
3381		return (error);
3382	}
3383
3384	MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label,
3385	    &intlabel);
3386	if (error) {
3387		mac_destroy_ifnet_label(&intlabel);
3388		return (error);
3389	}
3390
3391	MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel);
3392
3393	mac_destroy_ifnet_label(&intlabel);
3394	return (0);
3395}
3396
3397void
3398mac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp)
3399{
3400
3401	MAC_PERFORM(create_devfs_vnode, de, &de->de_label, vp, &vp->v_label);
3402}
3403
3404void
3405mac_create_devfs_device(dev_t dev, struct devfs_dirent *de)
3406{
3407
3408	MAC_PERFORM(create_devfs_device, dev, de, &de->de_label);
3409}
3410
3411void
3412mac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
3413    struct devfs_dirent *de)
3414{
3415
3416	MAC_PERFORM(create_devfs_symlink, cred, dd, &dd->de_label, de,
3417	    &de->de_label);
3418}
3419
3420static int
3421mac_stdcreatevnode_ea(struct vnode *vp)
3422{
3423	int error;
3424
3425	MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label);
3426
3427	return (error);
3428}
3429
3430void
3431mac_create_devfs_directory(char *dirname, int dirnamelen,
3432    struct devfs_dirent *de)
3433{
3434
3435	MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de,
3436	    &de->de_label);
3437}
3438
3439/*
3440 * When a new vnode is created, this call will initialize its label.
3441 */
3442void
3443mac_create_vnode(struct ucred *cred, struct vnode *parent,
3444    struct vnode *child)
3445{
3446	int error;
3447
3448	ASSERT_VOP_LOCKED(parent, "mac_create_vnode");
3449	ASSERT_VOP_LOCKED(child, "mac_create_vnode");
3450
3451	error = vn_refreshlabel(parent, cred);
3452	if (error) {
3453		printf("mac_create_vnode: vn_refreshlabel returned %d\n",
3454		    error);
3455		printf("mac_create_vnode: using old vnode label\n");
3456	}
3457
3458	MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child,
3459	    &child->v_label);
3460}
3461
3462int
3463mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
3464    struct mac *mac)
3465{
3466	struct label intlabel;
3467	char *buffer;
3468	int error;
3469
3470	error = mac_check_structmac_consistent(mac);
3471	if (error)
3472		return (error);
3473
3474	buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
3475
3476	error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL);
3477	if (error) {
3478		free(buffer, M_MACTEMP);
3479		return (error);
3480	}
3481
3482	mac_init_socket_label(&intlabel, M_WAITOK);
3483	error = mac_internalize_socket_label(&intlabel, buffer);
3484	free(buffer, M_MACTEMP);
3485	if (error) {
3486		mac_destroy_socket_label(&intlabel);
3487		return (error);
3488	}
3489
3490	mac_check_socket_relabel(cred, so, &intlabel);
3491	if (error) {
3492		mac_destroy_socket_label(&intlabel);
3493		return (error);
3494	}
3495
3496	mac_relabel_socket(cred, so, &intlabel);
3497
3498	mac_destroy_socket_label(&intlabel);
3499	return (0);
3500}
3501
3502int
3503mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label)
3504{
3505	int error;
3506
3507	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
3508
3509	error = mac_check_pipe_relabel(cred, pipe, label);
3510	if (error)
3511		return (error);
3512
3513	mac_relabel_pipe(cred, pipe, label);
3514
3515	return (0);
3516}
3517
3518int
3519mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
3520    struct mac *mac)
3521{
3522	char *buffer, *elements;
3523	int error;
3524
3525	error = mac_check_structmac_consistent(mac);
3526	if (error)
3527		return (error);
3528
3529	elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
3530
3531	error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
3532	if (error) {
3533		free(elements, M_MACTEMP);
3534		return (error);
3535	}
3536
3537	buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3538
3539	error = mac_externalize_socket_label(&so->so_label, elements,
3540	    buffer, mac->m_buflen, M_WAITOK);
3541	if (error == 0)
3542		error = copyout(buffer, mac->m_string, strlen(buffer)+1);
3543
3544	free(buffer, M_MACTEMP);
3545	free(elements, M_MACTEMP);
3546
3547	return (error);
3548}
3549
3550int
3551mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
3552    struct mac *mac)
3553{
3554	char *elements, *buffer;
3555	int error;
3556
3557	error = mac_check_structmac_consistent(mac);
3558	if (error)
3559		return (error);
3560
3561	elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
3562
3563	error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
3564	if (error) {
3565		free(elements, M_MACTEMP);
3566		return (error);
3567	}
3568
3569	buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3570
3571	error = mac_externalize_socket_peer_label(&so->so_peerlabel,
3572	    elements, buffer, mac->m_buflen, M_WAITOK);
3573	if (error == 0)
3574		error = copyout(buffer, mac->m_string, strlen(buffer)+1);
3575
3576	free(buffer, M_MACTEMP);
3577	free(elements, M_MACTEMP);
3578
3579	return (error);
3580}
3581
3582/*
3583 * Implementation of VOP_SETLABEL() that relies on extended attributes
3584 * to store label data.  Can be referenced by filesystems supporting
3585 * extended attributes.
3586 */
3587int
3588vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
3589{
3590	struct vnode *vp = ap->a_vp;
3591	struct label *intlabel = ap->a_label;
3592	struct oldmac extmac;
3593	int error;
3594
3595	ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
3596
3597	/*
3598	 * XXX: Eventually call out to EA check/set calls here.
3599	 * Be particularly careful to avoid race conditions,
3600	 * consistency problems, and stability problems when
3601	 * dealing with multiple EAs.  In particular, we require
3602	 * the ability to write multiple EAs on the same file in
3603	 * a single transaction, which the current EA interface
3604	 * does not provide.
3605	 */
3606
3607	error = mac_externalize_vnode_oldmac(intlabel, &extmac);
3608	if (error)
3609		return (error);
3610
3611	error = vn_extattr_set(vp, IO_NODELOCKED,
3612	    FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
3613	    sizeof(extmac), (char *)&extmac, curthread);
3614	if (error)
3615		return (error);
3616
3617	mac_relabel_vnode(ap->a_cred, vp, intlabel);
3618
3619	vp->v_vflag |= VV_CACHEDLABEL;
3620
3621	return (0);
3622}
3623
3624static int
3625vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred)
3626{
3627	int error;
3628
3629	if (vp->v_mount == NULL) {
3630		/* printf("vn_setlabel: null v_mount\n"); */
3631		if (vp->v_type != VNON)
3632			printf("vn_setlabel: null v_mount with non-VNON\n");
3633		return (EBADF);
3634	}
3635
3636	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
3637		return (EOPNOTSUPP);
3638
3639	/*
3640	 * Multi-phase commit.  First check the policies to confirm the
3641	 * change is OK.  Then commit via the filesystem.  Finally,
3642	 * update the actual vnode label.  Question: maybe the filesystem
3643	 * should update the vnode at the end as part of VOP_SETLABEL()?
3644	 */
3645	error = mac_check_vnode_relabel(cred, vp, intlabel);
3646	if (error)
3647		return (error);
3648
3649	/*
3650	 * VADMIN provides the opportunity for the filesystem to make
3651	 * decisions about who is and is not able to modify labels
3652	 * and protections on files.  This might not be right.  We can't
3653	 * assume VOP_SETLABEL() will do it, because we might implement
3654	 * that as part of vop_stdsetlabel_ea().
3655	 */
3656	error = VOP_ACCESS(vp, VADMIN, cred, curthread);
3657	if (error)
3658		return (error);
3659
3660	error = VOP_SETLABEL(vp, intlabel, cred, curthread);
3661	if (error)
3662		return (error);
3663
3664	return (0);
3665}
3666
3667int
3668__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
3669{
3670	char *elements, *buffer;
3671	struct mac mac;
3672	struct proc *tproc;
3673	struct ucred *tcred;
3674	int error;
3675
3676	error = copyin(SCARG(uap, mac_p), &mac, sizeof(mac));
3677	if (error)
3678		return (error);
3679
3680	error = mac_check_structmac_consistent(&mac);
3681	if (error)
3682		return (error);
3683
3684	tproc = pfind(uap->pid);
3685	if (tproc == NULL)
3686		return (ESRCH);
3687
3688	tcred = NULL;				/* Satisfy gcc. */
3689	error = p_cansee(td, tproc);
3690	if (error == 0)
3691		tcred = crhold(tproc->p_ucred);
3692	PROC_UNLOCK(tproc);
3693	if (error)
3694		return (error);
3695
3696	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3697
3698	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
3699	if (error) {
3700		free(elements, M_MACTEMP);
3701		crfree(tcred);
3702		return (error);
3703	}
3704
3705	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3706
3707	error = mac_externalize_cred_label(&tcred->cr_label, elements,
3708	    buffer, mac.m_buflen, M_WAITOK);
3709	if (error == 0)
3710		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
3711
3712	free(buffer, M_MACTEMP);
3713	free(elements, M_MACTEMP);
3714	crfree(tcred);
3715	return (error);
3716}
3717
3718/*
3719 * MPSAFE
3720 */
3721int
3722__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
3723{
3724	char *elements, *buffer;
3725	struct mac mac;
3726	int error;
3727
3728	error = copyin(uap->mac_p, &mac, sizeof(mac));
3729	if (error)
3730		return (error);
3731
3732	error = mac_check_structmac_consistent(&mac);
3733	if (error)
3734		return (error);
3735
3736	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3737
3738	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
3739	if (error) {
3740		free(elements, M_MACTEMP);
3741		return (error);
3742	}
3743
3744	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3745
3746	error = mac_externalize_cred_label(&td->td_ucred->cr_label,
3747	    elements, buffer, mac.m_buflen, M_WAITOK);
3748	if (error == 0)
3749		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
3750
3751	free(buffer, M_MACTEMP);
3752	free(elements, M_MACTEMP);
3753	return (error);
3754}
3755
3756/*
3757 * MPSAFE
3758 */
3759int
3760__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
3761{
3762	struct ucred *newcred, *oldcred;
3763	struct label intlabel;
3764	struct proc *p;
3765	struct mac mac;
3766	char *buffer;
3767	int error;
3768
3769	error = copyin(uap->mac_p, &mac, sizeof(mac));
3770	if (error)
3771		return (error);
3772
3773	error = mac_check_structmac_consistent(&mac);
3774	if (error)
3775		return (error);
3776
3777	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3778
3779	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
3780	if (error) {
3781		free(buffer, M_MACTEMP);
3782		return (error);
3783	}
3784
3785	mac_init_cred_label(&intlabel);
3786	error = mac_internalize_cred_label(&intlabel, buffer);
3787	free(buffer, M_MACTEMP);
3788	if (error) {
3789		mac_destroy_cred_label(&intlabel);
3790		return (error);
3791	}
3792
3793	newcred = crget();
3794
3795	p = td->td_proc;
3796	PROC_LOCK(p);
3797	oldcred = p->p_ucred;
3798
3799	error = mac_check_cred_relabel(oldcred, &intlabel);
3800	if (error) {
3801		PROC_UNLOCK(p);
3802		crfree(newcred);
3803		goto out;
3804	}
3805
3806	setsugid(p);
3807	crcopy(newcred, oldcred);
3808	mac_relabel_cred(newcred, &intlabel);
3809	p->p_ucred = newcred;
3810
3811	/*
3812	 * Grab additional reference for use while revoking mmaps, prior
3813	 * to releasing the proc lock and sharing the cred.
3814	 */
3815	crhold(newcred);
3816	PROC_UNLOCK(p);
3817
3818	if (mac_enforce_vm) {
3819		mtx_lock(&Giant);
3820		mac_cred_mmapped_drop_perms(td, newcred);
3821		mtx_unlock(&Giant);
3822	}
3823
3824	crfree(newcred);	/* Free revocation reference. */
3825	crfree(oldcred);
3826
3827out:
3828	mac_destroy_cred_label(&intlabel);
3829	return (error);
3830}
3831
3832/*
3833 * MPSAFE
3834 */
3835int
3836__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
3837{
3838	char *elements, *buffer;
3839	struct label intlabel;
3840	struct file *fp;
3841	struct mac mac;
3842	struct vnode *vp;
3843	struct pipe *pipe;
3844	short label_type;
3845	int error;
3846
3847	error = copyin(uap->mac_p, &mac, sizeof(mac));
3848	if (error)
3849		return (error);
3850
3851	error = mac_check_structmac_consistent(&mac);
3852	if (error)
3853		return (error);
3854
3855	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3856
3857	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
3858	if (error) {
3859		free(elements, M_MACTEMP);
3860		return (error);
3861	}
3862
3863	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3864
3865	mtx_lock(&Giant);				/* VFS */
3866	error = fget(td, SCARG(uap, fd), &fp);
3867	if (error)
3868		goto out;
3869
3870	label_type = fp->f_type;
3871	switch (fp->f_type) {
3872	case DTYPE_FIFO:
3873	case DTYPE_VNODE:
3874		vp = (struct vnode *)fp->f_data;
3875
3876		mac_init_vnode_label(&intlabel);
3877
3878		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3879		error = vn_refreshlabel(vp, td->td_ucred);
3880		if (error == 0)
3881			mac_copy_vnode_label(&vp->v_label, &intlabel);
3882		VOP_UNLOCK(vp, 0, td);
3883
3884		break;
3885	case DTYPE_PIPE:
3886		pipe = (struct pipe *)fp->f_data;
3887
3888		mac_init_pipe_label(&intlabel);
3889
3890		PIPE_LOCK(pipe);
3891		mac_copy_pipe_label(pipe->pipe_label, &intlabel);
3892		PIPE_UNLOCK(pipe);
3893		break;
3894	default:
3895		error = EINVAL;
3896		fdrop(fp, td);
3897		goto out;
3898	}
3899	fdrop(fp, td);
3900
3901	switch (label_type) {
3902	case DTYPE_FIFO:
3903	case DTYPE_VNODE:
3904		if (error == 0)
3905			error = mac_externalize_vnode_label(&intlabel,
3906			    elements, buffer, mac.m_buflen, M_WAITOK);
3907		mac_destroy_vnode_label(&intlabel);
3908		break;
3909	case DTYPE_PIPE:
3910		error = mac_externalize_pipe_label(&intlabel, elements,
3911		    buffer, mac.m_buflen, M_WAITOK);
3912		mac_destroy_pipe_label(&intlabel);
3913		break;
3914	default:
3915		panic("__mac_get_fd: corrupted label_type");
3916	}
3917
3918	if (error == 0)
3919		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
3920
3921out:
3922	mtx_unlock(&Giant);				/* VFS */
3923	free(buffer, M_MACTEMP);
3924	free(elements, M_MACTEMP);
3925
3926	return (error);
3927}
3928
3929/*
3930 * MPSAFE
3931 */
3932int
3933__mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
3934{
3935	char *elements, *buffer;
3936	struct nameidata nd;
3937	struct label intlabel;
3938	struct mac mac;
3939	int error;
3940
3941	error = copyin(uap->mac_p, &mac, sizeof(mac));
3942	if (error)
3943		return (error);
3944
3945	error = mac_check_structmac_consistent(&mac);
3946	if (error)
3947		return (error);
3948
3949	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3950
3951	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
3952	if (error) {
3953		free(elements, M_MACTEMP);
3954		return (error);
3955	}
3956
3957	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3958
3959	mtx_lock(&Giant);				/* VFS */
3960	NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p,
3961	    td);
3962	error = namei(&nd);
3963	if (error)
3964		goto out;
3965
3966	mac_init_vnode_label(&intlabel);
3967	error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
3968	if (error == 0)
3969		mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
3970	if (error == 0)
3971		error = mac_externalize_vnode_label(&intlabel, elements,
3972		    buffer, mac.m_buflen, M_WAITOK);
3973
3974	NDFREE(&nd, 0);
3975	mac_destroy_vnode_label(&intlabel);
3976
3977	if (error == 0)
3978		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
3979
3980out:
3981	mtx_unlock(&Giant);				/* VFS */
3982
3983	free(buffer, M_MACTEMP);
3984	free(elements, M_MACTEMP);
3985
3986	return (error);
3987}
3988
3989/*
3990 * MPSAFE
3991 */
3992int
3993__mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
3994{
3995	char *elements, *buffer;
3996	struct nameidata nd;
3997	struct label intlabel;
3998	struct mac mac;
3999	int error;
4000
4001	error = copyin(uap->mac_p, &mac, sizeof(mac));
4002	if (error)
4003		return (error);
4004
4005	error = mac_check_structmac_consistent(&mac);
4006	if (error)
4007		return (error);
4008
4009	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
4010
4011	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
4012	if (error) {
4013		free(elements, M_MACTEMP);
4014		return (error);
4015	}
4016
4017	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
4018
4019	mtx_lock(&Giant);				/* VFS */
4020	NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p,
4021	    td);
4022	error = namei(&nd);
4023	if (error)
4024		goto out;
4025
4026	mac_init_vnode_label(&intlabel);
4027	error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
4028	if (error == 0)
4029		mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
4030	if (error == 0)
4031		error = mac_externalize_vnode_label(&intlabel, elements,
4032		    buffer, mac.m_buflen, M_WAITOK);
4033	NDFREE(&nd, 0);
4034	mac_destroy_vnode_label(&intlabel);
4035
4036	if (error == 0)
4037		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
4038
4039out:
4040	mtx_unlock(&Giant);				/* VFS */
4041
4042	free(buffer, M_MACTEMP);
4043	free(elements, M_MACTEMP);
4044
4045	return (error);
4046}
4047
4048/*
4049 * MPSAFE
4050 */
4051int
4052__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
4053{
4054	struct label intlabel;
4055	struct pipe *pipe;
4056	struct file *fp;
4057	struct mount *mp;
4058	struct vnode *vp;
4059	struct mac mac;
4060	char *buffer;
4061	int error;
4062
4063	error = copyin(uap->mac_p, &mac, sizeof(mac));
4064	if (error)
4065		return (error);
4066
4067	error = mac_check_structmac_consistent(&mac);
4068	if (error)
4069		return (error);
4070
4071	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
4072
4073	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
4074	if (error) {
4075		free(buffer, M_MACTEMP);
4076		return (error);
4077	}
4078
4079	mtx_lock(&Giant);				/* VFS */
4080
4081	error = fget(td, SCARG(uap, fd), &fp);
4082	if (error)
4083		goto out;
4084
4085	switch (fp->f_type) {
4086	case DTYPE_FIFO:
4087	case DTYPE_VNODE:
4088		mac_init_vnode_label(&intlabel);
4089		error = mac_internalize_vnode_label(&intlabel, buffer);
4090		if (error) {
4091			mac_destroy_vnode_label(&intlabel);
4092			break;
4093		}
4094
4095		vp = (struct vnode *)fp->f_data;
4096		error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
4097		if (error != 0) {
4098			mac_destroy_vnode_label(&intlabel);
4099			break;
4100		}
4101
4102		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4103		error = vn_setlabel(vp, &intlabel, td->td_ucred);
4104		VOP_UNLOCK(vp, 0, td);
4105		vn_finished_write(mp);
4106
4107		mac_destroy_vnode_label(&intlabel);
4108		break;
4109
4110	case DTYPE_PIPE:
4111		mac_init_pipe_label(&intlabel);
4112		error = mac_internalize_pipe_label(&intlabel, buffer);
4113		if (error == 0) {
4114			pipe = (struct pipe *)fp->f_data;
4115			PIPE_LOCK(pipe);
4116			error = mac_pipe_label_set(td->td_ucred, pipe,
4117			    &intlabel);
4118			PIPE_UNLOCK(pipe);
4119		}
4120
4121		mac_destroy_pipe_label(&intlabel);
4122		break;
4123
4124	default:
4125		error = EINVAL;
4126	}
4127
4128	fdrop(fp, td);
4129out:
4130	mtx_unlock(&Giant);				/* VFS */
4131
4132	free(buffer, M_MACTEMP);
4133
4134	return (error);
4135}
4136
4137/*
4138 * MPSAFE
4139 */
4140int
4141__mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
4142{
4143	struct label intlabel;
4144	struct nameidata nd;
4145	struct mount *mp;
4146	struct mac mac;
4147	char *buffer;
4148	int error;
4149
4150	error = copyin(uap->mac_p, &mac, sizeof(mac));
4151	if (error)
4152		return (error);
4153
4154	error = mac_check_structmac_consistent(&mac);
4155	if (error)
4156		return (error);
4157
4158	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
4159
4160	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
4161	if (error) {
4162		free(buffer, M_MACTEMP);
4163		return (error);
4164	}
4165
4166	mac_init_vnode_label(&intlabel);
4167	error = mac_internalize_vnode_label(&intlabel, buffer);
4168	free(buffer, M_MACTEMP);
4169	if (error) {
4170		mac_destroy_vnode_label(&intlabel);
4171		return (error);
4172	}
4173
4174	mtx_lock(&Giant);				/* VFS */
4175
4176	NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p,
4177	    td);
4178	error = namei(&nd);
4179	if (error == 0) {
4180		error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
4181		if (error == 0)
4182			error = vn_setlabel(nd.ni_vp, &intlabel,
4183			    td->td_ucred);
4184		vn_finished_write(mp);
4185	}
4186
4187	NDFREE(&nd, 0);
4188	mtx_unlock(&Giant);				/* VFS */
4189	mac_destroy_vnode_label(&intlabel);
4190
4191	return (error);
4192}
4193
4194/*
4195 * MPSAFE
4196 */
4197int
4198__mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
4199{
4200	struct label intlabel;
4201	struct nameidata nd;
4202	struct mount *mp;
4203	struct mac mac;
4204	char *buffer;
4205	int error;
4206
4207	error = copyin(uap->mac_p, &mac, sizeof(mac));
4208	if (error)
4209		return (error);
4210
4211	error = mac_check_structmac_consistent(&mac);
4212	if (error)
4213		return (error);
4214
4215	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
4216
4217	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
4218	if (error) {
4219		free(buffer, M_MACTEMP);
4220		return (error);
4221	}
4222
4223	mac_init_vnode_label(&intlabel);
4224	error = mac_internalize_vnode_label(&intlabel, buffer);
4225	free(buffer, M_MACTEMP);
4226	if (error) {
4227		mac_destroy_vnode_label(&intlabel);
4228		return (error);
4229	}
4230
4231	mtx_lock(&Giant);				/* VFS */
4232
4233	NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p,
4234	    td);
4235	error = namei(&nd);
4236	if (error == 0) {
4237		error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
4238		if (error == 0)
4239			error = vn_setlabel(nd.ni_vp, &intlabel,
4240			    td->td_ucred);
4241		vn_finished_write(mp);
4242	}
4243
4244	NDFREE(&nd, 0);
4245	mtx_unlock(&Giant);				/* VFS */
4246	mac_destroy_vnode_label(&intlabel);
4247
4248	return (error);
4249}
4250
4251/*
4252 * MPSAFE
4253 */
4254int
4255mac_syscall(struct thread *td, struct mac_syscall_args *uap)
4256{
4257	struct mac_policy_conf *mpc;
4258	char target[MAC_MAX_POLICY_NAME];
4259	int error;
4260
4261	error = copyinstr(SCARG(uap, policy), target, sizeof(target), NULL);
4262	if (error)
4263		return (error);
4264
4265	error = ENOSYS;
4266	MAC_POLICY_LIST_BUSY();
4267	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {
4268		if (strcmp(mpc->mpc_name, target) == 0 &&
4269		    mpc->mpc_ops->mpo_syscall != NULL) {
4270			error = mpc->mpc_ops->mpo_syscall(td,
4271			    SCARG(uap, call), SCARG(uap, arg));
4272			goto out;
4273		}
4274	}
4275
4276out:
4277	MAC_POLICY_LIST_UNBUSY();
4278	return (error);
4279}
4280
4281SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL);
4282SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL);
4283
4284#else /* !MAC */
4285
4286int
4287__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
4288{
4289
4290	return (ENOSYS);
4291}
4292
4293int
4294__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
4295{
4296
4297	return (ENOSYS);
4298}
4299
4300int
4301__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
4302{
4303
4304	return (ENOSYS);
4305}
4306
4307int
4308__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
4309{
4310
4311	return (ENOSYS);
4312}
4313
4314int
4315__mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
4316{
4317
4318	return (ENOSYS);
4319}
4320
4321int
4322__mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
4323{
4324
4325	return (ENOSYS);
4326}
4327
4328int
4329__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
4330{
4331
4332	return (ENOSYS);
4333}
4334
4335int
4336__mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
4337{
4338
4339	return (ENOSYS);
4340}
4341
4342int
4343__mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
4344{
4345
4346	return (ENOSYS);
4347}
4348
4349int
4350mac_syscall(struct thread *td, struct mac_syscall_args *uap)
4351{
4352
4353	return (ENOSYS);
4354}
4355
4356#endif
4357