mac_syscalls.c revision 104236
1153761Swollman/*-
2192886Sedwin * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3192886Sedwin * Copyright (c) 2001 Ilmar S. Habibulin
4153761Swollman * Copyright (c) 2001, 2002 Networks Associates Technology, Inc.
52742Swollman * All rights reserved.
686464Swollman *
72742Swollman * This software was developed by Robert Watson and Ilmar Habibulin for the
82742Swollman * TrustedBSD Project.
92742Swollman *
102742Swollman * This software was developed for the FreeBSD Project in part by NAI Labs,
112742Swollman * the Security Research Division of Network Associates, Inc. under
122742Swollman * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
1386222Swollman * CHATS research program.
1486222Swollman *
152742Swollman * Redistribution and use in source and binary forms, with or without
1658787Sru * modification, are permitted provided that the following conditions
172742Swollman * are met:
182742Swollman * 1. Redistributions of source code must retain the above copyright
192742Swollman *    notice, this list of conditions and the following disclaimer.
202742Swollman * 2. Redistributions in binary form must reproduce the above copyright
212742Swollman *    notice, this list of conditions and the following disclaimer in the
222742Swollman *    documentation and/or other materials provided with the distribution.
2358787Sru * 3. The names of the authors may not be used to endorse or promote
2458787Sru *    products derived from this software without specific prior written
2558787Sru *    permission.
262742Swollman *
272742Swollman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
289908Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
292742Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3030711Swollman * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
312742Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
329908Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33169811Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34169811Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35169811Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36169811Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37169811Swollman * SUCH DAMAGE.
38169811Swollman *
39169811Swollman * $FreeBSD: head/sys/security/mac/mac_syscalls.c 104236 2002-09-30 20:50:00Z rwatson $
40169811Swollman */
41169811Swollman/*
42169811Swollman * Developed by the TrustedBSD Project.
43169811Swollman *
442742Swollman * Framework for extensible kernel access control.  Kernel and userland
4558787Sru * interface to the framework, policy registration and composition.
46169811Swollman */
47169811Swollman
48169811Swollman#include "opt_mac.h"
49169811Swollman
50169811Swollman#include <sys/param.h>
519908Swollman#include <sys/extattr.h>
5220094Swollman#include <sys/kernel.h>
53149514Swollman#include <sys/lock.h>
5420094Swollman#include <sys/malloc.h>
5520094Swollman#include <sys/mutex.h>
5620094Swollman#include <sys/mac.h>
5720094Swollman#include <sys/module.h>
5820094Swollman#include <sys/proc.h>
5920094Swollman#include <sys/systm.h>
6020094Swollman#include <sys/sysproto.h>
6120094Swollman#include <sys/sysent.h>
6220094Swollman#include <sys/vnode.h>
6320094Swollman#include <sys/mount.h>
6420094Swollman#include <sys/file.h>
6558787Sru#include <sys/namei.h>
6658787Sru#include <sys/socket.h>
6721217Swollman#include <sys/pipe.h>
6821217Swollman#include <sys/socketvar.h>
6958787Sru#include <sys/sysctl.h>
7058787Sru
712742Swollman#include <vm/vm.h>
7258787Sru#include <vm/pmap.h>
7321217Swollman#include <vm/vm_map.h>
7420094Swollman#include <vm/vm_object.h>
7558787Sru
7658787Sru#include <sys/mac_policy.h>
7720094Swollman
782742Swollman#include <fs/devfs/devfs.h>
799908Swollman
802742Swollman#include <net/bpfdesc.h>
8114343Swollman#include <net/if.h>
8214343Swollman#include <net/if_var.h>
83171948Sedwin
8414343Swollman#include <netinet/in.h>
8514343Swollman#include <netinet/ip_var.h>
86218122Sedwin
87218122Sedwin#ifdef MAC
88218122Sedwin
89218122Sedwin/*
90218122Sedwin * Declare that the kernel provides MAC support, version 1.  This permits
91149514Swollman * modules to refuse to be loaded if the necessary support isn't present,
92218122Sedwin * even if it's pre-boot.
93171948Sedwin */
94171948SedwinMODULE_VERSION(kernel_mac_support, 1);
95171948Sedwin
962742SwollmanSYSCTL_DECL(_security);
972742Swollman
982742SwollmanSYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0,
9958787Sru    "TrustedBSD MAC policy controls");
1002742SwollmanSYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0,
1012742Swollman    "TrustedBSD MAC debug info");
1029908Swollman
103149514Swollmanstatic int	mac_debug_label_fallback = 0;
104149514SwollmanSYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW,
105149514Swollman    &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label"
106149514Swollman    "when label is corrupted.");
107149514SwollmanTUNABLE_INT("security.mac.debug_label_fallback",
1082742Swollman    &mac_debug_label_fallback);
10958787Sru
11058787Sru#ifndef MAC_MAX_POLICIES
11114343Swollman#define	MAC_MAX_POLICIES	8
11214343Swollman#endif
11358787Sru#if MAC_MAX_POLICIES > 32
11414343Swollman#error "MAC_MAX_POLICIES too large"
11514343Swollman#endif
11614343Swollmanstatic unsigned int mac_max_policies = MAC_MAX_POLICIES;
11758787Srustatic unsigned int mac_policy_offsets_free = (1 << MAC_MAX_POLICIES) - 1;
11814343SwollmanSYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD,
11958787Sru    &mac_max_policies, 0, "");
12058787Sru
12158787Srustatic int	mac_late = 0;
122149514Swollman
12358787Srustatic int	mac_enforce_fs = 1;
12458787SruSYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
125149514Swollman    &mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
126171948SedwinTUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
127171948Sedwin
1282742Swollmanstatic int	mac_enforce_network = 1;
1292742SwollmanSYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
13058787Sru    &mac_enforce_network, 0, "Enforce MAC policy on network packets");
13158787SruTUNABLE_INT("security.mac.enforce_network", &mac_enforce_network);
13258787Sru
1332742Swollmanstatic int	mac_enforce_pipe = 1;
134149514SwollmanSYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW,
135149514Swollman    &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations");
136149514SwollmanTUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe);
137149514Swollman
138149514Swollmanstatic int	mac_enforce_process = 1;
1392742SwollmanSYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW,
1409908Swollman    &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations");
1412742SwollmanTUNABLE_INT("security.mac.enforce_process", &mac_enforce_process);
14214343Swollman
14358787Srustatic int	mac_enforce_socket = 1;
14414343SwollmanSYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
14514343Swollman    &mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
14658787SruTUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
14758787Sru
14814343Swollmanstatic int     mac_enforce_vm = 1;
149149514SwollmanSYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
15058787Sru    &mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
151171948SedwinTUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm);
152149514Swollman
153171948Sedwinstatic int	mac_label_size = sizeof(struct mac);
154171948SedwinSYSCTL_INT(_security_mac, OID_AUTO, label_size, CTLFLAG_RD,
155171948Sedwin    &mac_label_size, 0, "Pre-compiled MAC label size");
1562742Swollman
1572742Swollmanstatic int	mac_cache_fslabel_in_vnode = 1;
15858787SruSYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW,
1592742Swollman    &mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode");
1602742SwollmanTUNABLE_INT("security.mac.cache_fslabel_in_vnode",
1619908Swollman    &mac_cache_fslabel_in_vnode);
1622742Swollman
16314343Swollmanstatic int	mac_vnode_label_cache_hits = 0;
16414343SwollmanSYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_hits, CTLFLAG_RD,
16514343Swollman    &mac_vnode_label_cache_hits, 0, "Cache hits on vnode labels");
16614343Swollmanstatic int	mac_vnode_label_cache_misses = 0;
16714343SwollmanSYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_misses, CTLFLAG_RD,
16814343Swollman    &mac_vnode_label_cache_misses, 0, "Cache misses on vnode labels");
16914343Swollman
17043543Swollmanstatic int	mac_mmap_revocation = 1;
17114343SwollmanSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW,
172149514Swollman    &mac_mmap_revocation, 0, "Revoke mmap access to files on subject "
17358787Sru    "relabel");
174171948Sedwinstatic int	mac_mmap_revocation_via_cow = 0;
175149514SwollmanSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW,
176171948Sedwin    &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via "
177171948Sedwin    "copy-on-write semantics, or by removing all write access");
178171948Sedwin
1792742Swollman#ifdef MAC_DEBUG
1802742Swollmanstatic unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs,
18158787Sru    nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents,
1822742Swollman    nmacipqs, nmacpipes;
1832742SwollmanSYSCTL_UINT(_security_mac_debug, OID_AUTO, mbufs, CTLFLAG_RD,
1842742Swollman    &nmacmbufs, 0, "number of mbufs in use");
1852742SwollmanSYSCTL_UINT(_security_mac_debug, OID_AUTO, creds, CTLFLAG_RD,
18658787Sru    &nmaccreds, 0, "number of ucreds in use");
18758787SruSYSCTL_UINT(_security_mac_debug, OID_AUTO, ifnets, CTLFLAG_RD,
18858787Sru    &nmacifnets, 0, "number of ifnets in use");
1898029SwollmanSYSCTL_UINT(_security_mac_debug, OID_AUTO, ipqs, CTLFLAG_RD,
19014343Swollman    &nmacipqs, 0, "number of ipqs in use");
19114343SwollmanSYSCTL_UINT(_security_mac_debug, OID_AUTO, bpfdescs, CTLFLAG_RD,
19275267Swollman    &nmacbpfdescs, 0, "number of bpfdescs in use");
19375267SwollmanSYSCTL_UINT(_security_mac_debug, OID_AUTO, sockets, CTLFLAG_RD,
19475267Swollman    &nmacsockets, 0, "number of sockets in use");
19575267SwollmanSYSCTL_UINT(_security_mac_debug, OID_AUTO, pipes, CTLFLAG_RD,
19675267Swollman    &nmacpipes, 0, "number of pipes in use");
19775267SwollmanSYSCTL_UINT(_security_mac_debug, OID_AUTO, mounts, CTLFLAG_RD,
19875267Swollman    &nmacmounts, 0, "number of mounts in use");
199149514SwollmanSYSCTL_UINT(_security_mac_debug, OID_AUTO, temp, CTLFLAG_RD,
20075267Swollman    &nmactemp, 0, "number of temporary labels in use");
201171948SedwinSYSCTL_UINT(_security_mac_debug, OID_AUTO, vnodes, CTLFLAG_RD,
202149514Swollman    &nmacvnodes, 0, "number of vnodes in use");
203171948SedwinSYSCTL_UINT(_security_mac_debug, OID_AUTO, devfsdirents, CTLFLAG_RD,
204171948Sedwin    &nmacdevfsdirents, 0, "number of devfs dirents inuse");
205171948Sedwin#endif
2062742Swollman
2072742Swollmanstatic int	error_select(int error1, int error2);
20814343Swollmanstatic int	mac_externalize(struct label *label, struct mac *mac);
2098029Swollmanstatic int	mac_policy_register(struct mac_policy_conf *mpc);
21014343Swollmanstatic int	mac_policy_unregister(struct mac_policy_conf *mpc);
2112742Swollman
2122742Swollmanstatic int	mac_stdcreatevnode_ea(struct vnode *vp);
21314343Swollmanstatic void	mac_cred_mmapped_drop_perms(struct thread *td,
214169811Swollman		    struct ucred *cred);
2152742Swollmanstatic void	mac_cred_mmapped_drop_perms_recurse(struct thread *td,
21614343Swollman		    struct ucred *cred, struct vm_map *map);
21714343Swollman
218169811SwollmanMALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector");
21914343SwollmanMALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes");
22030711Swollman
22130711Swollman/*
22258787Sru * mac_policy_list_lock protects the consistency of 'mac_policy_list',
223169811Swollman * the linked list of attached policy modules.  Read-only consumers of
2242742Swollman * the list must acquire a shared lock for the duration of their use;
22543014Swollman * writers must acquire an exclusive lock.  Note that for compound
22643014Swollman * operations, locks should be held for the entire compound operation,
22743014Swollman * and that this is not yet done for relabel requests.
22843014Swollman */
2292742Swollmanstatic struct mtx mac_policy_list_lock;
2302742Swollmanstatic LIST_HEAD(, mac_policy_conf) mac_policy_list;
231158421Swollmanstatic int mac_policy_list_busy;
2322742Swollman#define	MAC_POLICY_LIST_LOCKINIT()	mtx_init(&mac_policy_list_lock,	\
23319878Swollman	"mac_policy_list_lock", NULL, MTX_DEF);
23443014Swollman#define	MAC_POLICY_LIST_LOCK()	mtx_lock(&mac_policy_list_lock);
23543014Swollman#define	MAC_POLICY_LIST_UNLOCK()	mtx_unlock(&mac_policy_list_lock);
2362742Swollman
2372742Swollman#define	MAC_POLICY_LIST_BUSY() do {					\
23819878Swollman	MAC_POLICY_LIST_LOCK();						\
23919878Swollman	mac_policy_list_busy++;						\
2402742Swollman	MAC_POLICY_LIST_UNLOCK();					\
2412742Swollman} while (0)
242149514Swollman
243149514Swollman#define	MAC_POLICY_LIST_UNBUSY() do {					\
2442742Swollman	MAC_POLICY_LIST_LOCK();						\
245149514Swollman	mac_policy_list_busy--;						\
246149514Swollman	if (mac_policy_list_busy < 0)					\
2472742Swollman		panic("Extra mac_policy_list_busy--");			\
2482742Swollman	MAC_POLICY_LIST_UNLOCK();					\
249199336Sedwin} while (0)
250199336Sedwin
251199336Sedwin/*
252199336Sedwin * MAC_CHECK performs the designated check by walking the policy
253199336Sedwin * module list and checking with each as to how it feels about the
254199336Sedwin * request.  Note that it returns its value via 'error' in the scope
255199336Sedwin * of the caller.
256199336Sedwin */
257199336Sedwin#define	MAC_CHECK(check, args...) do {					\
258199336Sedwin	struct mac_policy_conf *mpc;					\
259199336Sedwin									\
260199336Sedwin	error = 0;							\
261199336Sedwin	MAC_POLICY_LIST_BUSY();						\
262199336Sedwin	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {			\
263199336Sedwin		if (mpc->mpc_ops->mpo_ ## check != NULL)		\
264199336Sedwin			error = error_select(				\
265199336Sedwin			    mpc->mpc_ops->mpo_ ## check (args),		\
266199336Sedwin			    error);					\
267199336Sedwin	}								\
268204887Sedwin	MAC_POLICY_LIST_UNBUSY();					\
269204887Sedwin} while (0)
270204887Sedwin
271204887Sedwin/*
272204887Sedwin * MAC_BOOLEAN performs the designated boolean composition by walking
273204887Sedwin * the module list, invoking each instance of the operation, and
274204887Sedwin * combining the results using the passed C operator.  Note that it
275204887Sedwin * returns its value via 'result' in the scope of the caller, which
276204887Sedwin * should be initialized by the caller in a meaningful way to get
277204887Sedwin * a meaningful result.
278204887Sedwin */
279204887Sedwin#define	MAC_BOOLEAN(operation, composition, args...) do {		\
280204887Sedwin	struct mac_policy_conf *mpc;					\
281204887Sedwin									\
282204887Sedwin	MAC_POLICY_LIST_BUSY();						\
283204887Sedwin	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {			\
284204887Sedwin		if (mpc->mpc_ops->mpo_ ## operation != NULL)		\
285214722Sedwin			result = result composition			\
286240457Sedwin			    mpc->mpc_ops->mpo_ ## operation (args);	\
287214722Sedwin	}								\
288240457Sedwin	MAC_POLICY_LIST_UNBUSY();					\
289214722Sedwin} while (0)
290214722Sedwin
291214722Sedwin/*
292214722Sedwin * MAC_PERFORM performs the designated operation by walking the policy
293214722Sedwin * module list and invoking that operation for each policy.
294214722Sedwin */
295214722Sedwin#define	MAC_PERFORM(operation, args...) do {				\
296214722Sedwin	struct mac_policy_conf *mpc;					\
297214722Sedwin									\
298226289Sedwin	MAC_POLICY_LIST_BUSY();						\
299240457Sedwin	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {			\
300226289Sedwin		if (mpc->mpc_ops->mpo_ ## operation != NULL)		\
301226289Sedwin			mpc->mpc_ops->mpo_ ## operation (args);		\
302226289Sedwin	}								\
303226289Sedwin	MAC_POLICY_LIST_UNBUSY();					\
304226289Sedwin} while (0)
305226289Sedwin
306240457Sedwin/*
307240457Sedwin * Initialize the MAC subsystem, including appropriate SMP locks.
308226289Sedwin */
309226289Sedwinstatic void
310226976Sedwinmac_init(void)
311226976Sedwin{
312226976Sedwin
313226976Sedwin	LIST_INIT(&mac_policy_list);
314226976Sedwin	MAC_POLICY_LIST_LOCKINIT();
315226976Sedwin}
316226976Sedwin
317226976Sedwin/*
318226976Sedwin * For the purposes of modules that want to know if they were loaded
319226976Sedwin * "early", set the mac_late flag once we've processed modules either
320226976Sedwin * linked into the kernel, or loaded before the kernel startup.
321226976Sedwin */
322226976Sedwinstatic void
323226976Sedwinmac_late_init(void)
324240457Sedwin{
325240457Sedwin
326240457Sedwin	mac_late = 1;
327240457Sedwin}
328240457Sedwin
329240457Sedwin/*
330240457Sedwin * Allow MAC policy modules to register during boot, etc.
331240457Sedwin */
332240457Sedwinint
33343543Swollmanmac_policy_modevent(module_t mod, int type, void *data)
33475267Swollman{
33575267Swollman	struct mac_policy_conf *mpc;
336199336Sedwin	int error;
337204887Sedwin
338240457Sedwin	error = 0;
339214722Sedwin	mpc = (struct mac_policy_conf *) data;
340240457Sedwin
3412742Swollman	switch (type) {
3422742Swollman	case MOD_LOAD:
34343543Swollman		if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE &&
3442742Swollman		    mac_late) {
3452742Swollman			printf("mac_policy_modevent: can't load %s policy "
3462742Swollman			    "after booting\n", mpc->mpc_name);
3472742Swollman			error = EBUSY;
34819878Swollman			break;
3492742Swollman		}
35019878Swollman		error = mac_policy_register(mpc);
3512742Swollman		break;
35219878Swollman	case MOD_UNLOAD:
35343014Swollman		/* Don't unregister the module if it was never registered. */
35443014Swollman		if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED)
3552742Swollman		    != 0)
3562742Swollman			error = mac_policy_unregister(mpc);
3572742Swollman		else
35875267Swollman			error = 0;
35975267Swollman		break;
36075267Swollman	default:
36175267Swollman		break;
3622742Swollman	}
3632742Swollman
3642742Swollman	return (error);
3652742Swollman}
36619878Swollman
3672742Swollmanstatic int
36819878Swollmanmac_policy_register(struct mac_policy_conf *mpc)
36919878Swollman{
37019878Swollman	struct mac_policy_conf *tmpc;
3712742Swollman	struct mac_policy_op_entry *mpe;
37219878Swollman	int slot;
37319878Swollman
37419878Swollman	MALLOC(mpc->mpc_ops, struct mac_policy_ops *, sizeof(*mpc->mpc_ops),
3752742Swollman	    M_MACOPVEC, M_WAITOK | M_ZERO);
37614343Swollman	for (mpe = mpc->mpc_entries; mpe->mpe_constant != MAC_OP_LAST; mpe++) {
37714343Swollman		switch (mpe->mpe_constant) {
37875267Swollman		case MAC_OP_LAST:
37975267Swollman			/*
38019878Swollman			 * Doesn't actually happen, but this allows checking
38175267Swollman			 * that all enumerated values are handled.
38275267Swollman			 */
38314343Swollman			break;
38414343Swollman		case MAC_DESTROY:
38514343Swollman			mpc->mpc_ops->mpo_destroy =
38614343Swollman			    mpe->mpe_function;
38719878Swollman			break;
38819878Swollman		case MAC_INIT:
38914343Swollman			mpc->mpc_ops->mpo_init =
39019878Swollman			    mpe->mpe_function;
39119878Swollman			break;
39219878Swollman		case MAC_SYSCALL:
39314343Swollman			mpc->mpc_ops->mpo_syscall =
39414343Swollman			    mpe->mpe_function;
39514343Swollman			break;
396210718Sedwin		case MAC_INIT_BPFDESC:
397210718Sedwin			mpc->mpc_ops->mpo_init_bpfdesc =
398210718Sedwin			    mpe->mpe_function;
399210718Sedwin			break;
40014343Swollman		case MAC_INIT_CRED:
40158787Sru			mpc->mpc_ops->mpo_init_cred =
40258787Sru			    mpe->mpe_function;
40358787Sru			break;
40414343Swollman		case MAC_INIT_DEVFSDIRENT:
4052742Swollman			mpc->mpc_ops->mpo_init_devfsdirent =
4062742Swollman			    mpe->mpe_function;
4072742Swollman			break;
40819878Swollman		case MAC_INIT_IFNET:
4092742Swollman			mpc->mpc_ops->mpo_init_ifnet =
41019878Swollman			    mpe->mpe_function;
41119878Swollman			break;
4122742Swollman		case MAC_INIT_IPQ:
4132742Swollman			mpc->mpc_ops->mpo_init_ipq =
4142742Swollman			    mpe->mpe_function;
41519878Swollman			break;
41619878Swollman		case MAC_INIT_MBUF:
41743014Swollman			mpc->mpc_ops->mpo_init_mbuf =
418158421Swollman			    mpe->mpe_function;
41943014Swollman			break;
4202742Swollman		case MAC_INIT_MOUNT:
4212742Swollman			mpc->mpc_ops->mpo_init_mount =
4222742Swollman			    mpe->mpe_function;
4232742Swollman			break;
4242742Swollman		case MAC_INIT_PIPE:
4252742Swollman			mpc->mpc_ops->mpo_init_pipe =
4262742Swollman			    mpe->mpe_function;
4272742Swollman			break;
4282742Swollman		case MAC_INIT_SOCKET:
4292742Swollman			mpc->mpc_ops->mpo_init_socket =
430121098Swollman			    mpe->mpe_function;
431121098Swollman			break;
432121098Swollman		case MAC_INIT_TEMP:
433121098Swollman			mpc->mpc_ops->mpo_init_temp =
434121098Swollman			    mpe->mpe_function;
435121098Swollman			break;
436121098Swollman		case MAC_INIT_VNODE:
437121098Swollman			mpc->mpc_ops->mpo_init_vnode =
438121098Swollman			    mpe->mpe_function;
439114173Swollman			break;
440121098Swollman		case MAC_DESTROY_BPFDESC:
441114173Swollman			mpc->mpc_ops->mpo_destroy_bpfdesc =
442121098Swollman			    mpe->mpe_function;
4439908Swollman			break;
444121098Swollman		case MAC_DESTROY_CRED:
445114173Swollman			mpc->mpc_ops->mpo_destroy_cred =
446121098Swollman			    mpe->mpe_function;
447114173Swollman			break;
448121098Swollman		case MAC_DESTROY_DEVFSDIRENT:
449169811Swollman			mpc->mpc_ops->mpo_destroy_devfsdirent =
450169811Swollman			    mpe->mpe_function;
451169811Swollman			break;
452169811Swollman		case MAC_DESTROY_IFNET:
453169811Swollman			mpc->mpc_ops->mpo_destroy_ifnet =
454169811Swollman			    mpe->mpe_function;
455169811Swollman			break;
456169811Swollman		case MAC_DESTROY_IPQ:
4572742Swollman			mpc->mpc_ops->mpo_destroy_ipq =
458114173Swollman			    mpe->mpe_function;
459121098Swollman			break;
4602742Swollman		case MAC_DESTROY_MBUF:
461121098Swollman			mpc->mpc_ops->mpo_destroy_mbuf =
462121098Swollman			    mpe->mpe_function;
4632742Swollman			break;
4648029Swollman		case MAC_DESTROY_MOUNT:
46530711Swollman			mpc->mpc_ops->mpo_destroy_mount =
46658787Sru			    mpe->mpe_function;
46758787Sru			break;
4682742Swollman		case MAC_DESTROY_PIPE:
46930711Swollman			mpc->mpc_ops->mpo_destroy_pipe =
47058787Sru			    mpe->mpe_function;
47158787Sru			break;
47258787Sru		case MAC_DESTROY_SOCKET:
47330711Swollman			mpc->mpc_ops->mpo_destroy_socket =
47430711Swollman			    mpe->mpe_function;
4752742Swollman			break;
4762742Swollman		case MAC_DESTROY_TEMP:
4772742Swollman			mpc->mpc_ops->mpo_destroy_temp =
4782742Swollman			    mpe->mpe_function;
4792742Swollman			break;
4802742Swollman		case MAC_DESTROY_VNODE:
48119878Swollman			mpc->mpc_ops->mpo_destroy_vnode =
48219878Swollman			    mpe->mpe_function;
48319878Swollman			break;
4842742Swollman		case MAC_EXTERNALIZE:
4852742Swollman			mpc->mpc_ops->mpo_externalize =
4862742Swollman			    mpe->mpe_function;
4872742Swollman			break;
48819878Swollman		case MAC_INTERNALIZE:
48919878Swollman			mpc->mpc_ops->mpo_internalize =
4902742Swollman			    mpe->mpe_function;
49158787Sru			break;
4929908Swollman		case MAC_CREATE_DEVFS_DEVICE:
4939908Swollman			mpc->mpc_ops->mpo_create_devfs_device =
49419878Swollman			    mpe->mpe_function;
4959908Swollman			break;
4962742Swollman		case MAC_CREATE_DEVFS_DIRECTORY:
4972742Swollman			mpc->mpc_ops->mpo_create_devfs_directory =
4982742Swollman			    mpe->mpe_function;
49986222Swollman			break;
50019878Swollman		case MAC_CREATE_DEVFS_VNODE:
5012742Swollman			mpc->mpc_ops->mpo_create_devfs_vnode =
5022742Swollman			    mpe->mpe_function;
5032742Swollman			break;
5042742Swollman		case MAC_STDCREATEVNODE_EA:
50558787Sru			mpc->mpc_ops->mpo_stdcreatevnode_ea =
50658787Sru			    mpe->mpe_function;
5072742Swollman			break;
50814343Swollman		case MAC_CREATE_VNODE:
50914343Swollman			mpc->mpc_ops->mpo_create_vnode =
51014343Swollman			    mpe->mpe_function;
51119878Swollman			break;
51214343Swollman		case MAC_CREATE_MOUNT:
51314343Swollman			mpc->mpc_ops->mpo_create_mount =
51414343Swollman			    mpe->mpe_function;
51514343Swollman			break;
516149514Swollman		case MAC_CREATE_ROOT_MOUNT:
517196582Sedwin			mpc->mpc_ops->mpo_create_root_mount =
518204887Sedwin			    mpe->mpe_function;
519204887Sedwin			break;
520204887Sedwin		case MAC_RELABEL_VNODE:
521197000Sedwin			mpc->mpc_ops->mpo_relabel_vnode =
522204887Sedwin			    mpe->mpe_function;
523204887Sedwin			break;
524204887Sedwin		case MAC_UPDATE_DEVFSDIRENT:
525204887Sedwin			mpc->mpc_ops->mpo_update_devfsdirent =
526204887Sedwin			    mpe->mpe_function;
527197000Sedwin			break;
528197000Sedwin		case MAC_UPDATE_PROCFSVNODE:
529197000Sedwin			mpc->mpc_ops->mpo_update_procfsvnode =
530198270Sedwin			    mpe->mpe_function;
531204887Sedwin			break;
532204887Sedwin		case MAC_UPDATE_VNODE_FROM_EXTATTR:
533204887Sedwin			mpc->mpc_ops->mpo_update_vnode_from_extattr =
534204887Sedwin			    mpe->mpe_function;
535204887Sedwin			break;
536198270Sedwin		case MAC_UPDATE_VNODE_FROM_EXTERNALIZED:
537226289Sedwin			mpc->mpc_ops->mpo_update_vnode_from_externalized =
538214722Sedwin			    mpe->mpe_function;
539214722Sedwin			break;
540214722Sedwin		case MAC_UPDATE_VNODE_FROM_MOUNT:
541214722Sedwin			mpc->mpc_ops->mpo_update_vnode_from_mount =
542214722Sedwin			    mpe->mpe_function;
543214722Sedwin			break;
544214722Sedwin		case MAC_CREATE_MBUF_FROM_SOCKET:
545214722Sedwin			mpc->mpc_ops->mpo_create_mbuf_from_socket =
546214722Sedwin			    mpe->mpe_function;
547226289Sedwin			break;
548219687Sedwin		case MAC_CREATE_PIPE:
549219687Sedwin			mpc->mpc_ops->mpo_create_pipe =
550219687Sedwin			    mpe->mpe_function;
551219687Sedwin			break;
552219687Sedwin		case MAC_CREATE_SOCKET:
553219687Sedwin			mpc->mpc_ops->mpo_create_socket =
554219687Sedwin			    mpe->mpe_function;
555219687Sedwin			break;
556219687Sedwin		case MAC_CREATE_SOCKET_FROM_SOCKET:
557219687Sedwin			mpc->mpc_ops->mpo_create_socket_from_socket =
558219687Sedwin			    mpe->mpe_function;
559219687Sedwin			break;
560219687Sedwin		case MAC_RELABEL_PIPE:
561219687Sedwin			mpc->mpc_ops->mpo_relabel_pipe =
562219687Sedwin			    mpe->mpe_function;
563219687Sedwin			break;
564219687Sedwin		case MAC_RELABEL_SOCKET:
565219687Sedwin			mpc->mpc_ops->mpo_relabel_socket =
566219687Sedwin			    mpe->mpe_function;
567226289Sedwin			break;
568226289Sedwin		case MAC_SET_SOCKET_PEER_FROM_MBUF:
569240457Sedwin			mpc->mpc_ops->mpo_set_socket_peer_from_mbuf =
570226289Sedwin			    mpe->mpe_function;
571226289Sedwin			break;
572226289Sedwin		case MAC_SET_SOCKET_PEER_FROM_SOCKET:
573226289Sedwin			mpc->mpc_ops->mpo_set_socket_peer_from_socket =
574226289Sedwin			    mpe->mpe_function;
575226289Sedwin			break;
576226289Sedwin		case MAC_CREATE_BPFDESC:
577226289Sedwin			mpc->mpc_ops->mpo_create_bpfdesc =
578226289Sedwin			    mpe->mpe_function;
579226289Sedwin			break;
580226289Sedwin		case MAC_CREATE_DATAGRAM_FROM_IPQ:
581226289Sedwin			mpc->mpc_ops->mpo_create_datagram_from_ipq =
582226289Sedwin			    mpe->mpe_function;
583226289Sedwin			break;
584226289Sedwin		case MAC_CREATE_FRAGMENT:
585226289Sedwin			mpc->mpc_ops->mpo_create_fragment =
586226289Sedwin			    mpe->mpe_function;
587226289Sedwin			break;
588226289Sedwin		case MAC_CREATE_IFNET:
589226289Sedwin			mpc->mpc_ops->mpo_create_ifnet =
590226289Sedwin			    mpe->mpe_function;
591226289Sedwin			break;
592226289Sedwin		case MAC_CREATE_IPQ:
593226289Sedwin			mpc->mpc_ops->mpo_create_ipq =
594226289Sedwin			    mpe->mpe_function;
595226289Sedwin			break;
596226289Sedwin		case MAC_CREATE_MBUF_FROM_MBUF:
597226289Sedwin			mpc->mpc_ops->mpo_create_mbuf_from_mbuf =
598226289Sedwin			    mpe->mpe_function;
599226289Sedwin			break;
600226289Sedwin		case MAC_CREATE_MBUF_LINKLAYER:
601226289Sedwin			mpc->mpc_ops->mpo_create_mbuf_linklayer =
602226289Sedwin			    mpe->mpe_function;
603226289Sedwin			break;
604226289Sedwin		case MAC_CREATE_MBUF_FROM_BPFDESC:
605226289Sedwin			mpc->mpc_ops->mpo_create_mbuf_from_bpfdesc =
606226289Sedwin			    mpe->mpe_function;
607226289Sedwin			break;
608226289Sedwin		case MAC_CREATE_MBUF_FROM_IFNET:
609226289Sedwin			mpc->mpc_ops->mpo_create_mbuf_from_ifnet =
610226289Sedwin			    mpe->mpe_function;
611226289Sedwin			break;
612226289Sedwin		case MAC_CREATE_MBUF_MULTICAST_ENCAP:
613226289Sedwin			mpc->mpc_ops->mpo_create_mbuf_multicast_encap =
614226289Sedwin			    mpe->mpe_function;
615226289Sedwin			break;
616226289Sedwin		case MAC_CREATE_MBUF_NETLAYER:
617226289Sedwin			mpc->mpc_ops->mpo_create_mbuf_netlayer =
618226289Sedwin			    mpe->mpe_function;
619226289Sedwin			break;
620226289Sedwin		case MAC_FRAGMENT_MATCH:
621226289Sedwin			mpc->mpc_ops->mpo_fragment_match =
622226289Sedwin			    mpe->mpe_function;
623226289Sedwin			break;
624226289Sedwin		case MAC_RELABEL_IFNET:
625226289Sedwin			mpc->mpc_ops->mpo_relabel_ifnet =
626233445Sedwin			    mpe->mpe_function;
627233445Sedwin			break;
628233445Sedwin		case MAC_UPDATE_IPQ:
629233445Sedwin			mpc->mpc_ops->mpo_update_ipq =
630233445Sedwin			    mpe->mpe_function;
63114343Swollman			break;
63214343Swollman		case MAC_CREATE_CRED:
63319878Swollman			mpc->mpc_ops->mpo_create_cred =
634205475Sedwin			    mpe->mpe_function;
635219687Sedwin			break;
636226289Sedwin		case MAC_EXECVE_TRANSITION:
637226289Sedwin			mpc->mpc_ops->mpo_execve_transition =
638226289Sedwin			    mpe->mpe_function;
639226289Sedwin			break;
64014343Swollman		case MAC_EXECVE_WILL_TRANSITION:
6412742Swollman			mpc->mpc_ops->mpo_execve_will_transition =
6422742Swollman			    mpe->mpe_function;
6432742Swollman			break;
6442742Swollman		case MAC_CREATE_PROC0:
64519878Swollman			mpc->mpc_ops->mpo_create_proc0 = mpe->mpe_function;
6462742Swollman			break;
6472742Swollman		case MAC_CREATE_PROC1:
648233445Sedwin			mpc->mpc_ops->mpo_create_proc1 = mpe->mpe_function;
649233445Sedwin			break;
650233445Sedwin		case MAC_RELABEL_CRED:
651240457Sedwin			mpc->mpc_ops->mpo_relabel_cred =
652233445Sedwin			    mpe->mpe_function;
653240457Sedwin			break;
654240457Sedwin		case MAC_CHECK_BPFDESC_RECEIVE:
655240457Sedwin			mpc->mpc_ops->mpo_check_bpfdesc_receive =
656240457Sedwin			    mpe->mpe_function;
657240457Sedwin			break;
658233445Sedwin		case MAC_CHECK_CRED_RELABEL:
659240457Sedwin			mpc->mpc_ops->mpo_check_cred_relabel =
660240457Sedwin			    mpe->mpe_function;
661240457Sedwin			break;
662240457Sedwin		case MAC_CHECK_CRED_VISIBLE:
663240457Sedwin			mpc->mpc_ops->mpo_check_cred_visible =
664240457Sedwin			    mpe->mpe_function;
665233445Sedwin			break;
6662742Swollman		case MAC_CHECK_IFNET_RELABEL:
6672742Swollman			mpc->mpc_ops->mpo_check_ifnet_relabel =
668240457Sedwin			    mpe->mpe_function;
669240457Sedwin			break;
6702742Swollman		case MAC_CHECK_IFNET_TRANSMIT:
6712742Swollman			mpc->mpc_ops->mpo_check_ifnet_transmit =
67258787Sru			    mpe->mpe_function;
67375267Swollman			break;
67475267Swollman		case MAC_CHECK_MOUNT_STAT:
675114173Swollman			mpc->mpc_ops->mpo_check_mount_stat =
676114173Swollman			    mpe->mpe_function;
6772742Swollman			break;
6782742Swollman		case MAC_CHECK_PIPE_IOCTL:
67958787Sru			mpc->mpc_ops->mpo_check_pipe_ioctl =
68058787Sru			    mpe->mpe_function;
68158787Sru			break;
6822742Swollman		case MAC_CHECK_PIPE_POLL:
6832742Swollman			mpc->mpc_ops->mpo_check_pipe_poll =
6842742Swollman			    mpe->mpe_function;
6852742Swollman			break;
68619878Swollman		case MAC_CHECK_PIPE_READ:
6872742Swollman			mpc->mpc_ops->mpo_check_pipe_read =
68843014Swollman			    mpe->mpe_function;
68943014Swollman			break;
69043014Swollman		case MAC_CHECK_PIPE_RELABEL:
69143014Swollman			mpc->mpc_ops->mpo_check_pipe_relabel =
692171948Sedwin			    mpe->mpe_function;
693171948Sedwin			break;
694171948Sedwin		case MAC_CHECK_PIPE_STAT:
695171948Sedwin			mpc->mpc_ops->mpo_check_pipe_stat =
696171948Sedwin			    mpe->mpe_function;
697171948Sedwin			break;
698171948Sedwin		case MAC_CHECK_PIPE_WRITE:
699171948Sedwin			mpc->mpc_ops->mpo_check_pipe_write =
700171948Sedwin			    mpe->mpe_function;
70143014Swollman			break;
70243014Swollman		case MAC_CHECK_PROC_DEBUG:
703171948Sedwin			mpc->mpc_ops->mpo_check_proc_debug =
704171948Sedwin			    mpe->mpe_function;
705171948Sedwin			break;
70643014Swollman		case MAC_CHECK_PROC_SCHED:
70743014Swollman			mpc->mpc_ops->mpo_check_proc_sched =
70843014Swollman			    mpe->mpe_function;
70943014Swollman			break;
71043014Swollman		case MAC_CHECK_PROC_SIGNAL:
71143014Swollman			mpc->mpc_ops->mpo_check_proc_signal =
71243014Swollman			    mpe->mpe_function;
71343014Swollman			break;
71443014Swollman		case MAC_CHECK_SOCKET_BIND:
71543014Swollman			mpc->mpc_ops->mpo_check_socket_bind =
716149514Swollman			    mpe->mpe_function;
717149514Swollman			break;
718149514Swollman		case MAC_CHECK_SOCKET_CONNECT:
719149514Swollman			mpc->mpc_ops->mpo_check_socket_connect =
720149514Swollman			    mpe->mpe_function;
721149514Swollman			break;
722149514Swollman		case MAC_CHECK_SOCKET_DELIVER:
723149514Swollman			mpc->mpc_ops->mpo_check_socket_deliver =
724149514Swollman			    mpe->mpe_function;
725149514Swollman			break;
726149514Swollman		case MAC_CHECK_SOCKET_LISTEN:
72743014Swollman			mpc->mpc_ops->mpo_check_socket_listen =
728121098Swollman			    mpe->mpe_function;
729121098Swollman			break;
73043014Swollman		case MAC_CHECK_SOCKET_RELABEL:
73143014Swollman			mpc->mpc_ops->mpo_check_socket_relabel =
73243014Swollman			    mpe->mpe_function;
73343014Swollman			break;
73443014Swollman		case MAC_CHECK_SOCKET_VISIBLE:
73543014Swollman			mpc->mpc_ops->mpo_check_socket_visible =
73643014Swollman			    mpe->mpe_function;
73743014Swollman			break;
73843014Swollman		case MAC_CHECK_VNODE_ACCESS:
73943014Swollman			mpc->mpc_ops->mpo_check_vnode_access =
74043014Swollman			    mpe->mpe_function;
74143014Swollman			break;
74243014Swollman		case MAC_CHECK_VNODE_CHDIR:
7432742Swollman			mpc->mpc_ops->mpo_check_vnode_chdir =
7442742Swollman			    mpe->mpe_function;
74519878Swollman			break;
74619878Swollman		case MAC_CHECK_VNODE_CHROOT:
74719878Swollman			mpc->mpc_ops->mpo_check_vnode_chroot =
74820094Swollman			    mpe->mpe_function;
74920094Swollman			break;
75020094Swollman		case MAC_CHECK_VNODE_CREATE:
7512742Swollman			mpc->mpc_ops->mpo_check_vnode_create =
7522742Swollman			    mpe->mpe_function;
75319878Swollman			break;
7542742Swollman		case MAC_CHECK_VNODE_DELETE:
7552742Swollman			mpc->mpc_ops->mpo_check_vnode_delete =
7562742Swollman			    mpe->mpe_function;
7572742Swollman			break;
75819878Swollman		case MAC_CHECK_VNODE_DELETEACL:
7592742Swollman			mpc->mpc_ops->mpo_check_vnode_deleteacl =
7602742Swollman			    mpe->mpe_function;
7612742Swollman			break;
7622742Swollman		case MAC_CHECK_VNODE_EXEC:
7632742Swollman			mpc->mpc_ops->mpo_check_vnode_exec =
7642742Swollman			    mpe->mpe_function;
7652742Swollman			break;
7662742Swollman		case MAC_CHECK_VNODE_GETACL:
7672742Swollman			mpc->mpc_ops->mpo_check_vnode_getacl =
768158421Swollman			    mpe->mpe_function;
7692742Swollman			break;
770158421Swollman		case MAC_CHECK_VNODE_GETEXTATTR:
771158421Swollman			mpc->mpc_ops->mpo_check_vnode_getextattr =
7722742Swollman			    mpe->mpe_function;
77386222Swollman			break;
77420094Swollman		case MAC_CHECK_VNODE_LOOKUP:
77520094Swollman			mpc->mpc_ops->mpo_check_vnode_lookup =
77620094Swollman			    mpe->mpe_function;
77720094Swollman			break;
77820094Swollman		case MAC_CHECK_VNODE_MMAP_PERMS:
779158421Swollman			mpc->mpc_ops->mpo_check_vnode_mmap_perms =
780158421Swollman			    mpe->mpe_function;
78120094Swollman			break;
7822742Swollman		case MAC_CHECK_VNODE_OPEN:
7832742Swollman			mpc->mpc_ops->mpo_check_vnode_open =
7842742Swollman			    mpe->mpe_function;
7852742Swollman			break;
7862742Swollman		case MAC_CHECK_VNODE_POLL:
78758787Sru			mpc->mpc_ops->mpo_check_vnode_poll =
7882742Swollman			    mpe->mpe_function;
7892742Swollman			break;
7902742Swollman		case MAC_CHECK_VNODE_READ:
7912742Swollman			mpc->mpc_ops->mpo_check_vnode_read =
7922742Swollman			    mpe->mpe_function;
7932742Swollman			break;
7942742Swollman		case MAC_CHECK_VNODE_READDIR:
795169811Swollman			mpc->mpc_ops->mpo_check_vnode_readdir =
7962742Swollman			    mpe->mpe_function;
7972742Swollman			break;
7982742Swollman		case MAC_CHECK_VNODE_READLINK:
79975267Swollman			mpc->mpc_ops->mpo_check_vnode_readlink =
8002742Swollman			    mpe->mpe_function;
801121098Swollman			break;
802121098Swollman		case MAC_CHECK_VNODE_RELABEL:
80319878Swollman			mpc->mpc_ops->mpo_check_vnode_relabel =
8042742Swollman			    mpe->mpe_function;
80514343Swollman			break;
80658787Sru		case MAC_CHECK_VNODE_RENAME_FROM:
8072742Swollman			mpc->mpc_ops->mpo_check_vnode_rename_from =
80814343Swollman			    mpe->mpe_function;
8099908Swollman			break;
8102742Swollman		case MAC_CHECK_VNODE_RENAME_TO:
8112742Swollman			mpc->mpc_ops->mpo_check_vnode_rename_to =
8122742Swollman			    mpe->mpe_function;
8132742Swollman			break;
8142742Swollman		case MAC_CHECK_VNODE_REVOKE:
815153670Swollman			mpc->mpc_ops->mpo_check_vnode_revoke =
816153670Swollman			    mpe->mpe_function;
817153670Swollman			break;
818153670Swollman		case MAC_CHECK_VNODE_SETACL:
81958787Sru			mpc->mpc_ops->mpo_check_vnode_setacl =
820153670Swollman			    mpe->mpe_function;
821153670Swollman			break;
822153670Swollman		case MAC_CHECK_VNODE_SETEXTATTR:
823153670Swollman			mpc->mpc_ops->mpo_check_vnode_setextattr =
824153670Swollman			    mpe->mpe_function;
82519878Swollman			break;
8262742Swollman		case MAC_CHECK_VNODE_SETFLAGS:
8272742Swollman			mpc->mpc_ops->mpo_check_vnode_setflags =
8282742Swollman			    mpe->mpe_function;
8292742Swollman			break;
8302742Swollman		case MAC_CHECK_VNODE_SETMODE:
8312742Swollman			mpc->mpc_ops->mpo_check_vnode_setmode =
8322742Swollman			    mpe->mpe_function;
8332742Swollman			break;
8342742Swollman		case MAC_CHECK_VNODE_SETOWNER:
8352742Swollman			mpc->mpc_ops->mpo_check_vnode_setowner =
8362742Swollman			    mpe->mpe_function;
8372742Swollman			break;
8382742Swollman		case MAC_CHECK_VNODE_SETUTIMES:
8392742Swollman			mpc->mpc_ops->mpo_check_vnode_setutimes =
8402742Swollman			    mpe->mpe_function;
8412742Swollman			break;
8422742Swollman		case MAC_CHECK_VNODE_STAT:
84386222Swollman			mpc->mpc_ops->mpo_check_vnode_stat =
8442742Swollman			    mpe->mpe_function;
8452742Swollman			break;
8462742Swollman		case MAC_CHECK_VNODE_WRITE:
8472742Swollman			mpc->mpc_ops->mpo_check_vnode_write =
8482742Swollman			    mpe->mpe_function;
849163302Sru			break;
850163302Sru/*
851163302Sru		default:
852163302Sru			printf("MAC policy `%s': unknown operation %d\n",
853163302Sru			    mpc->mpc_name, mpe->mpe_constant);
854163302Sru			return (EINVAL);
85586222Swollman*/
85686222Swollman		}
85786222Swollman	}
85886222Swollman	MAC_POLICY_LIST_LOCK();
85986222Swollman	if (mac_policy_list_busy > 0) {
86086222Swollman		MAC_POLICY_LIST_UNLOCK();
86186222Swollman		FREE(mpc->mpc_ops, M_MACOPVEC);
86286222Swollman		mpc->mpc_ops = NULL;
86386222Swollman		return (EBUSY);
86486222Swollman	}
86586222Swollman	LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) {
86686222Swollman		if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) {
86786222Swollman			MAC_POLICY_LIST_UNLOCK();
86886222Swollman			FREE(mpc->mpc_ops, M_MACOPVEC);
86986222Swollman			mpc->mpc_ops = NULL;
87086222Swollman			return (EEXIST);
87186222Swollman		}
87286222Swollman	}
87386222Swollman	if (mpc->mpc_field_off != NULL) {
87486222Swollman		slot = ffs(mac_policy_offsets_free);
87586222Swollman		if (slot == 0) {
87686222Swollman			MAC_POLICY_LIST_UNLOCK();
87786222Swollman			FREE(mpc->mpc_ops, M_MACOPVEC);
87886222Swollman			mpc->mpc_ops = NULL;
87986222Swollman			return (ENOMEM);
88086222Swollman		}
88186222Swollman		slot--;
88286222Swollman		mac_policy_offsets_free &= ~(1 << slot);
88386222Swollman		*mpc->mpc_field_off = slot;
88486222Swollman	}
88586222Swollman	mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED;
88686222Swollman	LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list);
88786222Swollman
88886222Swollman	/* Per-policy initialization. */
88986222Swollman	if (mpc->mpc_ops->mpo_init != NULL)
89086222Swollman		(*(mpc->mpc_ops->mpo_init))(mpc);
89186222Swollman	MAC_POLICY_LIST_UNLOCK();
89286222Swollman
89386222Swollman	printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname,
89486222Swollman	    mpc->mpc_name);
89586222Swollman
89686222Swollman	return (0);
89786222Swollman}
89886222Swollman
89986222Swollmanstatic int
90086222Swollmanmac_policy_unregister(struct mac_policy_conf *mpc)
90186222Swollman{
90286222Swollman
90386222Swollman#if 0
90486222Swollman	/*
90586222Swollman	 * Don't allow unloading modules with private data.
90686222Swollman	 */
90786222Swollman	if (mpc->mpc_field_off != NULL)
90886222Swollman		return (EBUSY);
90986222Swollman#endif
91086222Swollman	if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0)
91186222Swollman		return (EBUSY);
91286222Swollman	MAC_POLICY_LIST_LOCK();
91386222Swollman	if (mac_policy_list_busy > 0) {
91486222Swollman		MAC_POLICY_LIST_UNLOCK();
91586222Swollman		return (EBUSY);
91686222Swollman	}
91786222Swollman	if (mpc->mpc_ops->mpo_destroy != NULL)
91886222Swollman		(*(mpc->mpc_ops->mpo_destroy))(mpc);
91986222Swollman
92086222Swollman	LIST_REMOVE(mpc, mpc_list);
92186222Swollman	MAC_POLICY_LIST_UNLOCK();
92286222Swollman
92386222Swollman	FREE(mpc->mpc_ops, M_MACOPVEC);
92486222Swollman	mpc->mpc_ops = NULL;
92586222Swollman
92686222Swollman	printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname,
92786222Swollman	    mpc->mpc_name);
92886222Swollman
92986222Swollman	return (0);
93086222Swollman}
93186222Swollman
93286222Swollman/*
93386222Swollman * Define an error value precedence, and given two arguments, selects the
93486222Swollman * value with the higher precedence.
93586222Swollman */
93614343Swollmanstatic int
937158421Swollmanerror_select(int error1, int error2)
938149514Swollman{
9399908Swollman
9409908Swollman	/* Certain decision-making errors take top priority. */
9419908Swollman	if (error1 == EDEADLK || error2 == EDEADLK)
94214343Swollman		return (EDEADLK);
9432742Swollman
944149514Swollman	/* Invalid arguments should be reported where possible. */
94575267Swollman	if (error1 == EINVAL || error2 == EINVAL)
94643014Swollman		return (EINVAL);
94743014Swollman
94843014Swollman	/* Precedence goes to "visibility", with both process and file. */
94975267Swollman	if (error1 == ESRCH || error2 == ESRCH)
95043014Swollman		return (ESRCH);
95143014Swollman
95243014Swollman	if (error1 == ENOENT || error2 == ENOENT)
95343014Swollman		return (ENOENT);
95443014Swollman
95558787Sru	/* Precedence goes to DAC/MAC protections. */
95643014Swollman	if (error1 == EACCES || error2 == EACCES)
95743014Swollman		return (EACCES);
95843014Swollman
95943014Swollman	/* Precedence goes to privilege. */
96043014Swollman	if (error1 == EPERM || error2 == EPERM)
96143014Swollman		return (EPERM);
96243014Swollman
963149514Swollman	/* Precedence goes to error over success; otherwise, arbitrary. */
964149514Swollman	if (error1 != 0)
965149514Swollman		return (error1);
966149514Swollman	return (error2);
967149514Swollman}
968149514Swollman
969149514Swollmanvoid
970149514Swollmanmac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp)
971149514Swollman{
972149514Swollman
973149514Swollman	MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label);
974149514Swollman}
975149514Swollman
976149514Swollmanvoid
977149514Swollmanmac_update_procfsvnode(struct vnode *vp, struct ucred *cred)
978149514Swollman{
979149514Swollman
980149514Swollman	MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred);
9819908Swollman}
9829908Swollman
98319878Swollman/*
9842742Swollman * Support callout for policies that manage their own externalization
9852742Swollman * using extended attributes.
9862742Swollman */
9872742Swollmanstatic int
9889908Swollmanmac_update_vnode_from_extattr(struct vnode *vp, struct mount *mp)
9892742Swollman{
99019878Swollman	int error;
9912742Swollman
9922742Swollman	MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp,
9932742Swollman	    &mp->mnt_fslabel);
9949908Swollman
9952742Swollman	return (error);
99619878Swollman}
9972742Swollman
9982742Swollman/*
9992742Swollman * Given an externalized mac label, internalize it and stamp it on a
10002742Swollman * vnode.
10012742Swollman */
10022742Swollmanstatic int
10032742Swollmanmac_update_vnode_from_externalized(struct vnode *vp, struct mac *extmac)
10042742Swollman{
10052742Swollman	int error;
10062742Swollman
10072742Swollman	MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac);
10082742Swollman
10092742Swollman	return (error);
10102742Swollman}
101119878Swollman
10122742Swollman/*
10132742Swollman * Call out to individual policies to update the label in a vnode from
10142742Swollman * the mountpoint.
101519878Swollman */
10162742Swollmanvoid
10172742Swollmanmac_update_vnode_from_mount(struct vnode *vp, struct mount *mp)
10182742Swollman{
10192742Swollman
10202742Swollman	MAC_PERFORM(update_vnode_from_mount, vp, &vp->v_label, mp,
10212742Swollman	    &mp->mnt_fslabel);
102219878Swollman
10232742Swollman	ASSERT_VOP_LOCKED(vp, "mac_update_vnode_from_mount");
10242742Swollman	if (mac_cache_fslabel_in_vnode)
10252742Swollman		vp->v_vflag |= VV_CACHEDLABEL;
102658787Sru}
102758787Sru
102858787Sru/*
102958787Sru * Implementation of VOP_REFRESHLABEL() that relies on extended attributes
103058787Sru * to store label data.  Can be referenced by filesystems supporting
10319908Swollman * extended attributes.
103219878Swollman */
10332742Swollmanint
10342742Swollmanvop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap)
10352742Swollman{
10362742Swollman	struct vnode *vp = ap->a_vp;
10372742Swollman	struct mac extmac;
10382742Swollman	int buflen, error;
10392742Swollman
10402742Swollman	ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea");
10412742Swollman
10422742Swollman	/*
104319878Swollman	 * Call out to external policies first.  Order doesn't really
10442742Swollman	 * matter, as long as failure of one assures failure of all.
10452742Swollman	 */
10462742Swollman	error = mac_update_vnode_from_extattr(vp, vp->v_mount);
104719878Swollman	if (error)
10482742Swollman		return (error);
10492742Swollman
10502742Swollman	buflen = sizeof(extmac);
10512742Swollman	error = vn_extattr_get(vp, IO_NODELOCKED,
105219878Swollman	    FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, &buflen,
10532742Swollman	    (char *)&extmac, curthread);
10542742Swollman	switch (error) {
10552742Swollman	case 0:
10562742Swollman		/* Got it */
105719878Swollman		break;
10582742Swollman
10592742Swollman	case ENOATTR:
10602742Swollman		/*
10612742Swollman		 * Use the label from the mount point.
10622742Swollman		 */
10632742Swollman		mac_update_vnode_from_mount(vp, vp->v_mount);
10642742Swollman		return (0);
106519878Swollman
10662742Swollman	case EOPNOTSUPP:
10672742Swollman	default:
1068169811Swollman		/* Fail horribly. */
1069169811Swollman		return (error);
1070169811Swollman	}
1071169811Swollman
1072169811Swollman	if (buflen != sizeof(extmac))
1073105196Swollman		error = EPERM;		/* Fail very closed. */
1074114173Swollman	if (error == 0)
1075169811Swollman		error = mac_update_vnode_from_externalized(vp, &extmac);
1076114173Swollman	if (error == 0)
1077114173Swollman		vp->v_vflag |= VV_CACHEDLABEL;
1078114173Swollman	else {
1079114173Swollman		struct vattr va;
1080169811Swollman
1081105196Swollman		printf("Corrupted label on %s",
1082105196Swollman		    vp->v_mount->mnt_stat.f_mntonname);
1083105196Swollman		if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread) == 0)
1084105196Swollman			printf(" inum %ld", va.va_fileid);
1085169811Swollman		if (mac_debug_label_fallback) {
1086105196Swollman			printf(", falling back.\n");
1087169811Swollman			mac_update_vnode_from_mount(vp, vp->v_mount);
1088169811Swollman			error = 0;
1089169811Swollman		} else {
1090169811Swollman			printf(".\n");
1091105196Swollman			error = EPERM;
1092169811Swollman		}
1093169811Swollman	}
1094169811Swollman
1095169811Swollman	return (error);
1096169811Swollman}
1097169811Swollman
1098169811Swollman/*
1099169811Swollman * Make sure the vnode label is up-to-date.  If EOPNOTSUPP, then we handle
1100169811Swollman * the labeling activity outselves.  Filesystems should be careful not
1101169811Swollman * to change their minds regarding whether they support vop_refreshlabel()
1102169811Swollman * for a vnode or not.  Don't cache the vnode here, allow the file
1103169811Swollman * system code to determine if it's safe to cache.  If we update from
1104169811Swollman * the mount, don't cache since a change to the mount label should affect
1105169811Swollman * all vnodes.
1106169811Swollman */
1107169811Swollmanstatic int
1108105196Swollmanvn_refreshlabel(struct vnode *vp, struct ucred *cred)
1109169811Swollman{
1110169811Swollman	int error;
1111169811Swollman
1112169811Swollman	ASSERT_VOP_LOCKED(vp, "vn_refreshlabel");
1113169811Swollman
1114171948Sedwin	if (vp->v_mount == NULL) {
11152742Swollman/*
1116171948Sedwin		Eventually, we probably want to special-case refreshing
1117171948Sedwin		of deadfs vnodes, and if there's a lock-free race somewhere,
1118171948Sedwin		that case might be handled here.
1119171948Sedwin
11202742Swollman		mac_update_vnode_deadfs(vp);
11212742Swollman		return (0);
11229908Swollman */
11232742Swollman		/* printf("vn_refreshlabel: null v_mount\n"); */
112419878Swollman		if (vp->v_type != VNON)
11252742Swollman			printf(
11262742Swollman			    "vn_refreshlabel: null v_mount with non-VNON\n");
11272742Swollman		return (EBADF);
11282742Swollman	}
112919878Swollman
11302742Swollman	if (vp->v_vflag & VV_CACHEDLABEL) {
11312742Swollman		mac_vnode_label_cache_hits++;
11322742Swollman		return (0);
11332742Swollman	} else
11342742Swollman		mac_vnode_label_cache_misses++;
11352742Swollman
11362742Swollman	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
1137158421Swollman		mac_update_vnode_from_mount(vp, vp->v_mount);
11382742Swollman		return (0);
11392742Swollman	}
114019878Swollman
11412742Swollman	error = VOP_REFRESHLABEL(vp, cred, curthread);
11422742Swollman	switch (error) {
11432742Swollman	case EOPNOTSUPP:
11442742Swollman		/*
114519878Swollman		 * If labels are not supported on this vnode, fall back to
11462742Swollman		 * the label in the mount and propagate it to the vnode.
11472742Swollman		 * There should probably be some sort of policy/flag/decision
11482742Swollman		 * about doing this.
11492742Swollman		 */
11502742Swollman		mac_update_vnode_from_mount(vp, vp->v_mount);
115119878Swollman		error = 0;
11522742Swollman	default:
11532742Swollman		return (error);
11542742Swollman	}
11552742Swollman}
115619878Swollman
11572742Swollman/*
11582742Swollman * Helper function for file systems using the vop_std*_ea() calls.  This
11592742Swollman * function must be called after EA service is available for the vnode,
11602742Swollman * but before it's hooked up to the namespace so that the node persists
1161149514Swollman * if there's a crash, or before it can be accessed.  On successful
11629908Swollman * commit of the label to disk (etc), do cache the label.
11639908Swollman */
11649908Swollmanint
11652742Swollmanvop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp, struct ucred *cred)
1166171948Sedwin{
1167171948Sedwin	struct mac extmac;
1168171948Sedwin	int error;
11699908Swollman
11709908Swollman	ASSERT_VOP_LOCKED(tvp, "vop_stdcreatevnode_ea");
117158787Sru	if ((dvp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
117258787Sru		mac_update_vnode_from_mount(tvp, tvp->v_mount);
11732742Swollman	} else {
11742742Swollman		error = vn_refreshlabel(dvp, cred);
11752742Swollman		if (error)
117619878Swollman			return (error);
11772742Swollman
11782742Swollman		/*
11792742Swollman		 * Stick the label in the vnode.  Then try to write to
11802742Swollman		 * disk.  If we fail, return a failure to abort the
118158787Sru		 * create operation.  Really, this failure shouldn't
118258787Sru		 * happen except in fairly unusual circumstances (out
118358787Sru		 * of disk, etc).
118458787Sru		 */
118558787Sru		mac_create_vnode(cred, dvp, tvp);
118658787Sru
118758787Sru		error = mac_stdcreatevnode_ea(tvp);
118864499Swollman		if (error)
118964499Swollman			return (error);
119064499Swollman
1191171948Sedwin		/*
1192171948Sedwin		 * XXX: Eventually this will go away and all policies will
1193171948Sedwin		 * directly manage their extended attributes.
11949908Swollman		 */
11952742Swollman		error = mac_externalize(&tvp->v_label, &extmac);
119658787Sru		if (error)
119758787Sru			return (error);
11982742Swollman
11992742Swollman		error = vn_extattr_set(tvp, IO_NODELOCKED,
12002742Swollman		    FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
120186222Swollman		    sizeof(extmac), (char *)&extmac, curthread);
120286222Swollman		if (error == 0)
120386222Swollman			tvp->v_vflag |= VV_CACHEDLABEL;
120486222Swollman		else {
120586222Swollman#if 0
120686222Swollman			/*
120786222Swollman			 * In theory, we could have fall-back behavior here.
120886222Swollman			 * It would probably be incorrect.
120986222Swollman			 */
121086222Swollman#endif
121186222Swollman			return (error);
121286222Swollman		}
121386222Swollman	}
121486222Swollman
121586222Swollman	return (0);
121686222Swollman}
121786222Swollman
121886222Swollmanvoid
121986222Swollmanmac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp)
122086222Swollman{
122186222Swollman	int error;
122286222Swollman
1223171948Sedwin	ASSERT_VOP_LOCKED(vp, "mac_execve_transition");
1224171948Sedwin
1225171948Sedwin	error = vn_refreshlabel(vp, old);
12269908Swollman	if (error) {
12272742Swollman		printf("mac_execve_transition: vn_refreshlabel returned %d\n",
12282742Swollman		    error);
12292742Swollman		printf("mac_execve_transition: using old vnode label\n");
1230149514Swollman	}
12312742Swollman
12322742Swollman	MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label);
12332742Swollman}
12342742Swollman
12352742Swollmanint
12362742Swollmanmac_execve_will_transition(struct ucred *old, struct vnode *vp)
12372742Swollman{
12382742Swollman	int error, result;
1239149514Swollman
124058787Sru	error = vn_refreshlabel(vp, old);
124158787Sru	if (error)
124258787Sru		return (error);
124358787Sru
124458787Sru	result = 0;
124558787Sru	MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label);
12462742Swollman
124758787Sru	return (result);
124858787Sru}
124958787Sru
125058787Srustatic void
125158787Srumac_init_label(struct label *label)
125258787Sru{
125358787Sru
125458787Sru	bzero(label, sizeof(*label));
125558787Sru	label->l_flags = MAC_FLAG_INITIALIZED;
125658787Sru}
125758787Sru
125858787Srustatic void
125958787Srumac_init_structmac(struct mac *mac)
126058787Sru{
126158787Sru
126258787Sru	bzero(mac, sizeof(*mac));
126358787Sru	mac->m_macflags = MAC_FLAG_INITIALIZED;
126458787Sru}
126558787Sru
126658787Srustatic void
126758787Srumac_destroy_label(struct label *label)
126858787Sru{
126958787Sru
127058787Sru	KASSERT(label->l_flags & MAC_FLAG_INITIALIZED,
127158787Sru	    ("destroying uninitialized label"));
127258787Sru
127358787Sru	bzero(label, sizeof(*label));
127458787Sru	/* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */
127558787Sru}
127675267Swollman
127758787Sruint
127858787Srumac_init_mbuf(struct mbuf *m, int how)
127958787Sru{
128058787Sru	KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf"));
128158787Sru
128258787Sru	/* "how" is one of M_(TRY|DONT)WAIT */
12832742Swollman	mac_init_label(&m->m_pkthdr.label);
128443543Swollman	MAC_PERFORM(init_mbuf, m, how, &m->m_pkthdr.label);
128543543Swollman#ifdef MAC_DEBUG
128658787Sru	atomic_add_int(&nmacmbufs, 1);
128743543Swollman#endif
128867578Swollman	return (0);
128975267Swollman}
129075267Swollman
129167578Swollmanvoid
1292171948Sedwinmac_destroy_mbuf(struct mbuf *m)
1293171948Sedwin{
1294171948Sedwin
12959908Swollman	MAC_PERFORM(destroy_mbuf, m, &m->m_pkthdr.label);
12962742Swollman	mac_destroy_label(&m->m_pkthdr.label);
129767578Swollman#ifdef MAC_DEBUG
12982742Swollman	atomic_subtract_int(&nmacmbufs, 1);
12992742Swollman#endif
130019878Swollman}
13012742Swollman
13022742Swollmanvoid
13032742Swollmanmac_init_cred(struct ucred *cr)
130443014Swollman{
13052742Swollman
13062742Swollman	mac_init_label(&cr->cr_label);
13072742Swollman	MAC_PERFORM(init_cred, cr, &cr->cr_label);
13082742Swollman#ifdef MAC_DEBUG
13092742Swollman	atomic_add_int(&nmaccreds, 1);
13102742Swollman#endif
13112742Swollman}
13122742Swollman
13132742Swollmanvoid
13142742Swollmanmac_destroy_cred(struct ucred *cr)
13152742Swollman{
13169908Swollman
13172742Swollman	MAC_PERFORM(destroy_cred, cr, &cr->cr_label);
131819878Swollman	mac_destroy_label(&cr->cr_label);
1319153670Swollman#ifdef MAC_DEBUG
13202742Swollman	atomic_subtract_int(&nmaccreds, 1);
13212742Swollman#endif
13222742Swollman}
13232742Swollman
132458787Sruvoid
132558787Srumac_init_ifnet(struct ifnet *ifp)
132658787Sru{
132758787Sru
132858787Sru	mac_init_label(&ifp->if_label);
132958787Sru	MAC_PERFORM(init_ifnet, ifp, &ifp->if_label);
1330226289Sedwin#ifdef MAC_DEBUG
133158787Sru	atomic_add_int(&nmacifnets, 1);
133258787Sru#endif
133358787Sru}
133414343Swollman
133575267Swollmanvoid
133675267Swollmanmac_destroy_ifnet(struct ifnet *ifp)
133775267Swollman{
133875267Swollman
133975267Swollman	MAC_PERFORM(destroy_ifnet, ifp, &ifp->if_label);
134075267Swollman	mac_destroy_label(&ifp->if_label);
134158787Sru#ifdef MAC_DEBUG
1342158421Swollman	atomic_subtract_int(&nmacifnets, 1);
1343158421Swollman#endif
1344158421Swollman}
134567578Swollman
1346171948Sedwinvoid
1347171948Sedwinmac_init_ipq(struct ipq *ipq)
1348171948Sedwin{
1349192886Sedwin
1350240457Sedwin	mac_init_label(&ipq->ipq_label);
1351240457Sedwin	MAC_PERFORM(init_ipq, ipq, &ipq->ipq_label);
1352192886Sedwin#ifdef MAC_DEBUG
1353240457Sedwin	atomic_add_int(&nmacipqs, 1);
1354192886Sedwin#endif
1355192886Sedwin}
1356192886Sedwin
1357192886Sedwinvoid
1358240457Sedwinmac_destroy_ipq(struct ipq *ipq)
1359192886Sedwin{
1360240457Sedwin
1361192886Sedwin	MAC_PERFORM(destroy_ipq, ipq, &ipq->ipq_label);
1362240457Sedwin	mac_destroy_label(&ipq->ipq_label);
1363240457Sedwin#ifdef MAC_DEBUG
1364192886Sedwin	atomic_subtract_int(&nmacipqs, 1);
1365240457Sedwin#endif
1366192886Sedwin}
1367192886Sedwin
1368192886Sedwinvoid
1369192886Sedwinmac_init_socket(struct socket *socket)
13702742Swollman{
13712742Swollman
137258787Sru	mac_init_label(&socket->so_label);
13732742Swollman	mac_init_label(&socket->so_peerlabel);
137419878Swollman	MAC_PERFORM(init_socket, socket, &socket->so_label,
13752742Swollman	    &socket->so_peerlabel);
13762742Swollman#ifdef MAC_DEBUG
13772742Swollman	atomic_add_int(&nmacsockets, 1);
13782742Swollman#endif
13792742Swollman}
138019878Swollman
13812742Swollmanvoid
13822742Swollmanmac_destroy_socket(struct socket *socket)
1383153670Swollman{
13842742Swollman
13852742Swollman	MAC_PERFORM(destroy_socket, socket, &socket->so_label,
13862742Swollman	    &socket->so_peerlabel);
13872742Swollman	mac_destroy_label(&socket->so_label);
13882742Swollman	mac_destroy_label(&socket->so_peerlabel);
13892742Swollman#ifdef MAC_DEBUG
13902742Swollman	atomic_subtract_int(&nmacsockets, 1);
13912742Swollman#endif
13922742Swollman}
13932742Swollman
139419878Swollmanvoid
13952742Swollmanmac_init_pipe(struct pipe *pipe)
13962742Swollman{
13972742Swollman	struct label *label;
139814343Swollman
1399158421Swollman	label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK);
1400149514Swollman	mac_init_label(label);
140114343Swollman	pipe->pipe_label = label;
140214343Swollman	pipe->pipe_peer->pipe_label = label;
140314343Swollman	MAC_PERFORM(init_pipe, pipe, pipe->pipe_label);
140414343Swollman#ifdef MAC_DEBUG
1405158421Swollman	atomic_add_int(&nmacpipes, 1);
1406121098Swollman#endif
1407121098Swollman}
1408158421Swollman
1409121098Swollmanvoid
1410121098Swollmanmac_destroy_pipe(struct pipe *pipe)
1411121098Swollman{
1412121098Swollman
141314343Swollman	MAC_PERFORM(destroy_pipe, pipe, pipe->pipe_label);
1414169811Swollman	mac_destroy_label(pipe->pipe_label);
1415169811Swollman	free(pipe->pipe_label, M_MACPIPELABEL);
1416169811Swollman#ifdef MAC_DEBUG
1417169811Swollman	atomic_subtract_int(&nmacpipes, 1);
1418169811Swollman#endif
1419169811Swollman}
14202742Swollman
14212742Swollmanvoid
142258787Srumac_init_bpfdesc(struct bpf_d *bpf_d)
14232742Swollman{
14242742Swollman
142558787Sru	mac_init_label(&bpf_d->bd_label);
142658787Sru	MAC_PERFORM(init_bpfdesc, bpf_d, &bpf_d->bd_label);
142758787Sru#ifdef MAC_DEBUG
14282742Swollman	atomic_add_int(&nmacbpfdescs, 1);
142943543Swollman#endif
143043543Swollman}
143175267Swollman
143243543Swollmanvoid
143343543Swollmanmac_destroy_bpfdesc(struct bpf_d *bpf_d)
143458787Sru{
143558787Sru
143658787Sru	MAC_PERFORM(destroy_bpfdesc, bpf_d, &bpf_d->bd_label);
143743543Swollman	mac_destroy_label(&bpf_d->bd_label);
143843543Swollman#ifdef MAC_DEBUG
143943543Swollman	atomic_subtract_int(&nmacbpfdescs, 1);
144043543Swollman#endif
144143543Swollman}
144243543Swollman
144343543Swollmanvoid
144475267Swollmanmac_init_mount(struct mount *mp)
144575267Swollman{
144658787Sru
144714343Swollman	mac_init_label(&mp->mnt_mntlabel);
144814343Swollman	mac_init_label(&mp->mnt_fslabel);
144914343Swollman	MAC_PERFORM(init_mount, mp, &mp->mnt_mntlabel, &mp->mnt_fslabel);
145014343Swollman#ifdef MAC_DEBUG
145158787Sru	atomic_add_int(&nmacmounts, 1);
145217200Swollman#endif
145317200Swollman}
145417200Swollman
145517200Swollmanvoid
1456226289Sedwinmac_destroy_mount(struct mount *mp)
145717200Swollman{
145817200Swollman
145958787Sru	MAC_PERFORM(destroy_mount, mp, &mp->mnt_mntlabel, &mp->mnt_fslabel);
14602742Swollman	mac_destroy_label(&mp->mnt_fslabel);
14612742Swollman	mac_destroy_label(&mp->mnt_mntlabel);
14622742Swollman#ifdef MAC_DEBUG
14632742Swollman	atomic_subtract_int(&nmacmounts, 1);
146419878Swollman#endif
14652742Swollman}
14662742Swollman
14672742Swollmanstatic void
146858787Srumac_init_temp(struct label *label)
146914343Swollman{
14702742Swollman
147158787Sru	mac_init_label(label);
14722742Swollman	MAC_PERFORM(init_temp, label);
14732742Swollman#ifdef MAC_DEBUG
147475267Swollman	atomic_add_int(&nmactemp, 1);
147575267Swollman#endif
147614343Swollman}
147775267Swollman
147875267Swollmanstatic void
147975267Swollmanmac_destroy_temp(struct label *label)
148075267Swollman{
148158787Sru
148275267Swollman	MAC_PERFORM(destroy_temp, label);
148317200Swollman	mac_destroy_label(label);
148417200Swollman#ifdef MAC_DEBUG
1485149514Swollman	atomic_subtract_int(&nmactemp, 1);
148617200Swollman#endif
148717200Swollman}
148817200Swollman
1489158421Swollmanvoid
1490158421Swollmanmac_init_vnode(struct vnode *vp)
149117200Swollman{
149258787Sru
149358787Sru	mac_init_label(&vp->v_label);
149458787Sru	MAC_PERFORM(init_vnode, vp, &vp->v_label);
149558787Sru#ifdef MAC_DEBUG
149658787Sru	atomic_add_int(&nmacvnodes, 1);
149758787Sru#endif
149858787Sru}
149958787Sru
150058787Sruvoid
1501121098Swollmanmac_destroy_vnode(struct vnode *vp)
1502121098Swollman{
1503121098Swollman
1504121098Swollman	MAC_PERFORM(destroy_vnode, vp, &vp->v_label);
1505121098Swollman	mac_destroy_label(&vp->v_label);
1506121098Swollman#ifdef MAC_DEBUG
1507121098Swollman	atomic_subtract_int(&nmacvnodes, 1);
1508121098Swollman#endif
1509121098Swollman}
1510121098Swollman
1511121098Swollmanvoid
1512121098Swollmanmac_init_devfsdirent(struct devfs_dirent *de)
1513121098Swollman{
1514121098Swollman
1515121098Swollman	mac_init_label(&de->de_label);
1516121098Swollman	MAC_PERFORM(init_devfsdirent, de, &de->de_label);
1517121098Swollman#ifdef MAC_DEBUG
151858787Sru	atomic_add_int(&nmacdevfsdirents, 1);
151958787Sru#endif
152058787Sru}
152158787Sru
152258787Sruvoid
152358787Srumac_destroy_devfsdirent(struct devfs_dirent *de)
152458787Sru{
152558787Sru
152658787Sru	MAC_PERFORM(destroy_devfsdirent, de, &de->de_label);
152758787Sru	mac_destroy_label(&de->de_label);
152858787Sru#ifdef MAC_DEBUG
152958787Sru	atomic_subtract_int(&nmacdevfsdirents, 1);
153058787Sru#endif
153158787Sru}
153258787Sru
153358787Srustatic int
153458787Srumac_externalize(struct label *label, struct mac *mac)
153558787Sru{
153658787Sru	int error;
153758787Sru
153858787Sru	mac_init_structmac(mac);
153958787Sru	MAC_CHECK(externalize, label, mac);
154058787Sru
154158787Sru	return (error);
154214343Swollman}
154314343Swollman
154458787Srustatic int
154558787Srumac_internalize(struct label *label, struct mac *mac)
154614343Swollman{
154714343Swollman	int error;
154814343Swollman
154917200Swollman	mac_init_temp(label);
155058787Sru	MAC_CHECK(internalize, label, mac);
155117200Swollman	if (error)
155217200Swollman		mac_destroy_temp(label);
155317200Swollman
155417200Swollman	return (error);
155517200Swollman}
155617200Swollman
155758787Sru/*
155858787Sru * Initialize MAC label for the first kernel process, from which other
155958787Sru * kernel processes and threads are spawned.
156058787Sru */
156158787Sruvoid
156258787Srumac_create_proc0(struct ucred *cred)
156358787Sru{
156458787Sru
156558787Sru	MAC_PERFORM(create_proc0, cred);
156658787Sru}
156758787Sru
156858787Sru/*
156958787Sru * Initialize MAC label for the first userland process, from which other
157058787Sru * userland processes and threads are spawned.
157158787Sru */
157258787Sruvoid
157358787Srumac_create_proc1(struct ucred *cred)
157458787Sru{
157558787Sru
157658787Sru	MAC_PERFORM(create_proc1, cred);
157758787Sru}
157858787Sru
157958787Sru/*
158058787Sru * When a new process is created, its label must be initialized.  Generally,
158158787Sru * this involves inheritence from the parent process, modulo possible
158258787Sru * deltas.  This function allows that processing to take place.
1583158421Swollman */
1584158421Swollmanvoid
158558787Srumac_create_cred(struct ucred *parent_cred, struct ucred *child_cred)
158658787Sru{
158758787Sru
158858787Sru	MAC_PERFORM(create_cred, parent_cred, child_cred);
158958787Sru}
159058787Sru
159158787Sruint
159258787Srumac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags)
1593149514Swollman{
159458787Sru	int error;
159575267Swollman
1596149514Swollman	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access");
1597181421Sedwin
159858787Sru	if (!mac_enforce_fs)
159958787Sru		return (0);
160075267Swollman
160158787Sru	error = vn_refreshlabel(vp, cred);
160258787Sru	if (error)
160358787Sru		return (error);
160458787Sru
160558787Sru	MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags);
1606149514Swollman	return (error);
1607181421Sedwin}
160858787Sru
160958787Sruint
161075267Swollmanmac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp)
161175267Swollman{
161275267Swollman	int error;
161375267Swollman
161458787Sru	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir");
161558787Sru
161658787Sru	if (!mac_enforce_fs)
161758787Sru		return (0);
161858787Sru
161958787Sru	error = vn_refreshlabel(dvp, cred);
162058787Sru	if (error)
162175267Swollman		return (error);
162275267Swollman
162375267Swollman	MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label);
162475267Swollman	return (error);
162575267Swollman}
162675267Swollman
162775267Swollmanint
162858787Srumac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp)
162975267Swollman{
163075267Swollman	int error;
163175267Swollman
163293799Swollman	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot");
163393799Swollman
163493799Swollman	if (!mac_enforce_fs)
163593799Swollman		return (0);
163693799Swollman
163786222Swollman	error = vn_refreshlabel(dvp, cred);
1638114173Swollman	if (error)
1639114173Swollman		return (error);
164086222Swollman
1641121098Swollman	MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label);
1642121098Swollman	return (error);
1643121098Swollman}
1644121098Swollman
1645121098Swollmanint
1646121098Swollmanmac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
1647121098Swollman    struct componentname *cnp, struct vattr *vap)
1648121098Swollman{
1649121098Swollman	int error;
1650121098Swollman
1651121098Swollman	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create");
1652121098Swollman
1653121098Swollman	if (!mac_enforce_fs)
1654121098Swollman		return (0);
1655121098Swollman
1656121098Swollman	error = vn_refreshlabel(dvp, cred);
1657121098Swollman	if (error)
1658121098Swollman		return (error);
165958787Sru
166058787Sru	MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap);
166158787Sru	return (error);
166258787Sru}
166358787Sru
166475267Swollmanint
166558787Srumac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp,
166658787Sru    struct componentname *cnp)
166758787Sru{
166858787Sru	int error;
166958787Sru
167058787Sru	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete");
167158787Sru	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete");
167258787Sru
167358787Sru	if (!mac_enforce_fs)
167458787Sru		return (0);
167558787Sru
1676153670Swollman	error = vn_refreshlabel(dvp, cred);
167758787Sru	if (error)
167858787Sru		return (error);
167958787Sru	error = vn_refreshlabel(vp, cred);
168058787Sru	if (error)
1681149514Swollman		return (error);
1682153670Swollman
1683153670Swollman	MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp,
1684153670Swollman	    &vp->v_label, cnp);
1685153670Swollman	return (error);
1686153670Swollman}
1687153670Swollman
1688153670Swollmanint
1689153670Swollmanmac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
1690153670Swollman    acl_type_t type)
1691153670Swollman{
1692153670Swollman	int error;
1693153670Swollman
1694153670Swollman	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl");
1695153670Swollman
1696149514Swollman	if (!mac_enforce_fs)
1697149514Swollman		return (0);
1698149514Swollman
1699149514Swollman	error = vn_refreshlabel(vp, cred);
1700149514Swollman	if (error)
1701149514Swollman		return (error);
1702149514Swollman
1703	MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type);
1704	return (error);
1705}
1706
1707int
1708mac_check_vnode_exec(struct ucred *cred, struct vnode *vp)
1709{
1710	int error;
1711
1712	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec");
1713
1714	if (!mac_enforce_process && !mac_enforce_fs)
1715		return (0);
1716
1717	error = vn_refreshlabel(vp, cred);
1718	if (error)
1719		return (error);
1720	MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label);
1721
1722	return (error);
1723}
1724
1725int
1726mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
1727{
1728	int error;
1729
1730	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl");
1731
1732	if (!mac_enforce_fs)
1733		return (0);
1734
1735	error = vn_refreshlabel(vp, cred);
1736	if (error)
1737		return (error);
1738
1739	MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type);
1740	return (error);
1741}
1742
1743int
1744mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
1745    int attrnamespace, const char *name, struct uio *uio)
1746{
1747	int error;
1748
1749	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr");
1750
1751	if (!mac_enforce_fs)
1752		return (0);
1753
1754	error = vn_refreshlabel(vp, cred);
1755	if (error)
1756		return (error);
1757
1758	MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label,
1759	    attrnamespace, name, uio);
1760	return (error);
1761}
1762
1763int
1764mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
1765    struct componentname *cnp)
1766{
1767	int error;
1768
1769	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup");
1770
1771	if (!mac_enforce_fs)
1772		return (0);
1773
1774	error = vn_refreshlabel(dvp, cred);
1775	if (error)
1776		return (error);
1777
1778	MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp);
1779	return (error);
1780}
1781
1782vm_prot_t
1783mac_check_vnode_mmap_prot(struct ucred *cred, struct vnode *vp, int newmapping)
1784{
1785	vm_prot_t result = VM_PROT_ALL;
1786
1787	if (!mac_enforce_vm)
1788		return (result);
1789
1790	/*
1791	 * This should be some sort of MAC_BITWISE, maybe :)
1792	 */
1793	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_perms");
1794	MAC_BOOLEAN(check_vnode_mmap_perms, &, cred, vp, &vp->v_label,
1795	    newmapping);
1796	return (result);
1797}
1798
1799int
1800mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode)
1801{
1802	int error;
1803
1804	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open");
1805
1806	if (!mac_enforce_fs)
1807		return (0);
1808
1809	error = vn_refreshlabel(vp, cred);
1810	if (error)
1811		return (error);
1812
1813	MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode);
1814	return (error);
1815}
1816
1817int
1818mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
1819    struct vnode *vp)
1820{
1821	int error;
1822
1823	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll");
1824
1825	if (!mac_enforce_fs)
1826		return (0);
1827
1828	error = vn_refreshlabel(vp, active_cred);
1829	if (error)
1830		return (error);
1831
1832	MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp,
1833	    &vp->v_label);
1834
1835	return (error);
1836}
1837
1838int
1839mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
1840    struct vnode *vp)
1841{
1842	int error;
1843
1844	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read");
1845
1846	if (!mac_enforce_fs)
1847		return (0);
1848
1849	error = vn_refreshlabel(vp, active_cred);
1850	if (error)
1851		return (error);
1852
1853	MAC_CHECK(check_vnode_read, active_cred, file_cred, vp,
1854	    &vp->v_label);
1855
1856	return (error);
1857}
1858
1859int
1860mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp)
1861{
1862	int error;
1863
1864	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir");
1865
1866	if (!mac_enforce_fs)
1867		return (0);
1868
1869	error = vn_refreshlabel(dvp, cred);
1870	if (error)
1871		return (error);
1872
1873	MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label);
1874	return (error);
1875}
1876
1877int
1878mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp)
1879{
1880	int error;
1881
1882	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink");
1883
1884	if (!mac_enforce_fs)
1885		return (0);
1886
1887	error = vn_refreshlabel(vp, cred);
1888	if (error)
1889		return (error);
1890
1891	MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label);
1892	return (error);
1893}
1894
1895static int
1896mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
1897    struct label *newlabel)
1898{
1899	int error;
1900
1901	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel");
1902
1903	error = vn_refreshlabel(vp, cred);
1904	if (error)
1905		return (error);
1906
1907	MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel);
1908
1909	return (error);
1910}
1911
1912int
1913mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
1914    struct vnode *vp, struct componentname *cnp)
1915{
1916	int error;
1917
1918	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from");
1919	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from");
1920
1921	if (!mac_enforce_fs)
1922		return (0);
1923
1924	error = vn_refreshlabel(dvp, cred);
1925	if (error)
1926		return (error);
1927	error = vn_refreshlabel(vp, cred);
1928	if (error)
1929		return (error);
1930
1931	MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp,
1932	    &vp->v_label, cnp);
1933	return (error);
1934}
1935
1936int
1937mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
1938    struct vnode *vp, int samedir, struct componentname *cnp)
1939{
1940	int error;
1941
1942	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to");
1943	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to");
1944
1945	if (!mac_enforce_fs)
1946		return (0);
1947
1948	error = vn_refreshlabel(dvp, cred);
1949	if (error)
1950		return (error);
1951	if (vp != NULL) {
1952		error = vn_refreshlabel(vp, cred);
1953		if (error)
1954			return (error);
1955	}
1956	MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp,
1957	    vp != NULL ? &vp->v_label : NULL, samedir, cnp);
1958	return (error);
1959}
1960
1961int
1962mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp)
1963{
1964	int error;
1965
1966	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke");
1967
1968	if (!mac_enforce_fs)
1969		return (0);
1970
1971	error = vn_refreshlabel(vp, cred);
1972	if (error)
1973		return (error);
1974
1975	MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label);
1976	return (error);
1977}
1978
1979int
1980mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
1981    struct acl *acl)
1982{
1983	int error;
1984
1985	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl");
1986
1987	if (!mac_enforce_fs)
1988		return (0);
1989
1990	error = vn_refreshlabel(vp, cred);
1991	if (error)
1992		return (error);
1993
1994	MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl);
1995	return (error);
1996}
1997
1998int
1999mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2000    int attrnamespace, const char *name, struct uio *uio)
2001{
2002	int error;
2003
2004	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr");
2005
2006	if (!mac_enforce_fs)
2007		return (0);
2008
2009	error = vn_refreshlabel(vp, cred);
2010	if (error)
2011		return (error);
2012
2013	MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label,
2014	    attrnamespace, name, uio);
2015	return (error);
2016}
2017
2018int
2019mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
2020{
2021	int error;
2022
2023	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags");
2024
2025	if (!mac_enforce_fs)
2026		return (0);
2027
2028	error = vn_refreshlabel(vp, cred);
2029	if (error)
2030		return (error);
2031
2032	MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags);
2033	return (error);
2034}
2035
2036int
2037mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
2038{
2039	int error;
2040
2041	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode");
2042
2043	if (!mac_enforce_fs)
2044		return (0);
2045
2046	error = vn_refreshlabel(vp, cred);
2047	if (error)
2048		return (error);
2049
2050	MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode);
2051	return (error);
2052}
2053
2054int
2055mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
2056    gid_t gid)
2057{
2058	int error;
2059
2060	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner");
2061
2062	if (!mac_enforce_fs)
2063		return (0);
2064
2065	error = vn_refreshlabel(vp, cred);
2066	if (error)
2067		return (error);
2068
2069	MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid);
2070	return (error);
2071}
2072
2073int
2074mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2075    struct timespec atime, struct timespec mtime)
2076{
2077	int error;
2078
2079	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes");
2080
2081	if (!mac_enforce_fs)
2082		return (0);
2083
2084	error = vn_refreshlabel(vp, cred);
2085	if (error)
2086		return (error);
2087
2088	MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime,
2089	    mtime);
2090	return (error);
2091}
2092
2093int
2094mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2095    struct vnode *vp)
2096{
2097	int error;
2098
2099	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat");
2100
2101	if (!mac_enforce_fs)
2102		return (0);
2103
2104	error = vn_refreshlabel(vp, active_cred);
2105	if (error)
2106		return (error);
2107
2108	MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp,
2109	    &vp->v_label);
2110	return (error);
2111}
2112
2113int
2114mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
2115    struct vnode *vp)
2116{
2117	int error;
2118
2119	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write");
2120
2121	if (!mac_enforce_fs)
2122		return (0);
2123
2124	error = vn_refreshlabel(vp, active_cred);
2125	if (error)
2126		return (error);
2127
2128	MAC_CHECK(check_vnode_write, active_cred, file_cred, vp,
2129	    &vp->v_label);
2130
2131	return (error);
2132}
2133
2134/*
2135 * When relabeling a process, call out to the policies for the maximum
2136 * permission allowed for each object type we know about in its
2137 * memory space, and revoke access (in the least surprising ways we
2138 * know) when necessary.  The process lock is not held here.
2139 */
2140static void
2141mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred)
2142{
2143
2144	/* XXX freeze all other threads */
2145	mac_cred_mmapped_drop_perms_recurse(td, cred,
2146	    &td->td_proc->p_vmspace->vm_map);
2147	/* XXX allow other threads to continue */
2148}
2149
2150static __inline const char *
2151prot2str(vm_prot_t prot)
2152{
2153
2154	switch (prot & VM_PROT_ALL) {
2155	case VM_PROT_READ:
2156		return ("r--");
2157	case VM_PROT_READ | VM_PROT_WRITE:
2158		return ("rw-");
2159	case VM_PROT_READ | VM_PROT_EXECUTE:
2160		return ("r-x");
2161	case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
2162		return ("rwx");
2163	case VM_PROT_WRITE:
2164		return ("-w-");
2165	case VM_PROT_EXECUTE:
2166		return ("--x");
2167	case VM_PROT_WRITE | VM_PROT_EXECUTE:
2168		return ("-wx");
2169	default:
2170		return ("---");
2171	}
2172}
2173
2174static void
2175mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred,
2176    struct vm_map *map)
2177{
2178	struct vm_map_entry *vme;
2179	vm_prot_t result, revokeperms;
2180	vm_object_t object;
2181	vm_ooffset_t offset;
2182	struct vnode *vp;
2183
2184	if (!mac_mmap_revocation)
2185		return;
2186
2187	vm_map_lock_read(map);
2188	for (vme = map->header.next; vme != &map->header; vme = vme->next) {
2189		if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) {
2190			mac_cred_mmapped_drop_perms_recurse(td, cred,
2191			    vme->object.sub_map);
2192			continue;
2193		}
2194		/*
2195		 * Skip over entries that obviously are not shared.
2196		 */
2197		if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) ||
2198		    !vme->max_protection)
2199			continue;
2200		/*
2201		 * Drill down to the deepest backing object.
2202		 */
2203		offset = vme->offset;
2204		object = vme->object.vm_object;
2205		if (object == NULL)
2206			continue;
2207		while (object->backing_object != NULL) {
2208			object = object->backing_object;
2209			offset += object->backing_object_offset;
2210		}
2211		/*
2212		 * At the moment, vm_maps and objects aren't considered
2213		 * by the MAC system, so only things with backing by a
2214		 * normal object (read: vnodes) are checked.
2215		 */
2216		if (object->type != OBJT_VNODE)
2217			continue;
2218		vp = (struct vnode *)object->handle;
2219		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2220		result = mac_check_vnode_mmap_prot(cred, vp, 0);
2221		VOP_UNLOCK(vp, 0, td);
2222		/*
2223		 * Find out what maximum protection we may be allowing
2224		 * now but a policy needs to get removed.
2225		 */
2226		revokeperms = vme->max_protection & ~result;
2227		if (!revokeperms)
2228			continue;
2229		printf("pid %ld: revoking %s perms from %#lx:%ld "
2230		    "(max %s/cur %s)\n", (long)td->td_proc->p_pid,
2231		    prot2str(revokeperms), (u_long)vme->start,
2232		    (long)(vme->end - vme->start),
2233		    prot2str(vme->max_protection), prot2str(vme->protection));
2234		vm_map_lock_upgrade(map);
2235		/*
2236		 * This is the really simple case: if a map has more
2237		 * max_protection than is allowed, but it's not being
2238		 * actually used (that is, the current protection is
2239		 * still allowed), we can just wipe it out and do
2240		 * nothing more.
2241		 */
2242		if ((vme->protection & revokeperms) == 0) {
2243			vme->max_protection -= revokeperms;
2244		} else {
2245			if (revokeperms & VM_PROT_WRITE) {
2246				/*
2247				 * In the more complicated case, flush out all
2248				 * pending changes to the object then turn it
2249				 * copy-on-write.
2250				 */
2251				vm_object_reference(object);
2252				vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2253				vm_object_page_clean(object,
2254				    OFF_TO_IDX(offset),
2255				    OFF_TO_IDX(offset + vme->end - vme->start +
2256					PAGE_MASK),
2257				    OBJPC_SYNC);
2258				VOP_UNLOCK(vp, 0, td);
2259				vm_object_deallocate(object);
2260				/*
2261				 * Why bother if there's no read permissions
2262				 * anymore?  For the rest, we need to leave
2263				 * the write permissions on for COW, or
2264				 * remove them entirely if configured to.
2265				 */
2266				if (!mac_mmap_revocation_via_cow) {
2267					vme->max_protection &= ~VM_PROT_WRITE;
2268					vme->protection &= ~VM_PROT_WRITE;
2269				} if ((revokeperms & VM_PROT_READ) == 0)
2270					vme->eflags |= MAP_ENTRY_COW |
2271					    MAP_ENTRY_NEEDS_COPY;
2272			}
2273			if (revokeperms & VM_PROT_EXECUTE) {
2274				vme->max_protection &= ~VM_PROT_EXECUTE;
2275				vme->protection &= ~VM_PROT_EXECUTE;
2276			}
2277			if (revokeperms & VM_PROT_READ) {
2278				vme->max_protection = 0;
2279				vme->protection = 0;
2280			}
2281			pmap_protect(map->pmap, vme->start, vme->end,
2282			    vme->protection & ~revokeperms);
2283			vm_map_simplify_entry(map, vme);
2284		}
2285		vm_map_lock_downgrade(map);
2286	}
2287	vm_map_unlock_read(map);
2288}
2289
2290/*
2291 * When the subject's label changes, it may require revocation of privilege
2292 * to mapped objects.  This can't be done on-the-fly later with a unified
2293 * buffer cache.
2294 */
2295static void
2296mac_relabel_cred(struct ucred *cred, struct label *newlabel)
2297{
2298
2299	MAC_PERFORM(relabel_cred, cred, newlabel);
2300}
2301
2302void
2303mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel)
2304{
2305
2306	MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel);
2307}
2308
2309void
2310mac_create_ifnet(struct ifnet *ifnet)
2311{
2312
2313	MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label);
2314}
2315
2316void
2317mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d)
2318{
2319
2320	MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label);
2321}
2322
2323void
2324mac_create_socket(struct ucred *cred, struct socket *socket)
2325{
2326
2327	MAC_PERFORM(create_socket, cred, socket, &socket->so_label);
2328}
2329
2330void
2331mac_create_pipe(struct ucred *cred, struct pipe *pipe)
2332{
2333
2334	MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label);
2335}
2336
2337void
2338mac_create_socket_from_socket(struct socket *oldsocket,
2339    struct socket *newsocket)
2340{
2341
2342	MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label,
2343	    newsocket, &newsocket->so_label);
2344}
2345
2346static void
2347mac_relabel_socket(struct ucred *cred, struct socket *socket,
2348    struct label *newlabel)
2349{
2350
2351	MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel);
2352}
2353
2354static void
2355mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel)
2356{
2357
2358	MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel);
2359}
2360
2361void
2362mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket)
2363{
2364
2365	MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label,
2366	    socket, &socket->so_peerlabel);
2367}
2368
2369void
2370mac_set_socket_peer_from_socket(struct socket *oldsocket,
2371    struct socket *newsocket)
2372{
2373
2374	MAC_PERFORM(set_socket_peer_from_socket, oldsocket,
2375	    &oldsocket->so_label, newsocket, &newsocket->so_peerlabel);
2376}
2377
2378void
2379mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram)
2380{
2381
2382	MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label,
2383	    datagram, &datagram->m_pkthdr.label);
2384}
2385
2386void
2387mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment)
2388{
2389
2390	MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label,
2391	    fragment, &fragment->m_pkthdr.label);
2392}
2393
2394void
2395mac_create_ipq(struct mbuf *fragment, struct ipq *ipq)
2396{
2397
2398	MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq,
2399	    &ipq->ipq_label);
2400}
2401
2402void
2403mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf)
2404{
2405
2406	MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label,
2407	    newmbuf, &newmbuf->m_pkthdr.label);
2408}
2409
2410void
2411mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf)
2412{
2413
2414	MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf,
2415	    &mbuf->m_pkthdr.label);
2416}
2417
2418void
2419mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf)
2420{
2421
2422	MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf,
2423	    &mbuf->m_pkthdr.label);
2424}
2425
2426void
2427mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf)
2428{
2429
2430	MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf,
2431	    &mbuf->m_pkthdr.label);
2432}
2433
2434void
2435mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet,
2436    struct mbuf *newmbuf)
2437{
2438
2439	MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf,
2440	    &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf,
2441	    &newmbuf->m_pkthdr.label);
2442}
2443
2444void
2445mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf)
2446{
2447
2448	MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label,
2449	    newmbuf, &newmbuf->m_pkthdr.label);
2450}
2451
2452int
2453mac_fragment_match(struct mbuf *fragment, struct ipq *ipq)
2454{
2455	int result;
2456
2457	result = 1;
2458	MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label,
2459	    ipq, &ipq->ipq_label);
2460
2461	return (result);
2462}
2463
2464void
2465mac_update_ipq(struct mbuf *fragment, struct ipq *ipq)
2466{
2467
2468	MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq,
2469	    &ipq->ipq_label);
2470}
2471
2472void
2473mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf)
2474{
2475
2476	MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf,
2477	    &mbuf->m_pkthdr.label);
2478}
2479
2480void
2481mac_create_mount(struct ucred *cred, struct mount *mp)
2482{
2483
2484	MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel,
2485	    &mp->mnt_fslabel);
2486}
2487
2488void
2489mac_create_root_mount(struct ucred *cred, struct mount *mp)
2490{
2491
2492	MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel,
2493	    &mp->mnt_fslabel);
2494}
2495
2496int
2497mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet)
2498{
2499	int error;
2500
2501	if (!mac_enforce_network)
2502		return (0);
2503
2504	MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet,
2505	    &ifnet->if_label);
2506
2507	return (error);
2508}
2509
2510static int
2511mac_check_cred_relabel(struct ucred *cred, struct label *newlabel)
2512{
2513	int error;
2514
2515	MAC_CHECK(check_cred_relabel, cred, newlabel);
2516
2517	return (error);
2518}
2519
2520int
2521mac_check_cred_visible(struct ucred *u1, struct ucred *u2)
2522{
2523	int error;
2524
2525	if (!mac_enforce_process)
2526		return (0);
2527
2528	MAC_CHECK(check_cred_visible, u1, u2);
2529
2530	return (error);
2531}
2532
2533int
2534mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf)
2535{
2536	int error;
2537
2538	if (!mac_enforce_network)
2539		return (0);
2540
2541	KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr"));
2542	if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED))
2543		printf("%s%d: not initialized\n", ifnet->if_name,
2544		    ifnet->if_unit);
2545
2546	MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf,
2547	    &mbuf->m_pkthdr.label);
2548
2549	return (error);
2550}
2551
2552int
2553mac_check_mount_stat(struct ucred *cred, struct mount *mount)
2554{
2555	int error;
2556
2557	if (!mac_enforce_fs)
2558		return (0);
2559
2560	MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel);
2561
2562	return (error);
2563}
2564
2565int
2566mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd,
2567    void *data)
2568{
2569	int error;
2570
2571	MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data);
2572
2573	return (error);
2574}
2575
2576int
2577mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe)
2578{
2579	int error;
2580
2581	MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label);
2582
2583	return (error);
2584}
2585
2586int
2587mac_check_pipe_read(struct ucred *cred, struct pipe *pipe)
2588{
2589	int error;
2590
2591	MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label);
2592
2593	return (error);
2594}
2595
2596static int
2597mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
2598    struct label *newlabel)
2599{
2600	int error;
2601
2602	MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel);
2603
2604	return (error);
2605}
2606
2607int
2608mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe)
2609{
2610	int error;
2611
2612	MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label);
2613
2614	return (error);
2615}
2616
2617int
2618mac_check_pipe_write(struct ucred *cred, struct pipe *pipe)
2619{
2620	int error;
2621
2622	MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label);
2623
2624	return (error);
2625}
2626
2627int
2628mac_check_proc_debug(struct ucred *cred, struct proc *proc)
2629{
2630	int error;
2631
2632	PROC_LOCK_ASSERT(proc, MA_OWNED);
2633
2634	if (!mac_enforce_process)
2635		return (0);
2636
2637	MAC_CHECK(check_proc_debug, cred, proc);
2638
2639	return (error);
2640}
2641
2642int
2643mac_check_proc_sched(struct ucred *cred, struct proc *proc)
2644{
2645	int error;
2646
2647	PROC_LOCK_ASSERT(proc, MA_OWNED);
2648
2649	if (!mac_enforce_process)
2650		return (0);
2651
2652	MAC_CHECK(check_proc_sched, cred, proc);
2653
2654	return (error);
2655}
2656
2657int
2658mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
2659{
2660	int error;
2661
2662	PROC_LOCK_ASSERT(proc, MA_OWNED);
2663
2664	if (!mac_enforce_process)
2665		return (0);
2666
2667	MAC_CHECK(check_proc_signal, cred, proc, signum);
2668
2669	return (error);
2670}
2671
2672int
2673mac_check_socket_bind(struct ucred *ucred, struct socket *socket,
2674    struct sockaddr *sockaddr)
2675{
2676	int error;
2677
2678	if (!mac_enforce_socket)
2679		return (0);
2680
2681	MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label,
2682	    sockaddr);
2683
2684	return (error);
2685}
2686
2687int
2688mac_check_socket_connect(struct ucred *cred, struct socket *socket,
2689    struct sockaddr *sockaddr)
2690{
2691	int error;
2692
2693	if (!mac_enforce_socket)
2694		return (0);
2695
2696	MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label,
2697	    sockaddr);
2698
2699	return (error);
2700}
2701
2702int
2703mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf)
2704{
2705	int error;
2706
2707	if (!mac_enforce_socket)
2708		return (0);
2709
2710	MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf,
2711	    &mbuf->m_pkthdr.label);
2712
2713	return (error);
2714}
2715
2716int
2717mac_check_socket_listen(struct ucred *cred, struct socket *socket)
2718{
2719	int error;
2720
2721	if (!mac_enforce_socket)
2722		return (0);
2723
2724	MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label);
2725	return (error);
2726}
2727
2728static int
2729mac_check_socket_relabel(struct ucred *cred, struct socket *socket,
2730    struct label *newlabel)
2731{
2732	int error;
2733
2734	MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label,
2735	    newlabel);
2736
2737	return (error);
2738}
2739
2740int
2741mac_check_socket_visible(struct ucred *cred, struct socket *socket)
2742{
2743	int error;
2744
2745	if (!mac_enforce_socket)
2746		return (0);
2747
2748	MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label);
2749
2750	return (error);
2751}
2752
2753int
2754mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
2755    struct ifnet *ifnet)
2756{
2757	struct mac label;
2758	int error;
2759
2760	error = mac_externalize(&ifnet->if_label, &label);
2761	if (error)
2762		return (error);
2763
2764	return (copyout(&label, ifr->ifr_ifru.ifru_data, sizeof(label)));
2765}
2766
2767int
2768mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
2769    struct ifnet *ifnet)
2770{
2771	struct mac newlabel;
2772	struct label intlabel;
2773	int error;
2774
2775	error = copyin(ifr->ifr_ifru.ifru_data, &newlabel, sizeof(newlabel));
2776	if (error)
2777		return (error);
2778
2779	error = mac_internalize(&intlabel, &newlabel);
2780	if (error)
2781		return (error);
2782
2783	/*
2784	 * XXX: Note that this is a redundant privilege check, since
2785	 * policies impose this check themselves if required by the
2786	 * policy.  Eventually, this should go away.
2787	 */
2788	error = suser_cred(cred, 0);
2789	if (error)
2790		goto out;
2791
2792	MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label,
2793	    &intlabel);
2794	if (error)
2795		goto out;
2796
2797	MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel);
2798
2799out:
2800	mac_destroy_temp(&intlabel);
2801	return (error);
2802}
2803
2804void
2805mac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp)
2806{
2807
2808	MAC_PERFORM(create_devfs_vnode, de, &de->de_label, vp, &vp->v_label);
2809}
2810
2811void
2812mac_create_devfs_device(dev_t dev, struct devfs_dirent *de)
2813{
2814
2815	MAC_PERFORM(create_devfs_device, dev, de, &de->de_label);
2816}
2817
2818static int
2819mac_stdcreatevnode_ea(struct vnode *vp)
2820{
2821	int error;
2822
2823	MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label);
2824
2825	return (error);
2826}
2827
2828void
2829mac_create_devfs_directory(char *dirname, int dirnamelen,
2830    struct devfs_dirent *de)
2831{
2832
2833	MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de,
2834	    &de->de_label);
2835}
2836
2837/*
2838 * When a new vnode is created, this call will initialize its label.
2839 */
2840void
2841mac_create_vnode(struct ucred *cred, struct vnode *parent,
2842    struct vnode *child)
2843{
2844	int error;
2845
2846	ASSERT_VOP_LOCKED(parent, "mac_create_vnode");
2847	ASSERT_VOP_LOCKED(child, "mac_create_vnode");
2848
2849	error = vn_refreshlabel(parent, cred);
2850	if (error) {
2851		printf("mac_create_vnode: vn_refreshlabel returned %d\n",
2852		    error);
2853		printf("mac_create_vnode: using old vnode label\n");
2854	}
2855
2856	MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child,
2857	    &child->v_label);
2858}
2859
2860int
2861mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
2862    struct mac *extmac)
2863{
2864	struct label intlabel;
2865	int error;
2866
2867	error = mac_internalize(&intlabel, extmac);
2868	if (error)
2869		return (error);
2870
2871	mac_check_socket_relabel(cred, so, &intlabel);
2872	if (error) {
2873		mac_destroy_temp(&intlabel);
2874		return (error);
2875	}
2876
2877	mac_relabel_socket(cred, so, &intlabel);
2878
2879	mac_destroy_temp(&intlabel);
2880	return (0);
2881}
2882
2883int
2884mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label)
2885{
2886	int error;
2887
2888	error = mac_check_pipe_relabel(cred, pipe, label);
2889	if (error)
2890		return (error);
2891
2892	mac_relabel_pipe(cred, pipe, label);
2893
2894	return (0);
2895}
2896
2897int
2898mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
2899    struct mac *extmac)
2900{
2901
2902	return (mac_externalize(&so->so_label, extmac));
2903}
2904
2905int
2906mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
2907    struct mac *extmac)
2908{
2909
2910	return (mac_externalize(&so->so_peerlabel, extmac));
2911}
2912
2913/*
2914 * Implementation of VOP_SETLABEL() that relies on extended attributes
2915 * to store label data.  Can be referenced by filesystems supporting
2916 * extended attributes.
2917 */
2918int
2919vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
2920{
2921	struct vnode *vp = ap->a_vp;
2922	struct label *intlabel = ap->a_label;
2923	struct mac extmac;
2924	int error;
2925
2926	ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
2927
2928	/*
2929	 * XXX: Eventually call out to EA check/set calls here.
2930	 * Be particularly careful to avoid race conditions,
2931	 * consistency problems, and stability problems when
2932	 * dealing with multiple EAs.  In particular, we require
2933	 * the ability to write multiple EAs on the same file in
2934	 * a single transaction, which the current EA interface
2935	 * does not provide.
2936	 */
2937
2938	error = mac_externalize(intlabel, &extmac);
2939	if (error)
2940		return (error);
2941
2942	error = vn_extattr_set(vp, IO_NODELOCKED,
2943	    FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
2944	    sizeof(extmac), (char *)&extmac, curthread);
2945	if (error)
2946		return (error);
2947
2948	mac_relabel_vnode(ap->a_cred, vp, intlabel);
2949
2950	vp->v_vflag |= VV_CACHEDLABEL;
2951
2952	return (0);
2953}
2954
2955static int
2956vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred)
2957{
2958	int error;
2959
2960	if (vp->v_mount == NULL) {
2961		/* printf("vn_setlabel: null v_mount\n"); */
2962		if (vp->v_type != VNON)
2963			printf("vn_setlabel: null v_mount with non-VNON\n");
2964		return (EBADF);
2965	}
2966
2967	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
2968		return (EOPNOTSUPP);
2969
2970	/*
2971	 * Multi-phase commit.  First check the policies to confirm the
2972	 * change is OK.  Then commit via the filesystem.  Finally,
2973	 * update the actual vnode label.  Question: maybe the filesystem
2974	 * should update the vnode at the end as part of VOP_SETLABEL()?
2975	 */
2976	error = mac_check_vnode_relabel(cred, vp, intlabel);
2977	if (error)
2978		return (error);
2979
2980	/*
2981	 * VADMIN provides the opportunity for the filesystem to make
2982	 * decisions about who is and is not able to modify labels
2983	 * and protections on files.  This might not be right.  We can't
2984	 * assume VOP_SETLABEL() will do it, because we might implement
2985	 * that as part of vop_stdsetlabel_ea().
2986	 */
2987	error = VOP_ACCESS(vp, VADMIN, cred, curthread);
2988	if (error)
2989		return (error);
2990
2991	error = VOP_SETLABEL(vp, intlabel, cred, curthread);
2992	if (error)
2993		return (error);
2994
2995	return (0);
2996}
2997
2998/*
2999 * MPSAFE
3000 */
3001int
3002__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
3003{
3004	struct mac extmac;
3005	int error;
3006
3007	error = mac_externalize(&td->td_ucred->cr_label, &extmac);
3008	if (error == 0)
3009		error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac));
3010
3011	return (error);
3012}
3013
3014/*
3015 * MPSAFE
3016 */
3017int
3018__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
3019{
3020	struct ucred *newcred, *oldcred;
3021	struct proc *p;
3022	struct mac extmac;
3023	struct label intlabel;
3024	int error;
3025
3026	error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac));
3027	if (error)
3028		return (error);
3029
3030	error = mac_internalize(&intlabel, &extmac);
3031	if (error)
3032		return (error);
3033
3034	newcred = crget();
3035
3036	p = td->td_proc;
3037	PROC_LOCK(p);
3038	oldcred = p->p_ucred;
3039
3040	error = mac_check_cred_relabel(oldcred, &intlabel);
3041	if (error) {
3042		PROC_UNLOCK(p);
3043		mac_destroy_temp(&intlabel);
3044		crfree(newcred);
3045		return (error);
3046	}
3047
3048	setsugid(p);
3049	crcopy(newcred, oldcred);
3050	mac_relabel_cred(newcred, &intlabel);
3051	p->p_ucred = newcred;
3052
3053	/*
3054	 * Grab additional reference for use while revoking mmaps, prior
3055	 * to releasing the proc lock and sharing the cred.
3056	 */
3057	crhold(newcred);
3058	PROC_UNLOCK(p);
3059
3060	mtx_lock(&Giant);
3061	mac_cred_mmapped_drop_perms(td, newcred);
3062	mtx_unlock(&Giant);
3063
3064	crfree(newcred);	/* Free revocation reference. */
3065	crfree(oldcred);
3066	mac_destroy_temp(&intlabel);
3067	return (0);
3068}
3069
3070/*
3071 * MPSAFE
3072 */
3073int
3074__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
3075{
3076	struct file *fp;
3077	struct mac extmac;
3078	struct vnode *vp;
3079	struct pipe *pipe;
3080	int error;
3081
3082	mtx_lock(&Giant);
3083
3084	error = fget(td, SCARG(uap, fd), &fp);
3085	if (error)
3086		goto out;
3087
3088	switch (fp->f_type) {
3089	case DTYPE_FIFO:
3090	case DTYPE_VNODE:
3091		vp = (struct vnode *)fp->f_data;
3092
3093		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3094		error = vn_refreshlabel(vp, td->td_ucred);
3095		if (error == 0)
3096			error = mac_externalize(&vp->v_label, &extmac);
3097		VOP_UNLOCK(vp, 0, td);
3098		break;
3099	case DTYPE_PIPE:
3100		pipe = (struct pipe *)fp->f_data;
3101		error = mac_externalize(pipe->pipe_label, &extmac);
3102		break;
3103	default:
3104		error = EINVAL;
3105	}
3106
3107	if (error == 0)
3108		error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac));
3109
3110	fdrop(fp, td);
3111
3112out:
3113	mtx_unlock(&Giant);
3114	return (error);
3115}
3116
3117/*
3118 * MPSAFE
3119 */
3120int
3121__mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
3122{
3123	struct nameidata nd;
3124	struct mac extmac;
3125	int error;
3126
3127	mtx_lock(&Giant);
3128	NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE,
3129	    SCARG(uap, path_p), td);
3130	error = namei(&nd);
3131	if (error)
3132		goto out;
3133
3134	error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
3135	if (error == 0)
3136		error = mac_externalize(&nd.ni_vp->v_label, &extmac);
3137	NDFREE(&nd, 0);
3138	if (error)
3139		goto out;
3140
3141	error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac));
3142
3143out:
3144	mtx_unlock(&Giant);
3145	return (error);
3146}
3147
3148/*
3149 * MPSAFE
3150 */
3151int
3152__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
3153{
3154	struct file *fp;
3155	struct mac extmac;
3156	struct label intlabel;
3157	struct mount *mp;
3158	struct vnode *vp;
3159	struct pipe *pipe;
3160	int error;
3161
3162	mtx_lock(&Giant);
3163	error = fget(td, SCARG(uap, fd), &fp);
3164	if (error)
3165		goto out1;
3166
3167	error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac));
3168	if (error)
3169		goto out2;
3170
3171	error = mac_internalize(&intlabel, &extmac);
3172	if (error)
3173		goto out2;
3174
3175	switch (fp->f_type) {
3176	case DTYPE_FIFO:
3177	case DTYPE_VNODE:
3178		vp = (struct vnode *)fp->f_data;
3179		error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
3180		if (error != 0)
3181			break;
3182
3183		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3184		error = vn_setlabel(vp, &intlabel, td->td_ucred);
3185		VOP_UNLOCK(vp, 0, td);
3186		vn_finished_write(mp);
3187		mac_destroy_temp(&intlabel);
3188		break;
3189	case DTYPE_PIPE:
3190		pipe = (struct pipe *)fp->f_data;
3191		error = mac_pipe_label_set(td->td_ucred, pipe, &intlabel);
3192		break;
3193	default:
3194		error = EINVAL;
3195	}
3196
3197out2:
3198	fdrop(fp, td);
3199out1:
3200	mtx_unlock(&Giant);
3201	return (error);
3202}
3203
3204/*
3205 * MPSAFE
3206 */
3207int
3208__mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
3209{
3210	struct nameidata nd;
3211	struct mac extmac;
3212	struct label intlabel;
3213	struct mount *mp;
3214	int error;
3215
3216	mtx_lock(&Giant);
3217
3218	error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac));
3219	if (error)
3220		goto out;
3221
3222	error = mac_internalize(&intlabel, &extmac);
3223	if (error)
3224		goto out;
3225
3226	NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE,
3227	    SCARG(uap, path_p), td);
3228	error = namei(&nd);
3229	if (error)
3230		goto out2;
3231	error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
3232	if (error)
3233		goto out2;
3234
3235	error = vn_setlabel(nd.ni_vp, &intlabel, td->td_ucred);
3236
3237	vn_finished_write(mp);
3238out2:
3239	mac_destroy_temp(&intlabel);
3240	NDFREE(&nd, 0);
3241out:
3242	mtx_unlock(&Giant);
3243	return (error);
3244}
3245
3246int
3247mac_syscall(struct thread *td, struct mac_syscall_args *uap)
3248{
3249	struct mac_policy_conf *mpc;
3250	char target[MAC_MAX_POLICY_NAME];
3251	int error;
3252
3253	error = copyinstr(SCARG(uap, policy), target, sizeof(target), NULL);
3254	if (error)
3255		return (error);
3256
3257	error = ENOSYS;
3258	MAC_POLICY_LIST_BUSY();
3259	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {
3260		if (strcmp(mpc->mpc_name, target) == 0 &&
3261		    mpc->mpc_ops->mpo_syscall != NULL) {
3262			error = mpc->mpc_ops->mpo_syscall(td,
3263			    SCARG(uap, call), SCARG(uap, arg));
3264			goto out;
3265		}
3266	}
3267
3268out:
3269	MAC_POLICY_LIST_UNBUSY();
3270	return (error);
3271}
3272
3273SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL);
3274SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL);
3275
3276#else /* !MAC */
3277
3278int
3279__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
3280{
3281
3282	return (ENOSYS);
3283}
3284
3285int
3286__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
3287{
3288
3289	return (ENOSYS);
3290}
3291
3292int
3293__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
3294{
3295
3296	return (ENOSYS);
3297}
3298
3299int
3300__mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
3301{
3302
3303	return (ENOSYS);
3304}
3305
3306int
3307__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
3308{
3309
3310	return (ENOSYS);
3311}
3312
3313int
3314__mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
3315{
3316
3317	return (ENOSYS);
3318}
3319
3320int
3321mac_syscall(struct thread *td, struct mac_syscall_args *uap)
3322{
3323
3324	return (ENOSYS);
3325}
3326
3327#endif /* !MAC */
3328