mac_cred.c revision 106369
1100894Srwatson/*-
2100894Srwatson * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3100894Srwatson * Copyright (c) 2001 Ilmar S. Habibulin
4100894Srwatson * Copyright (c) 2001, 2002 Networks Associates Technology, Inc.
5100894Srwatson * All rights reserved.
6100894Srwatson *
7100894Srwatson * This software was developed by Robert Watson and Ilmar Habibulin for the
8100894Srwatson * TrustedBSD Project.
9100894Srwatson *
10100894Srwatson * This software was developed for the FreeBSD Project in part by NAI Labs,
11100894Srwatson * the Security Research Division of Network Associates, Inc. under
12100894Srwatson * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
13100894Srwatson * CHATS research program.
14100894Srwatson *
15100894Srwatson * Redistribution and use in source and binary forms, with or without
16100894Srwatson * modification, are permitted provided that the following conditions
17100894Srwatson * are met:
18100894Srwatson * 1. Redistributions of source code must retain the above copyright
19100894Srwatson *    notice, this list of conditions and the following disclaimer.
20100894Srwatson * 2. Redistributions in binary form must reproduce the above copyright
21100894Srwatson *    notice, this list of conditions and the following disclaimer in the
22100894Srwatson *    documentation and/or other materials provided with the distribution.
23100894Srwatson * 3. The names of the authors may not be used to endorse or promote
24100894Srwatson *    products derived from this software without specific prior written
25100894Srwatson *    permission.
26100894Srwatson *
27100894Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
28100894Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29100894Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30100894Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
31100894Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32100894Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33100894Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34100894Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35100894Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36100894Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37100894Srwatson * SUCH DAMAGE.
38100894Srwatson *
39100894Srwatson * $FreeBSD: head/sys/security/mac/mac_process.c 106369 2002-11-03 02:39:42Z rwatson $
40100894Srwatson */
41100894Srwatson/*
42100894Srwatson * Developed by the TrustedBSD Project.
43100894Srwatson *
44100894Srwatson * Framework for extensible kernel access control.  Kernel and userland
45100894Srwatson * interface to the framework, policy registration and composition.
46100894Srwatson */
47100894Srwatson
48100894Srwatson#include "opt_mac.h"
49104300Sphk#include "opt_devfs.h"
50101173Srwatson
51100894Srwatson#include <sys/param.h>
52100979Srwatson#include <sys/extattr.h>
53100979Srwatson#include <sys/kernel.h>
54100979Srwatson#include <sys/lock.h>
55102949Sbde#include <sys/malloc.h>
56100979Srwatson#include <sys/mutex.h>
57100979Srwatson#include <sys/mac.h>
58101712Srwatson#include <sys/module.h>
59100979Srwatson#include <sys/proc.h>
60100979Srwatson#include <sys/systm.h>
61100894Srwatson#include <sys/sysproto.h>
62100894Srwatson#include <sys/sysent.h>
63100979Srwatson#include <sys/vnode.h>
64100979Srwatson#include <sys/mount.h>
65100979Srwatson#include <sys/file.h>
66100979Srwatson#include <sys/namei.h>
67100979Srwatson#include <sys/socket.h>
68100979Srwatson#include <sys/pipe.h>
69100979Srwatson#include <sys/socketvar.h>
70100979Srwatson#include <sys/sysctl.h>
71100894Srwatson
72100979Srwatson#include <vm/vm.h>
73100979Srwatson#include <vm/pmap.h>
74100979Srwatson#include <vm/vm_map.h>
75100979Srwatson#include <vm/vm_object.h>
76100979Srwatson
77100979Srwatson#include <sys/mac_policy.h>
78100979Srwatson
79100979Srwatson#include <fs/devfs/devfs.h>
80100979Srwatson
81100979Srwatson#include <net/bpfdesc.h>
82100979Srwatson#include <net/if.h>
83100979Srwatson#include <net/if_var.h>
84100979Srwatson
85100979Srwatson#include <netinet/in.h>
86100979Srwatson#include <netinet/ip_var.h>
87100979Srwatson
88100979Srwatson#ifdef MAC
89100979Srwatson
90101712Srwatson/*
91101712Srwatson * Declare that the kernel provides MAC support, version 1.  This permits
92101712Srwatson * modules to refuse to be loaded if the necessary support isn't present,
93101712Srwatson * even if it's pre-boot.
94101712Srwatson */
95101712SrwatsonMODULE_VERSION(kernel_mac_support, 1);
96101712Srwatson
97100979SrwatsonSYSCTL_DECL(_security);
98100979Srwatson
99100979SrwatsonSYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0,
100100979Srwatson    "TrustedBSD MAC policy controls");
101104517Srwatson
102100979Srwatson#if MAC_MAX_POLICIES > 32
103100979Srwatson#error "MAC_MAX_POLICIES too large"
104100979Srwatson#endif
105105497Srwatson
106100979Srwatsonstatic unsigned int mac_max_policies = MAC_MAX_POLICIES;
107100979Srwatsonstatic unsigned int mac_policy_offsets_free = (1 << MAC_MAX_POLICIES) - 1;
108100979SrwatsonSYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD,
109100979Srwatson    &mac_max_policies, 0, "");
110100979Srwatson
111105959Srwatson/*
112105959Srwatson * Has the kernel started generating labeled objects yet?  All read/write
113105959Srwatson * access to this variable is serialized during the boot process.  Following
114105959Srwatson * the end of serialization, we don't update this flag; no locking.
115105959Srwatson */
116100979Srwatsonstatic int	mac_late = 0;
117100979Srwatson
118105988Srwatson/*
119105988Srwatson * Warn about EA transactions only the first time they happen.
120105988Srwatson * Weak coherency, no locking.
121105988Srwatson */
122105988Srwatsonstatic int	ea_warn_once = 0;
123105988Srwatson
124100979Srwatsonstatic int	mac_enforce_fs = 1;
125100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
126100979Srwatson    &mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
127100979SrwatsonTUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
128100979Srwatson
129100979Srwatsonstatic int	mac_enforce_network = 1;
130100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
131100979Srwatson    &mac_enforce_network, 0, "Enforce MAC policy on network packets");
132100979SrwatsonTUNABLE_INT("security.mac.enforce_network", &mac_enforce_network);
133100979Srwatson
134103513Srwatsonstatic int	mac_enforce_pipe = 1;
135103513SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW,
136103513Srwatson    &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations");
137104236SrwatsonTUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe);
138103513Srwatson
139100979Srwatsonstatic int	mac_enforce_process = 1;
140100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW,
141100979Srwatson    &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations");
142100979SrwatsonTUNABLE_INT("security.mac.enforce_process", &mac_enforce_process);
143100979Srwatson
144100979Srwatsonstatic int	mac_enforce_socket = 1;
145100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
146100979Srwatson    &mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
147100979SrwatsonTUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
148100979Srwatson
149106045Srwatsonstatic int	mac_enforce_system = 1;
150106045SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_system, CTLFLAG_RW,
151106045Srwatson    &mac_enforce_system, 0, "Enforce MAC policy on system operations");
152106045SrwatsonTUNABLE_INT("security.mac.enforce_system", &mac_enforce_system);
153106025Srwatson
154106045Srwatsonstatic int	mac_enforce_vm = 1;
155103514SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
156103514Srwatson    &mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
157104236SrwatsonTUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm);
158103514Srwatson
159100979Srwatsonstatic int	mac_cache_fslabel_in_vnode = 1;
160100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW,
161100979Srwatson    &mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode");
162100979SrwatsonTUNABLE_INT("security.mac.cache_fslabel_in_vnode",
163100979Srwatson    &mac_cache_fslabel_in_vnode);
164100979Srwatson
165103136Srwatsonstatic int	mac_mmap_revocation = 1;
166103136SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW,
167103136Srwatson    &mac_mmap_revocation, 0, "Revoke mmap access to files on subject "
168103136Srwatson    "relabel");
169101892Srwatsonstatic int	mac_mmap_revocation_via_cow = 0;
170100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW,
171100979Srwatson    &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via "
172100979Srwatson    "copy-on-write semantics, or by removing all write access");
173100979Srwatson
174101988Srwatson#ifdef MAC_DEBUG
175104268SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0,
176104268Srwatson    "TrustedBSD MAC debug info");
177104268Srwatson
178104268Srwatsonstatic int	mac_debug_label_fallback = 0;
179104268SrwatsonSYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW,
180104268Srwatson    &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label"
181104268Srwatson    "when label is corrupted.");
182104268SrwatsonTUNABLE_INT("security.mac.debug_label_fallback",
183104268Srwatson    &mac_debug_label_fallback);
184104268Srwatson
185104517SrwatsonSYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0,
186104517Srwatson    "TrustedBSD MAC object counters");
187104517Srwatson
188100979Srwatsonstatic unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs,
189100979Srwatson    nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents,
190100979Srwatson    nmacipqs, nmacpipes;
191104517Srwatson
192104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD,
193100979Srwatson    &nmacmbufs, 0, "number of mbufs in use");
194104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD,
195100979Srwatson    &nmaccreds, 0, "number of ucreds in use");
196104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD,
197100979Srwatson    &nmacifnets, 0, "number of ifnets in use");
198104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD,
199100979Srwatson    &nmacipqs, 0, "number of ipqs in use");
200104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD,
201100979Srwatson    &nmacbpfdescs, 0, "number of bpfdescs in use");
202104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD,
203100979Srwatson    &nmacsockets, 0, "number of sockets in use");
204104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, pipes, CTLFLAG_RD,
205100979Srwatson    &nmacpipes, 0, "number of pipes in use");
206104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD,
207100979Srwatson    &nmacmounts, 0, "number of mounts in use");
208104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD,
209100979Srwatson    &nmactemp, 0, "number of temporary labels in use");
210104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD,
211100979Srwatson    &nmacvnodes, 0, "number of vnodes in use");
212104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD,
213100979Srwatson    &nmacdevfsdirents, 0, "number of devfs dirents inuse");
214101988Srwatson#endif
215100979Srwatson
216100979Srwatsonstatic int	error_select(int error1, int error2);
217100979Srwatsonstatic int	mac_policy_register(struct mac_policy_conf *mpc);
218100979Srwatsonstatic int	mac_policy_unregister(struct mac_policy_conf *mpc);
219100979Srwatson
220104546Srwatsonstatic void	mac_check_vnode_mmap_downgrade(struct ucred *cred,
221104546Srwatson		    struct vnode *vp, int *prot);
222100979Srwatsonstatic void	mac_cred_mmapped_drop_perms_recurse(struct thread *td,
223100979Srwatson		    struct ucred *cred, struct vm_map *map);
224100979Srwatson
225104541Srwatsonstatic void	mac_destroy_socket_label(struct label *label);
226104541Srwatson
227105988Srwatsonstatic int	mac_setlabel_vnode_extattr(struct ucred *cred,
228105988Srwatson		    struct vnode *vp, struct label *intlabel);
229105988Srwatson
230105988Srwatson
231100979SrwatsonMALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector");
232100979SrwatsonMALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes");
233105694SrwatsonMALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
234100979Srwatson
235100979Srwatson/*
236100979Srwatson * mac_policy_list_lock protects the consistency of 'mac_policy_list',
237100979Srwatson * the linked list of attached policy modules.  Read-only consumers of
238100979Srwatson * the list must acquire a shared lock for the duration of their use;
239100979Srwatson * writers must acquire an exclusive lock.  Note that for compound
240100979Srwatson * operations, locks should be held for the entire compound operation,
241100979Srwatson * and that this is not yet done for relabel requests.
242100979Srwatson */
243100979Srwatsonstatic struct mtx mac_policy_list_lock;
244100979Srwatsonstatic LIST_HEAD(, mac_policy_conf) mac_policy_list;
245100979Srwatsonstatic int mac_policy_list_busy;
246100979Srwatson#define	MAC_POLICY_LIST_LOCKINIT()	mtx_init(&mac_policy_list_lock,	\
247100979Srwatson	"mac_policy_list_lock", NULL, MTX_DEF);
248100979Srwatson#define	MAC_POLICY_LIST_LOCK()	mtx_lock(&mac_policy_list_lock);
249100979Srwatson#define	MAC_POLICY_LIST_UNLOCK()	mtx_unlock(&mac_policy_list_lock);
250100979Srwatson
251100979Srwatson#define	MAC_POLICY_LIST_BUSY() do {					\
252100979Srwatson	MAC_POLICY_LIST_LOCK();						\
253100979Srwatson	mac_policy_list_busy++;						\
254100979Srwatson	MAC_POLICY_LIST_UNLOCK();					\
255100979Srwatson} while (0)
256100979Srwatson
257100979Srwatson#define	MAC_POLICY_LIST_UNBUSY() do {					\
258100979Srwatson	MAC_POLICY_LIST_LOCK();						\
259100979Srwatson	mac_policy_list_busy--;						\
260100979Srwatson	if (mac_policy_list_busy < 0)					\
261100979Srwatson		panic("Extra mac_policy_list_busy--");			\
262100979Srwatson	MAC_POLICY_LIST_UNLOCK();					\
263100979Srwatson} while (0)
264100979Srwatson
265100979Srwatson/*
266100979Srwatson * MAC_CHECK performs the designated check by walking the policy
267100979Srwatson * module list and checking with each as to how it feels about the
268100979Srwatson * request.  Note that it returns its value via 'error' in the scope
269100979Srwatson * of the caller.
270100979Srwatson */
271100979Srwatson#define	MAC_CHECK(check, args...) do {					\
272100979Srwatson	struct mac_policy_conf *mpc;					\
273100979Srwatson									\
274100979Srwatson	error = 0;							\
275100979Srwatson	MAC_POLICY_LIST_BUSY();						\
276100979Srwatson	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {			\
277100979Srwatson		if (mpc->mpc_ops->mpo_ ## check != NULL)		\
278100979Srwatson			error = error_select(				\
279100979Srwatson			    mpc->mpc_ops->mpo_ ## check (args),		\
280100979Srwatson			    error);					\
281100979Srwatson	}								\
282100979Srwatson	MAC_POLICY_LIST_UNBUSY();					\
283100979Srwatson} while (0)
284100979Srwatson
285100979Srwatson/*
286100979Srwatson * MAC_BOOLEAN performs the designated boolean composition by walking
287100979Srwatson * the module list, invoking each instance of the operation, and
288100979Srwatson * combining the results using the passed C operator.  Note that it
289100979Srwatson * returns its value via 'result' in the scope of the caller, which
290100979Srwatson * should be initialized by the caller in a meaningful way to get
291100979Srwatson * a meaningful result.
292100979Srwatson */
293100979Srwatson#define	MAC_BOOLEAN(operation, composition, args...) do {		\
294100979Srwatson	struct mac_policy_conf *mpc;					\
295100979Srwatson									\
296100979Srwatson	MAC_POLICY_LIST_BUSY();						\
297100979Srwatson	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {			\
298100979Srwatson		if (mpc->mpc_ops->mpo_ ## operation != NULL)		\
299100979Srwatson			result = result composition			\
300100979Srwatson			    mpc->mpc_ops->mpo_ ## operation (args);	\
301100979Srwatson	}								\
302100979Srwatson	MAC_POLICY_LIST_UNBUSY();					\
303100979Srwatson} while (0)
304100979Srwatson
305105694Srwatson#define	MAC_EXTERNALIZE(type, label, elementlist, outbuf, 		\
306105694Srwatson    outbuflen) do {							\
307105694Srwatson	char *curptr, *curptr_start, *element_name, *element_temp;	\
308105694Srwatson	size_t left, left_start, len;					\
309105694Srwatson	int claimed, first, first_start, ignorenotfound;		\
310105694Srwatson									\
311105694Srwatson	error = 0;							\
312105694Srwatson	element_temp = elementlist;					\
313105694Srwatson	curptr = outbuf;						\
314105694Srwatson	curptr[0] = '\0';						\
315105694Srwatson	left = outbuflen;						\
316105694Srwatson	first = 1;							\
317105694Srwatson	while ((element_name = strsep(&element_temp, ",")) != NULL) {	\
318105694Srwatson		curptr_start = curptr;					\
319105694Srwatson		left_start = left;					\
320105694Srwatson		first_start = first;					\
321105694Srwatson		if (element_name[0] == '?') {				\
322105694Srwatson			element_name++;					\
323105694Srwatson			ignorenotfound = 1;				\
324105694Srwatson		} else							\
325105694Srwatson			ignorenotfound = 0;				\
326105694Srwatson		claimed = 0;						\
327105694Srwatson		if (first) {						\
328105694Srwatson			len = snprintf(curptr, left, "%s/",		\
329105694Srwatson			    element_name);				\
330105694Srwatson			first = 0;					\
331105694Srwatson		} else							\
332105694Srwatson			len = snprintf(curptr, left, ",%s/",		\
333105694Srwatson			    element_name);				\
334105694Srwatson		if (len >= left) {					\
335105694Srwatson			error = EINVAL;		/* XXXMAC: E2BIG */	\
336105694Srwatson			break;						\
337105694Srwatson		}							\
338105694Srwatson		curptr += len;						\
339105694Srwatson		left -= len;						\
340105694Srwatson									\
341105694Srwatson		MAC_CHECK(externalize_ ## type, label, element_name,	\
342105694Srwatson		    curptr, left, &len, &claimed);			\
343105694Srwatson		if (error)						\
344105694Srwatson			break;						\
345105694Srwatson		if (claimed == 1) {					\
346105694Srwatson			if (len >= outbuflen) {				\
347105694Srwatson				error = EINVAL;	/* XXXMAC: E2BIG */	\
348105694Srwatson				break;					\
349105694Srwatson			}						\
350105694Srwatson			curptr += len;					\
351105694Srwatson			left -= len;					\
352105694Srwatson		} else if (claimed == 0 && ignorenotfound) {		\
353105694Srwatson			/*						\
354105694Srwatson			 * Revert addition of the label element		\
355105694Srwatson			 * name.					\
356105694Srwatson			 */						\
357105694Srwatson			curptr = curptr_start;				\
358105694Srwatson			*curptr = '\0';					\
359105694Srwatson			left = left_start;				\
360105694Srwatson			first = first_start;				\
361105694Srwatson		} else {						\
362105694Srwatson			error = EINVAL;		/* XXXMAC: ENOLABEL */	\
363105694Srwatson			break;						\
364105694Srwatson		}							\
365105694Srwatson	}								\
366105694Srwatson} while (0)
367105694Srwatson
368105694Srwatson#define	MAC_INTERNALIZE(type, label, instring) do {			\
369105694Srwatson	char *element, *element_name, *element_data;			\
370105694Srwatson	int claimed;							\
371105694Srwatson									\
372105694Srwatson	error = 0;							\
373105694Srwatson	element = instring;						\
374105694Srwatson	while ((element_name = strsep(&element, ",")) != NULL) {	\
375105694Srwatson		element_data = element_name;				\
376105694Srwatson		element_name = strsep(&element_data, "/");		\
377105694Srwatson		if (element_data == NULL) {				\
378105694Srwatson			error = EINVAL;					\
379105694Srwatson			break;						\
380105694Srwatson		}							\
381105694Srwatson		claimed = 0;						\
382105694Srwatson		MAC_CHECK(internalize_ ## type, label, element_name,	\
383105694Srwatson		    element_data, &claimed);				\
384105694Srwatson		if (error)						\
385105694Srwatson			break;						\
386105694Srwatson		if (claimed != 1) {					\
387105694Srwatson			/* XXXMAC: Another error here? */		\
388105694Srwatson			error = EINVAL;					\
389105694Srwatson			break;						\
390105694Srwatson		}							\
391105694Srwatson	}								\
392105694Srwatson} while (0)
393105694Srwatson
394100979Srwatson/*
395100979Srwatson * MAC_PERFORM performs the designated operation by walking the policy
396100979Srwatson * module list and invoking that operation for each policy.
397100979Srwatson */
398100979Srwatson#define	MAC_PERFORM(operation, args...) do {				\
399100979Srwatson	struct mac_policy_conf *mpc;					\
400100979Srwatson									\
401100979Srwatson	MAC_POLICY_LIST_BUSY();						\
402100979Srwatson	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {			\
403100979Srwatson		if (mpc->mpc_ops->mpo_ ## operation != NULL)		\
404100979Srwatson			mpc->mpc_ops->mpo_ ## operation (args);		\
405100979Srwatson	}								\
406100979Srwatson	MAC_POLICY_LIST_UNBUSY();					\
407100979Srwatson} while (0)
408100979Srwatson
409100979Srwatson/*
410100979Srwatson * Initialize the MAC subsystem, including appropriate SMP locks.
411100979Srwatson */
412100979Srwatsonstatic void
413100979Srwatsonmac_init(void)
414100979Srwatson{
415100979Srwatson
416100979Srwatson	LIST_INIT(&mac_policy_list);
417100979Srwatson	MAC_POLICY_LIST_LOCKINIT();
418100979Srwatson}
419100979Srwatson
420100979Srwatson/*
421100979Srwatson * For the purposes of modules that want to know if they were loaded
422100979Srwatson * "early", set the mac_late flag once we've processed modules either
423100979Srwatson * linked into the kernel, or loaded before the kernel startup.
424100979Srwatson */
425100979Srwatsonstatic void
426100979Srwatsonmac_late_init(void)
427100979Srwatson{
428100979Srwatson
429100979Srwatson	mac_late = 1;
430100979Srwatson}
431100979Srwatson
432100979Srwatson/*
433100979Srwatson * Allow MAC policy modules to register during boot, etc.
434100979Srwatson */
435100894Srwatsonint
436100979Srwatsonmac_policy_modevent(module_t mod, int type, void *data)
437100979Srwatson{
438100979Srwatson	struct mac_policy_conf *mpc;
439100979Srwatson	int error;
440100979Srwatson
441100979Srwatson	error = 0;
442100979Srwatson	mpc = (struct mac_policy_conf *) data;
443100979Srwatson
444100979Srwatson	switch (type) {
445100979Srwatson	case MOD_LOAD:
446100979Srwatson		if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE &&
447100979Srwatson		    mac_late) {
448100979Srwatson			printf("mac_policy_modevent: can't load %s policy "
449100979Srwatson			    "after booting\n", mpc->mpc_name);
450100979Srwatson			error = EBUSY;
451100979Srwatson			break;
452100979Srwatson		}
453100979Srwatson		error = mac_policy_register(mpc);
454100979Srwatson		break;
455100979Srwatson	case MOD_UNLOAD:
456100979Srwatson		/* Don't unregister the module if it was never registered. */
457100979Srwatson		if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED)
458100979Srwatson		    != 0)
459100979Srwatson			error = mac_policy_unregister(mpc);
460100979Srwatson		else
461100979Srwatson			error = 0;
462100979Srwatson		break;
463100979Srwatson	default:
464100979Srwatson		break;
465100979Srwatson	}
466100979Srwatson
467100979Srwatson	return (error);
468100979Srwatson}
469100979Srwatson
470100979Srwatsonstatic int
471100979Srwatsonmac_policy_register(struct mac_policy_conf *mpc)
472100979Srwatson{
473100979Srwatson	struct mac_policy_conf *tmpc;
474100979Srwatson	int slot;
475100979Srwatson
476100979Srwatson	MAC_POLICY_LIST_LOCK();
477100979Srwatson	if (mac_policy_list_busy > 0) {
478100979Srwatson		MAC_POLICY_LIST_UNLOCK();
479100979Srwatson		return (EBUSY);
480100979Srwatson	}
481100979Srwatson	LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) {
482100979Srwatson		if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) {
483100979Srwatson			MAC_POLICY_LIST_UNLOCK();
484100979Srwatson			return (EEXIST);
485100979Srwatson		}
486100979Srwatson	}
487100979Srwatson	if (mpc->mpc_field_off != NULL) {
488100979Srwatson		slot = ffs(mac_policy_offsets_free);
489100979Srwatson		if (slot == 0) {
490100979Srwatson			MAC_POLICY_LIST_UNLOCK();
491100979Srwatson			return (ENOMEM);
492100979Srwatson		}
493100979Srwatson		slot--;
494100979Srwatson		mac_policy_offsets_free &= ~(1 << slot);
495100979Srwatson		*mpc->mpc_field_off = slot;
496100979Srwatson	}
497100979Srwatson	mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED;
498100979Srwatson	LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list);
499100979Srwatson
500100979Srwatson	/* Per-policy initialization. */
501100979Srwatson	if (mpc->mpc_ops->mpo_init != NULL)
502100979Srwatson		(*(mpc->mpc_ops->mpo_init))(mpc);
503100979Srwatson	MAC_POLICY_LIST_UNLOCK();
504100979Srwatson
505100979Srwatson	printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname,
506100979Srwatson	    mpc->mpc_name);
507100979Srwatson
508100979Srwatson	return (0);
509100979Srwatson}
510100979Srwatson
511100979Srwatsonstatic int
512100979Srwatsonmac_policy_unregister(struct mac_policy_conf *mpc)
513100979Srwatson{
514100979Srwatson
515104520Srwatson	/*
516104520Srwatson	 * If we fail the load, we may get a request to unload.  Check
517104520Srwatson	 * to see if we did the run-time registration, and if not,
518104520Srwatson	 * silently succeed.
519104520Srwatson	 */
520104520Srwatson	MAC_POLICY_LIST_LOCK();
521104520Srwatson	if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) {
522104520Srwatson		MAC_POLICY_LIST_UNLOCK();
523104520Srwatson		return (0);
524104520Srwatson	}
525100979Srwatson#if 0
526100979Srwatson	/*
527100979Srwatson	 * Don't allow unloading modules with private data.
528100979Srwatson	 */
529104520Srwatson	if (mpc->mpc_field_off != NULL) {
530104520Srwatson		MAC_POLICY_LIST_UNLOCK();
531100979Srwatson		return (EBUSY);
532104520Srwatson	}
533100979Srwatson#endif
534104520Srwatson	/*
535104520Srwatson	 * Only allow the unload to proceed if the module is unloadable
536104520Srwatson	 * by its own definition.
537104520Srwatson	 */
538104520Srwatson	if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) {
539104520Srwatson		MAC_POLICY_LIST_UNLOCK();
540100979Srwatson		return (EBUSY);
541104520Srwatson	}
542104520Srwatson	/*
543104520Srwatson	 * Right now, we EBUSY if the list is in use.  In the future,
544104520Srwatson	 * for reliability reasons, we might want to sleep and wakeup
545104520Srwatson	 * later to try again.
546104520Srwatson	 */
547100979Srwatson	if (mac_policy_list_busy > 0) {
548100979Srwatson		MAC_POLICY_LIST_UNLOCK();
549100979Srwatson		return (EBUSY);
550100979Srwatson	}
551100979Srwatson	if (mpc->mpc_ops->mpo_destroy != NULL)
552100979Srwatson		(*(mpc->mpc_ops->mpo_destroy))(mpc);
553100979Srwatson
554100979Srwatson	LIST_REMOVE(mpc, mpc_list);
555100979Srwatson	MAC_POLICY_LIST_UNLOCK();
556100979Srwatson
557105474Srwatson	mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED;
558100979Srwatson
559100979Srwatson	printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname,
560100979Srwatson	    mpc->mpc_name);
561100979Srwatson
562100979Srwatson	return (0);
563100979Srwatson}
564100979Srwatson
565100979Srwatson/*
566100979Srwatson * Define an error value precedence, and given two arguments, selects the
567100979Srwatson * value with the higher precedence.
568100979Srwatson */
569100979Srwatsonstatic int
570100979Srwatsonerror_select(int error1, int error2)
571100979Srwatson{
572100979Srwatson
573100979Srwatson	/* Certain decision-making errors take top priority. */
574100979Srwatson	if (error1 == EDEADLK || error2 == EDEADLK)
575100979Srwatson		return (EDEADLK);
576100979Srwatson
577100979Srwatson	/* Invalid arguments should be reported where possible. */
578100979Srwatson	if (error1 == EINVAL || error2 == EINVAL)
579100979Srwatson		return (EINVAL);
580100979Srwatson
581100979Srwatson	/* Precedence goes to "visibility", with both process and file. */
582100979Srwatson	if (error1 == ESRCH || error2 == ESRCH)
583100979Srwatson		return (ESRCH);
584100979Srwatson
585100979Srwatson	if (error1 == ENOENT || error2 == ENOENT)
586100979Srwatson		return (ENOENT);
587100979Srwatson
588100979Srwatson	/* Precedence goes to DAC/MAC protections. */
589100979Srwatson	if (error1 == EACCES || error2 == EACCES)
590100979Srwatson		return (EACCES);
591100979Srwatson
592100979Srwatson	/* Precedence goes to privilege. */
593100979Srwatson	if (error1 == EPERM || error2 == EPERM)
594100979Srwatson		return (EPERM);
595100979Srwatson
596100979Srwatson	/* Precedence goes to error over success; otherwise, arbitrary. */
597100979Srwatson	if (error1 != 0)
598100979Srwatson		return (error1);
599100979Srwatson	return (error2);
600100979Srwatson}
601100979Srwatson
602104521Srwatsonstatic void
603104521Srwatsonmac_init_label(struct label *label)
604104521Srwatson{
605104521Srwatson
606104521Srwatson	bzero(label, sizeof(*label));
607104521Srwatson	label->l_flags = MAC_FLAG_INITIALIZED;
608104521Srwatson}
609104521Srwatson
610104521Srwatsonstatic void
611104521Srwatsonmac_destroy_label(struct label *label)
612104521Srwatson{
613104521Srwatson
614104521Srwatson	KASSERT(label->l_flags & MAC_FLAG_INITIALIZED,
615104521Srwatson	    ("destroying uninitialized label"));
616104521Srwatson
617104521Srwatson	bzero(label, sizeof(*label));
618104521Srwatson	/* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */
619104521Srwatson}
620104521Srwatson
621100979Srwatsonvoid
622104527Srwatsonmac_init_bpfdesc(struct bpf_d *bpf_d)
623104521Srwatson{
624104521Srwatson
625104527Srwatson	mac_init_label(&bpf_d->bd_label);
626104527Srwatson	MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label);
627104521Srwatson#ifdef MAC_DEBUG
628104527Srwatson	atomic_add_int(&nmacbpfdescs, 1);
629104521Srwatson#endif
630104521Srwatson}
631104521Srwatson
632105694Srwatsonstatic void
633105694Srwatsonmac_init_cred_label(struct label *label)
634104521Srwatson{
635104521Srwatson
636105694Srwatson	mac_init_label(label);
637105694Srwatson	MAC_PERFORM(init_cred_label, label);
638104521Srwatson#ifdef MAC_DEBUG
639104521Srwatson	atomic_add_int(&nmaccreds, 1);
640104521Srwatson#endif
641104521Srwatson}
642104521Srwatson
643104521Srwatsonvoid
644105694Srwatsonmac_init_cred(struct ucred *cred)
645105694Srwatson{
646105694Srwatson
647105694Srwatson	mac_init_cred_label(&cred->cr_label);
648105694Srwatson}
649105694Srwatson
650105694Srwatsonvoid
651104527Srwatsonmac_init_devfsdirent(struct devfs_dirent *de)
652104521Srwatson{
653104521Srwatson
654104527Srwatson	mac_init_label(&de->de_label);
655104527Srwatson	MAC_PERFORM(init_devfsdirent_label, &de->de_label);
656104521Srwatson#ifdef MAC_DEBUG
657104527Srwatson	atomic_add_int(&nmacdevfsdirents, 1);
658104521Srwatson#endif
659104521Srwatson}
660104521Srwatson
661105694Srwatsonstatic void
662105694Srwatsonmac_init_ifnet_label(struct label *label)
663104521Srwatson{
664104521Srwatson
665105694Srwatson	mac_init_label(label);
666105694Srwatson	MAC_PERFORM(init_ifnet_label, label);
667104521Srwatson#ifdef MAC_DEBUG
668104521Srwatson	atomic_add_int(&nmacifnets, 1);
669104521Srwatson#endif
670104521Srwatson}
671104521Srwatson
672104521Srwatsonvoid
673105694Srwatsonmac_init_ifnet(struct ifnet *ifp)
674105694Srwatson{
675105694Srwatson
676105694Srwatson	mac_init_ifnet_label(&ifp->if_label);
677105694Srwatson}
678105694Srwatson
679105694Srwatsonvoid
680104527Srwatsonmac_init_ipq(struct ipq *ipq)
681104521Srwatson{
682104521Srwatson
683104527Srwatson	mac_init_label(&ipq->ipq_label);
684104527Srwatson	MAC_PERFORM(init_ipq_label, &ipq->ipq_label);
685104521Srwatson#ifdef MAC_DEBUG
686104527Srwatson	atomic_add_int(&nmacipqs, 1);
687104521Srwatson#endif
688104521Srwatson}
689104521Srwatson
690104527Srwatsonint
691104527Srwatsonmac_init_mbuf(struct mbuf *m, int flag)
692104527Srwatson{
693104528Srwatson	int error;
694104528Srwatson
695104527Srwatson	KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf"));
696104527Srwatson
697104527Srwatson	mac_init_label(&m->m_pkthdr.label);
698104527Srwatson
699104528Srwatson	MAC_CHECK(init_mbuf_label, &m->m_pkthdr.label, flag);
700104528Srwatson	if (error) {
701104528Srwatson		MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label);
702104528Srwatson		mac_destroy_label(&m->m_pkthdr.label);
703104528Srwatson	}
704104528Srwatson
705104527Srwatson#ifdef MAC_DEBUG
706104528Srwatson	if (error == 0)
707104528Srwatson		atomic_add_int(&nmacmbufs, 1);
708104527Srwatson#endif
709104528Srwatson	return (error);
710104527Srwatson}
711104527Srwatson
712104521Srwatsonvoid
713104527Srwatsonmac_init_mount(struct mount *mp)
714104521Srwatson{
715104521Srwatson
716104527Srwatson	mac_init_label(&mp->mnt_mntlabel);
717104527Srwatson	mac_init_label(&mp->mnt_fslabel);
718104527Srwatson	MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel);
719104527Srwatson	MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel);
720104521Srwatson#ifdef MAC_DEBUG
721104527Srwatson	atomic_add_int(&nmacmounts, 1);
722104521Srwatson#endif
723104521Srwatson}
724104521Srwatson
725105694Srwatsonstatic void
726105694Srwatsonmac_init_pipe_label(struct label *label)
727105694Srwatson{
728105694Srwatson
729105694Srwatson	mac_init_label(label);
730105694Srwatson	MAC_PERFORM(init_pipe_label, label);
731105694Srwatson#ifdef MAC_DEBUG
732105694Srwatson	atomic_add_int(&nmacpipes, 1);
733105694Srwatson#endif
734105694Srwatson}
735105694Srwatson
736104521Srwatsonvoid
737104527Srwatsonmac_init_pipe(struct pipe *pipe)
738104521Srwatson{
739104527Srwatson	struct label *label;
740104521Srwatson
741104527Srwatson	label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK);
742104527Srwatson	pipe->pipe_label = label;
743104527Srwatson	pipe->pipe_peer->pipe_label = label;
744105694Srwatson	mac_init_pipe_label(label);
745104521Srwatson}
746104521Srwatson
747104541Srwatsonstatic int
748104541Srwatsonmac_init_socket_label(struct label *label, int flag)
749104521Srwatson{
750104541Srwatson	int error;
751104521Srwatson
752104541Srwatson	mac_init_label(label);
753104541Srwatson
754104541Srwatson	MAC_CHECK(init_socket_label, label, flag);
755104541Srwatson	if (error) {
756104541Srwatson		MAC_PERFORM(destroy_socket_label, label);
757104541Srwatson		mac_destroy_label(label);
758104541Srwatson	}
759104541Srwatson
760104521Srwatson#ifdef MAC_DEBUG
761104541Srwatson	if (error == 0)
762104541Srwatson		atomic_add_int(&nmacsockets, 1);
763104521Srwatson#endif
764104541Srwatson
765104541Srwatson	return (error);
766104521Srwatson}
767104521Srwatson
768104541Srwatsonstatic int
769104541Srwatsonmac_init_socket_peer_label(struct label *label, int flag)
770104541Srwatson{
771104541Srwatson	int error;
772104541Srwatson
773104541Srwatson	mac_init_label(label);
774104541Srwatson
775104541Srwatson	MAC_CHECK(init_socket_peer_label, label, flag);
776104541Srwatson	if (error) {
777104541Srwatson		MAC_PERFORM(destroy_socket_label, label);
778104541Srwatson		mac_destroy_label(label);
779104541Srwatson	}
780104541Srwatson
781104541Srwatson	return (error);
782104541Srwatson}
783104541Srwatson
784104541Srwatsonint
785104541Srwatsonmac_init_socket(struct socket *socket, int flag)
786104541Srwatson{
787104541Srwatson	int error;
788104541Srwatson
789104541Srwatson	error = mac_init_socket_label(&socket->so_label, flag);
790104541Srwatson	if (error)
791104541Srwatson		return (error);
792104541Srwatson
793104541Srwatson	error = mac_init_socket_peer_label(&socket->so_peerlabel, flag);
794104541Srwatson	if (error)
795104541Srwatson		mac_destroy_socket_label(&socket->so_label);
796104541Srwatson
797104541Srwatson	return (error);
798104541Srwatson}
799104541Srwatson
800105988Srwatsonvoid
801105694Srwatsonmac_init_vnode_label(struct label *label)
802104521Srwatson{
803104521Srwatson
804104527Srwatson	mac_init_label(label);
805105694Srwatson	MAC_PERFORM(init_vnode_label, label);
806104521Srwatson#ifdef MAC_DEBUG
807105694Srwatson	atomic_add_int(&nmacvnodes, 1);
808104521Srwatson#endif
809104521Srwatson}
810104521Srwatson
811104521Srwatsonvoid
812104527Srwatsonmac_init_vnode(struct vnode *vp)
813104521Srwatson{
814104521Srwatson
815105694Srwatson	mac_init_vnode_label(&vp->v_label);
816104521Srwatson}
817104521Srwatson
818104521Srwatsonvoid
819104527Srwatsonmac_destroy_bpfdesc(struct bpf_d *bpf_d)
820104521Srwatson{
821104521Srwatson
822104527Srwatson	MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label);
823104527Srwatson	mac_destroy_label(&bpf_d->bd_label);
824104521Srwatson#ifdef MAC_DEBUG
825104527Srwatson	atomic_subtract_int(&nmacbpfdescs, 1);
826104521Srwatson#endif
827104521Srwatson}
828104521Srwatson
829105694Srwatsonstatic void
830105694Srwatsonmac_destroy_cred_label(struct label *label)
831104521Srwatson{
832104521Srwatson
833105694Srwatson	MAC_PERFORM(destroy_cred_label, label);
834105694Srwatson	mac_destroy_label(label);
835104521Srwatson#ifdef MAC_DEBUG
836104527Srwatson	atomic_subtract_int(&nmaccreds, 1);
837104521Srwatson#endif
838104521Srwatson}
839104521Srwatson
840104521Srwatsonvoid
841105694Srwatsonmac_destroy_cred(struct ucred *cred)
842105694Srwatson{
843105694Srwatson
844105694Srwatson	mac_destroy_cred_label(&cred->cr_label);
845105694Srwatson}
846105694Srwatson
847105694Srwatsonvoid
848104527Srwatsonmac_destroy_devfsdirent(struct devfs_dirent *de)
849104521Srwatson{
850104521Srwatson
851104527Srwatson	MAC_PERFORM(destroy_devfsdirent_label, &de->de_label);
852104527Srwatson	mac_destroy_label(&de->de_label);
853104521Srwatson#ifdef MAC_DEBUG
854104527Srwatson	atomic_subtract_int(&nmacdevfsdirents, 1);
855104521Srwatson#endif
856104521Srwatson}
857104521Srwatson
858105694Srwatsonstatic void
859105694Srwatsonmac_destroy_ifnet_label(struct label *label)
860104521Srwatson{
861104521Srwatson
862105694Srwatson	MAC_PERFORM(destroy_ifnet_label, label);
863105694Srwatson	mac_destroy_label(label);
864104521Srwatson#ifdef MAC_DEBUG
865104527Srwatson	atomic_subtract_int(&nmacifnets, 1);
866104521Srwatson#endif
867104521Srwatson}
868104521Srwatson
869104521Srwatsonvoid
870105694Srwatsonmac_destroy_ifnet(struct ifnet *ifp)
871105694Srwatson{
872105694Srwatson
873105694Srwatson	mac_destroy_ifnet_label(&ifp->if_label);
874105694Srwatson}
875105694Srwatson
876105694Srwatsonvoid
877104527Srwatsonmac_destroy_ipq(struct ipq *ipq)
878104521Srwatson{
879104521Srwatson
880104527Srwatson	MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label);
881104527Srwatson	mac_destroy_label(&ipq->ipq_label);
882104521Srwatson#ifdef MAC_DEBUG
883104527Srwatson	atomic_subtract_int(&nmacipqs, 1);
884104521Srwatson#endif
885104521Srwatson}
886104521Srwatson
887104527Srwatsonvoid
888104527Srwatsonmac_destroy_mbuf(struct mbuf *m)
889104521Srwatson{
890104521Srwatson
891104527Srwatson	MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label);
892104527Srwatson	mac_destroy_label(&m->m_pkthdr.label);
893104521Srwatson#ifdef MAC_DEBUG
894104527Srwatson	atomic_subtract_int(&nmacmbufs, 1);
895104521Srwatson#endif
896104521Srwatson}
897104521Srwatson
898104527Srwatsonvoid
899104527Srwatsonmac_destroy_mount(struct mount *mp)
900104521Srwatson{
901104521Srwatson
902104527Srwatson	MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel);
903104527Srwatson	MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel);
904104527Srwatson	mac_destroy_label(&mp->mnt_fslabel);
905104527Srwatson	mac_destroy_label(&mp->mnt_mntlabel);
906104521Srwatson#ifdef MAC_DEBUG
907104527Srwatson	atomic_subtract_int(&nmacmounts, 1);
908104521Srwatson#endif
909104521Srwatson}
910104521Srwatson
911105694Srwatsonstatic void
912105694Srwatsonmac_destroy_pipe_label(struct label *label)
913104521Srwatson{
914104521Srwatson
915105694Srwatson	MAC_PERFORM(destroy_pipe_label, label);
916105694Srwatson	mac_destroy_label(label);
917104521Srwatson#ifdef MAC_DEBUG
918104527Srwatson	atomic_subtract_int(&nmacpipes, 1);
919104521Srwatson#endif
920104521Srwatson}
921104521Srwatson
922105694Srwatsonvoid
923105694Srwatsonmac_destroy_pipe(struct pipe *pipe)
924105694Srwatson{
925105694Srwatson
926105694Srwatson	mac_destroy_pipe_label(pipe->pipe_label);
927105694Srwatson	free(pipe->pipe_label, M_MACPIPELABEL);
928105694Srwatson}
929105694Srwatson
930104541Srwatsonstatic void
931104541Srwatsonmac_destroy_socket_label(struct label *label)
932104521Srwatson{
933104521Srwatson
934104541Srwatson	MAC_PERFORM(destroy_socket_label, label);
935104541Srwatson	mac_destroy_label(label);
936104521Srwatson#ifdef MAC_DEBUG
937104527Srwatson	atomic_subtract_int(&nmacsockets, 1);
938104521Srwatson#endif
939104521Srwatson}
940104521Srwatson
941104527Srwatsonstatic void
942104541Srwatsonmac_destroy_socket_peer_label(struct label *label)
943104541Srwatson{
944104541Srwatson
945104541Srwatson	MAC_PERFORM(destroy_socket_peer_label, label);
946104541Srwatson	mac_destroy_label(label);
947104541Srwatson}
948104541Srwatson
949104541Srwatsonvoid
950104541Srwatsonmac_destroy_socket(struct socket *socket)
951104541Srwatson{
952104541Srwatson
953104541Srwatson	mac_destroy_socket_label(&socket->so_label);
954104541Srwatson	mac_destroy_socket_peer_label(&socket->so_peerlabel);
955104541Srwatson}
956104541Srwatson
957105988Srwatsonvoid
958105694Srwatsonmac_destroy_vnode_label(struct label *label)
959104521Srwatson{
960104521Srwatson
961105694Srwatson	MAC_PERFORM(destroy_vnode_label, label);
962104527Srwatson	mac_destroy_label(label);
963104521Srwatson#ifdef MAC_DEBUG
964105694Srwatson	atomic_subtract_int(&nmacvnodes, 1);
965104521Srwatson#endif
966104521Srwatson}
967104521Srwatson
968104521Srwatsonvoid
969104527Srwatsonmac_destroy_vnode(struct vnode *vp)
970104521Srwatson{
971104521Srwatson
972105694Srwatson	mac_destroy_vnode_label(&vp->v_label);
973104521Srwatson}
974104521Srwatson
975105694Srwatsonstatic void
976105694Srwatsonmac_copy_pipe_label(struct label *src, struct label *dest)
977105694Srwatson{
978105694Srwatson
979105694Srwatson	MAC_PERFORM(copy_pipe_label, src, dest);
980105694Srwatson}
981105694Srwatson
982105988Srwatsonvoid
983105694Srwatsonmac_copy_vnode_label(struct label *src, struct label *dest)
984105694Srwatson{
985105694Srwatson
986105694Srwatson	MAC_PERFORM(copy_vnode_label, src, dest);
987105694Srwatson}
988105694Srwatson
989104522Srwatsonstatic int
990105694Srwatsonmac_check_structmac_consistent(struct mac *mac)
991104522Srwatson{
992105694Srwatson
993105694Srwatson	if (mac->m_buflen > MAC_MAX_LABEL_BUF_LEN)
994105694Srwatson		return (EINVAL);
995105694Srwatson
996105694Srwatson	return (0);
997105694Srwatson}
998105694Srwatson
999105694Srwatsonstatic int
1000105694Srwatsonmac_externalize_cred_label(struct label *label, char *elements,
1001105694Srwatson    char *outbuf, size_t outbuflen, int flags)
1002105694Srwatson{
1003104522Srwatson	int error;
1004104522Srwatson
1005105694Srwatson	MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen);
1006104522Srwatson
1007104522Srwatson	return (error);
1008104522Srwatson}
1009104522Srwatson
1010104522Srwatsonstatic int
1011105694Srwatsonmac_externalize_ifnet_label(struct label *label, char *elements,
1012105694Srwatson    char *outbuf, size_t outbuflen, int flags)
1013104522Srwatson{
1014104522Srwatson	int error;
1015104522Srwatson
1016105694Srwatson	MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen);
1017104522Srwatson
1018104522Srwatson	return (error);
1019104522Srwatson}
1020104522Srwatson
1021105694Srwatsonstatic int
1022105694Srwatsonmac_externalize_pipe_label(struct label *label, char *elements,
1023105694Srwatson    char *outbuf, size_t outbuflen, int flags)
1024105694Srwatson{
1025105694Srwatson	int error;
1026105694Srwatson
1027105694Srwatson	MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen);
1028105694Srwatson
1029105694Srwatson	return (error);
1030105694Srwatson}
1031105694Srwatson
1032105694Srwatsonstatic int
1033105694Srwatsonmac_externalize_socket_label(struct label *label, char *elements,
1034105694Srwatson    char *outbuf, size_t outbuflen, int flags)
1035105694Srwatson{
1036105694Srwatson	int error;
1037105694Srwatson
1038105694Srwatson	MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen);
1039105694Srwatson
1040105694Srwatson	return (error);
1041105694Srwatson}
1042105694Srwatson
1043105694Srwatsonstatic int
1044105694Srwatsonmac_externalize_socket_peer_label(struct label *label, char *elements,
1045105694Srwatson    char *outbuf, size_t outbuflen, int flags)
1046105694Srwatson{
1047105694Srwatson	int error;
1048105694Srwatson
1049105694Srwatson	MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen);
1050105694Srwatson
1051105694Srwatson	return (error);
1052105694Srwatson}
1053105694Srwatson
1054105694Srwatsonstatic int
1055105694Srwatsonmac_externalize_vnode_label(struct label *label, char *elements,
1056105694Srwatson    char *outbuf, size_t outbuflen, int flags)
1057105694Srwatson{
1058105694Srwatson	int error;
1059105694Srwatson
1060105694Srwatson	MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen);
1061105694Srwatson
1062105694Srwatson	return (error);
1063105694Srwatson}
1064105694Srwatson
1065105694Srwatsonstatic int
1066105694Srwatsonmac_internalize_cred_label(struct label *label, char *string)
1067105694Srwatson{
1068105694Srwatson	int error;
1069105694Srwatson
1070105694Srwatson	MAC_INTERNALIZE(cred_label, label, string);
1071105694Srwatson
1072105694Srwatson	return (error);
1073105694Srwatson}
1074105694Srwatson
1075105694Srwatsonstatic int
1076105694Srwatsonmac_internalize_ifnet_label(struct label *label, char *string)
1077105694Srwatson{
1078105694Srwatson	int error;
1079105694Srwatson
1080105694Srwatson	MAC_INTERNALIZE(ifnet_label, label, string);
1081105694Srwatson
1082105694Srwatson	return (error);
1083105694Srwatson}
1084105694Srwatson
1085105694Srwatsonstatic int
1086105694Srwatsonmac_internalize_pipe_label(struct label *label, char *string)
1087105694Srwatson{
1088105694Srwatson	int error;
1089105694Srwatson
1090105694Srwatson	MAC_INTERNALIZE(pipe_label, label, string);
1091105694Srwatson
1092105694Srwatson	return (error);
1093105694Srwatson}
1094105694Srwatson
1095105694Srwatsonstatic int
1096105694Srwatsonmac_internalize_socket_label(struct label *label, char *string)
1097105694Srwatson{
1098105694Srwatson	int error;
1099105694Srwatson
1100105694Srwatson	MAC_INTERNALIZE(socket_label, label, string);
1101105694Srwatson
1102105694Srwatson	return (error);
1103105694Srwatson}
1104105694Srwatson
1105105694Srwatsonstatic int
1106105694Srwatsonmac_internalize_vnode_label(struct label *label, char *string)
1107105694Srwatson{
1108105694Srwatson	int error;
1109105694Srwatson
1110105694Srwatson	MAC_INTERNALIZE(vnode_label, label, string);
1111105694Srwatson
1112105694Srwatson	return (error);
1113105694Srwatson}
1114105694Srwatson
1115104522Srwatson/*
1116104522Srwatson * Initialize MAC label for the first kernel process, from which other
1117104522Srwatson * kernel processes and threads are spawned.
1118104522Srwatson */
1119104521Srwatsonvoid
1120104522Srwatsonmac_create_proc0(struct ucred *cred)
1121104522Srwatson{
1122104522Srwatson
1123104522Srwatson	MAC_PERFORM(create_proc0, cred);
1124104522Srwatson}
1125104522Srwatson
1126104522Srwatson/*
1127104522Srwatson * Initialize MAC label for the first userland process, from which other
1128104522Srwatson * userland processes and threads are spawned.
1129104522Srwatson */
1130104522Srwatsonvoid
1131104522Srwatsonmac_create_proc1(struct ucred *cred)
1132104522Srwatson{
1133104522Srwatson
1134104522Srwatson	MAC_PERFORM(create_proc1, cred);
1135104522Srwatson}
1136104522Srwatson
1137104522Srwatsonvoid
1138104522Srwatsonmac_thread_userret(struct thread *td)
1139104522Srwatson{
1140104522Srwatson
1141104522Srwatson	MAC_PERFORM(thread_userret, td);
1142104522Srwatson}
1143104522Srwatson
1144104522Srwatson/*
1145104522Srwatson * When a new process is created, its label must be initialized.  Generally,
1146104522Srwatson * this involves inheritence from the parent process, modulo possible
1147104522Srwatson * deltas.  This function allows that processing to take place.
1148104522Srwatson */
1149104522Srwatsonvoid
1150104522Srwatsonmac_create_cred(struct ucred *parent_cred, struct ucred *child_cred)
1151104522Srwatson{
1152104522Srwatson
1153104522Srwatson	MAC_PERFORM(create_cred, parent_cred, child_cred);
1154104522Srwatson}
1155104522Srwatson
1156104522Srwatsonvoid
1157100979Srwatsonmac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp)
1158100979Srwatson{
1159100979Srwatson
1160100979Srwatson	MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label);
1161100979Srwatson}
1162100979Srwatson
1163100979Srwatsonvoid
1164105988Srwatsonmac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de,
1165105988Srwatson    struct vnode *vp)
1166100979Srwatson{
1167100979Srwatson
1168105988Srwatson	MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de,
1169105988Srwatson	    &de->de_label, vp, &vp->v_label);
1170100979Srwatson}
1171100979Srwatson
1172105988Srwatsonint
1173105988Srwatsonmac_associate_vnode_extattr(struct mount *mp, struct vnode *vp)
1174100979Srwatson{
1175100979Srwatson	int error;
1176100979Srwatson
1177105988Srwatson	ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr");
1178100979Srwatson
1179105988Srwatson	MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp,
1180105988Srwatson	    &vp->v_label);
1181100979Srwatson
1182100979Srwatson	return (error);
1183100979Srwatson}
1184100979Srwatson
1185100979Srwatsonvoid
1186105988Srwatsonmac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp)
1187100979Srwatson{
1188100979Srwatson
1189105988Srwatson	MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp,
1190105988Srwatson	    &vp->v_label);
1191100979Srwatson}
1192100979Srwatson
1193100979Srwatsonint
1194105988Srwatsonmac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
1195105988Srwatson    struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
1196100979Srwatson{
1197105988Srwatson	int error;
1198100979Srwatson
1199105988Srwatson	ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr");
1200105988Srwatson	ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr");
1201100979Srwatson
1202105988Srwatson	error = VOP_OPENEXTATTR(vp, cred, curthread);
1203105988Srwatson	if (error == EOPNOTSUPP) {
1204105988Srwatson		/* XXX: Optionally abort if transactions not supported. */
1205105988Srwatson		if (ea_warn_once == 0) {
1206105988Srwatson			printf("Warning: transactions not supported "
1207105988Srwatson			    "in EA write.\n");
1208105988Srwatson			ea_warn_once = 1;
1209105988Srwatson		}
1210105988Srwatson	} else if (error)
1211100979Srwatson		return (error);
1212100979Srwatson
1213105988Srwatson	MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel,
1214105988Srwatson	    dvp, &dvp->v_label, vp, &vp->v_label, cnp);
1215100979Srwatson
1216105988Srwatson	if (error) {
1217105988Srwatson		VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
1218100979Srwatson		return (error);
1219100979Srwatson	}
1220100979Srwatson
1221105988Srwatson	error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
1222100979Srwatson
1223105988Srwatson	if (error == EOPNOTSUPP)
1224105988Srwatson		error = 0;				/* XXX */
1225100979Srwatson
1226100979Srwatson	return (error);
1227100979Srwatson}
1228100979Srwatson
1229100979Srwatsonstatic int
1230105988Srwatsonmac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
1231105988Srwatson    struct label *intlabel)
1232100979Srwatson{
1233100979Srwatson	int error;
1234100979Srwatson
1235105988Srwatson	ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr");
1236100979Srwatson
1237105988Srwatson	error = VOP_OPENEXTATTR(vp, cred, curthread);
1238105988Srwatson	if (error == EOPNOTSUPP) {
1239105988Srwatson		/* XXX: Optionally abort if transactions not supported. */
1240105988Srwatson		if (ea_warn_once == 0) {
1241105988Srwatson			printf("Warning: transactions not supported "
1242105988Srwatson			    "in EA write.\n");
1243105988Srwatson			ea_warn_once = 1;
1244105988Srwatson		}
1245105988Srwatson	} else if (error)
1246105988Srwatson		return (error);
1247100979Srwatson
1248105988Srwatson	MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel);
1249100979Srwatson
1250105988Srwatson	if (error) {
1251105988Srwatson		VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
1252100979Srwatson		return (error);
1253100979Srwatson	}
1254100979Srwatson
1255105988Srwatson	error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
1256100979Srwatson
1257105988Srwatson	if (error == EOPNOTSUPP)
1258105988Srwatson		error = 0;				/* XXX */
1259100979Srwatson
1260105988Srwatson	return (error);
1261100979Srwatson}
1262100979Srwatson
1263100979Srwatsonvoid
1264100979Srwatsonmac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp)
1265100979Srwatson{
1266100979Srwatson
1267100979Srwatson	ASSERT_VOP_LOCKED(vp, "mac_execve_transition");
1268100979Srwatson
1269100979Srwatson	MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label);
1270100979Srwatson}
1271100979Srwatson
1272100979Srwatsonint
1273100979Srwatsonmac_execve_will_transition(struct ucred *old, struct vnode *vp)
1274100979Srwatson{
1275105988Srwatson	int result;
1276100979Srwatson
1277100979Srwatson	result = 0;
1278100979Srwatson	MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label);
1279100979Srwatson
1280100979Srwatson	return (result);
1281100979Srwatson}
1282100979Srwatson
1283100979Srwatsonint
1284106212Srwatsonmac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode)
1285100979Srwatson{
1286100979Srwatson	int error;
1287100979Srwatson
1288100979Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access");
1289100979Srwatson
1290100979Srwatson	if (!mac_enforce_fs)
1291100979Srwatson		return (0);
1292100979Srwatson
1293106212Srwatson	MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, acc_mode);
1294100979Srwatson	return (error);
1295100979Srwatson}
1296100979Srwatson
1297100979Srwatsonint
1298100979Srwatsonmac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp)
1299100979Srwatson{
1300100979Srwatson	int error;
1301100979Srwatson
1302100979Srwatson	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir");
1303100979Srwatson
1304100979Srwatson	if (!mac_enforce_fs)
1305100979Srwatson		return (0);
1306100979Srwatson
1307100979Srwatson	MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label);
1308100979Srwatson	return (error);
1309100979Srwatson}
1310100979Srwatson
1311100979Srwatsonint
1312100979Srwatsonmac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp)
1313100979Srwatson{
1314100979Srwatson	int error;
1315100979Srwatson
1316100979Srwatson	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot");
1317100979Srwatson
1318100979Srwatson	if (!mac_enforce_fs)
1319100979Srwatson		return (0);
1320100979Srwatson
1321100979Srwatson	MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label);
1322100979Srwatson	return (error);
1323100979Srwatson}
1324100979Srwatson
1325100979Srwatsonint
1326100979Srwatsonmac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
1327100979Srwatson    struct componentname *cnp, struct vattr *vap)
1328100979Srwatson{
1329100979Srwatson	int error;
1330100979Srwatson
1331100979Srwatson	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create");
1332100979Srwatson
1333100979Srwatson	if (!mac_enforce_fs)
1334100979Srwatson		return (0);
1335100979Srwatson
1336100979Srwatson	MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap);
1337100979Srwatson	return (error);
1338100979Srwatson}
1339100979Srwatson
1340100979Srwatsonint
1341100979Srwatsonmac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp,
1342100979Srwatson    struct componentname *cnp)
1343100979Srwatson{
1344100979Srwatson	int error;
1345100979Srwatson
1346100979Srwatson	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete");
1347100979Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete");
1348100979Srwatson
1349100979Srwatson	if (!mac_enforce_fs)
1350100979Srwatson		return (0);
1351100979Srwatson
1352100979Srwatson	MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp,
1353100979Srwatson	    &vp->v_label, cnp);
1354100979Srwatson	return (error);
1355100979Srwatson}
1356100979Srwatson
1357100979Srwatsonint
1358100979Srwatsonmac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
1359100979Srwatson    acl_type_t type)
1360100979Srwatson{
1361100979Srwatson	int error;
1362100979Srwatson
1363100979Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl");
1364100979Srwatson
1365100979Srwatson	if (!mac_enforce_fs)
1366100979Srwatson		return (0);
1367100979Srwatson
1368100979Srwatson	MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type);
1369100979Srwatson	return (error);
1370100979Srwatson}
1371100979Srwatson
1372100979Srwatsonint
1373100979Srwatsonmac_check_vnode_exec(struct ucred *cred, struct vnode *vp)
1374100979Srwatson{
1375100979Srwatson	int error;
1376100979Srwatson
1377102102Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec");
1378102102Srwatson
1379100979Srwatson	if (!mac_enforce_process && !mac_enforce_fs)
1380100979Srwatson		return (0);
1381100979Srwatson
1382100979Srwatson	MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label);
1383100979Srwatson
1384100979Srwatson	return (error);
1385100979Srwatson}
1386100979Srwatson
1387100979Srwatsonint
1388100979Srwatsonmac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
1389100979Srwatson{
1390100979Srwatson	int error;
1391100979Srwatson
1392100979Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl");
1393100979Srwatson
1394100979Srwatson	if (!mac_enforce_fs)
1395100979Srwatson		return (0);
1396100979Srwatson
1397100979Srwatson	MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type);
1398100979Srwatson	return (error);
1399100979Srwatson}
1400100979Srwatson
1401100979Srwatsonint
1402100979Srwatsonmac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
1403100979Srwatson    int attrnamespace, const char *name, struct uio *uio)
1404100979Srwatson{
1405100979Srwatson	int error;
1406100979Srwatson
1407100979Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr");
1408100979Srwatson
1409100979Srwatson	if (!mac_enforce_fs)
1410100979Srwatson		return (0);
1411100979Srwatson
1412100979Srwatson	MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label,
1413100979Srwatson	    attrnamespace, name, uio);
1414100979Srwatson	return (error);
1415100979Srwatson}
1416100979Srwatson
1417100979Srwatsonint
1418104529Srwatsonmac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
1419104529Srwatson    struct vnode *vp, struct componentname *cnp)
1420104529Srwatson{
1421104529Srwatson	int error;
1422104529Srwatson
1423104529Srwatson	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link");
1424104529Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link");
1425104529Srwatson
1426104529Srwatson	if (!mac_enforce_fs)
1427104529Srwatson		return (0);
1428104529Srwatson
1429104529Srwatson	MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp,
1430104529Srwatson	    &vp->v_label, cnp);
1431104529Srwatson	return (error);
1432104529Srwatson}
1433104529Srwatson
1434104529Srwatsonint
1435100979Srwatsonmac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
1436100979Srwatson    struct componentname *cnp)
1437100979Srwatson{
1438100979Srwatson	int error;
1439100979Srwatson
1440100979Srwatson	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup");
1441100979Srwatson
1442100979Srwatson	if (!mac_enforce_fs)
1443100979Srwatson		return (0);
1444100979Srwatson
1445100979Srwatson	MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp);
1446100979Srwatson	return (error);
1447100979Srwatson}
1448100979Srwatson
1449104546Srwatsonint
1450104546Srwatsonmac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot)
1451100979Srwatson{
1452104546Srwatson	int error;
1453100979Srwatson
1454104546Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap");
1455103514Srwatson
1456104546Srwatson	if (!mac_enforce_fs || !mac_enforce_vm)
1457104546Srwatson		return (0);
1458104546Srwatson
1459104546Srwatson	MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot);
1460104546Srwatson	return (error);
1461100979Srwatson}
1462100979Srwatson
1463104546Srwatsonvoid
1464104546Srwatsonmac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot)
1465104546Srwatson{
1466104546Srwatson	int result = *prot;
1467104546Srwatson
1468104546Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade");
1469104546Srwatson
1470104546Srwatson	if (!mac_enforce_fs || !mac_enforce_vm)
1471104546Srwatson		return;
1472104546Srwatson
1473104546Srwatson	MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label,
1474104546Srwatson	    &result);
1475104546Srwatson
1476104546Srwatson	*prot = result;
1477104546Srwatson}
1478104546Srwatson
1479100979Srwatsonint
1480104546Srwatsonmac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot)
1481104546Srwatson{
1482104546Srwatson	int error;
1483104546Srwatson
1484104546Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect");
1485104546Srwatson
1486104546Srwatson	if (!mac_enforce_fs || !mac_enforce_vm)
1487104546Srwatson		return (0);
1488104546Srwatson
1489104546Srwatson	MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot);
1490104546Srwatson	return (error);
1491104546Srwatson}
1492104546Srwatson
1493104546Srwatsonint
1494106212Srwatsonmac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode)
1495100979Srwatson{
1496100979Srwatson	int error;
1497100979Srwatson
1498102112Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open");
1499102112Srwatson
1500100979Srwatson	if (!mac_enforce_fs)
1501100979Srwatson		return (0);
1502100979Srwatson
1503102112Srwatson	MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode);
1504102112Srwatson	return (error);
1505102112Srwatson}
1506102112Srwatson
1507102112Srwatsonint
1508102129Srwatsonmac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
1509102129Srwatson    struct vnode *vp)
1510102112Srwatson{
1511102112Srwatson	int error;
1512102112Srwatson
1513102112Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll");
1514102112Srwatson
1515102112Srwatson	if (!mac_enforce_fs)
1516102112Srwatson		return (0);
1517102112Srwatson
1518102129Srwatson	MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp,
1519102129Srwatson	    &vp->v_label);
1520100979Srwatson
1521100979Srwatson	return (error);
1522100979Srwatson}
1523100979Srwatson
1524100979Srwatsonint
1525102129Srwatsonmac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
1526102129Srwatson    struct vnode *vp)
1527100979Srwatson{
1528100979Srwatson	int error;
1529100979Srwatson
1530102112Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read");
1531100979Srwatson
1532100979Srwatson	if (!mac_enforce_fs)
1533100979Srwatson		return (0);
1534100979Srwatson
1535102129Srwatson	MAC_CHECK(check_vnode_read, active_cred, file_cred, vp,
1536102129Srwatson	    &vp->v_label);
1537102112Srwatson
1538100979Srwatson	return (error);
1539100979Srwatson}
1540100979Srwatson
1541100979Srwatsonint
1542100979Srwatsonmac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp)
1543100979Srwatson{
1544100979Srwatson	int error;
1545100979Srwatson
1546100979Srwatson	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir");
1547100979Srwatson
1548100979Srwatson	if (!mac_enforce_fs)
1549100979Srwatson		return (0);
1550100979Srwatson
1551100979Srwatson	MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label);
1552100979Srwatson	return (error);
1553100979Srwatson}
1554100979Srwatson
1555100979Srwatsonint
1556100979Srwatsonmac_check_vnode_readlink(struct ucred *cred, struct vnode *vp)
1557100979Srwatson{
1558100979Srwatson	int error;
1559100979Srwatson
1560100979Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink");
1561100979Srwatson
1562100979Srwatson	if (!mac_enforce_fs)
1563100979Srwatson		return (0);
1564100979Srwatson
1565100979Srwatson	MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label);
1566100979Srwatson	return (error);
1567100979Srwatson}
1568100979Srwatson
1569100979Srwatsonstatic int
1570100979Srwatsonmac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
1571100979Srwatson    struct label *newlabel)
1572100979Srwatson{
1573100979Srwatson	int error;
1574100979Srwatson
1575100979Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel");
1576100979Srwatson
1577100979Srwatson	MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel);
1578100979Srwatson
1579100979Srwatson	return (error);
1580100979Srwatson}
1581100979Srwatson
1582100979Srwatsonint
1583100979Srwatsonmac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
1584100979Srwatson    struct vnode *vp, struct componentname *cnp)
1585100979Srwatson{
1586100979Srwatson	int error;
1587100979Srwatson
1588100979Srwatson	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from");
1589100979Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from");
1590100979Srwatson
1591100979Srwatson	if (!mac_enforce_fs)
1592100979Srwatson		return (0);
1593100979Srwatson
1594100979Srwatson	MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp,
1595100979Srwatson	    &vp->v_label, cnp);
1596100979Srwatson	return (error);
1597100979Srwatson}
1598100979Srwatson
1599100979Srwatsonint
1600100979Srwatsonmac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
1601100979Srwatson    struct vnode *vp, int samedir, struct componentname *cnp)
1602100979Srwatson{
1603100979Srwatson	int error;
1604100979Srwatson
1605100979Srwatson	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to");
1606100979Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to");
1607100979Srwatson
1608100979Srwatson	if (!mac_enforce_fs)
1609100979Srwatson		return (0);
1610100979Srwatson
1611100979Srwatson	MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp,
1612100979Srwatson	    vp != NULL ? &vp->v_label : NULL, samedir, cnp);
1613100979Srwatson	return (error);
1614100979Srwatson}
1615100979Srwatson
1616100979Srwatsonint
1617100979Srwatsonmac_check_vnode_revoke(struct ucred *cred, struct vnode *vp)
1618100979Srwatson{
1619100979Srwatson	int error;
1620100979Srwatson
1621100979Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke");
1622100979Srwatson
1623100979Srwatson	if (!mac_enforce_fs)
1624100979Srwatson		return (0);
1625100979Srwatson
1626100979Srwatson	MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label);
1627100979Srwatson	return (error);
1628100979Srwatson}
1629100979Srwatson
1630100979Srwatsonint
1631100979Srwatsonmac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
1632100979Srwatson    struct acl *acl)
1633100979Srwatson{
1634100979Srwatson	int error;
1635100979Srwatson
1636100979Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl");
1637100979Srwatson
1638100979Srwatson	if (!mac_enforce_fs)
1639100979Srwatson		return (0);
1640100979Srwatson
1641100979Srwatson	MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl);
1642100979Srwatson	return (error);
1643100979Srwatson}
1644100979Srwatson
1645100979Srwatsonint
1646100979Srwatsonmac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
1647100979Srwatson    int attrnamespace, const char *name, struct uio *uio)
1648100979Srwatson{
1649100979Srwatson	int error;
1650100979Srwatson
1651100979Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr");
1652100979Srwatson
1653100979Srwatson	if (!mac_enforce_fs)
1654100979Srwatson		return (0);
1655100979Srwatson
1656100979Srwatson	MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label,
1657100979Srwatson	    attrnamespace, name, uio);
1658100979Srwatson	return (error);
1659100979Srwatson}
1660100979Srwatson
1661100979Srwatsonint
1662100979Srwatsonmac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
1663100979Srwatson{
1664100979Srwatson	int error;
1665100979Srwatson
1666100979Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags");
1667100979Srwatson
1668100979Srwatson	if (!mac_enforce_fs)
1669100979Srwatson		return (0);
1670100979Srwatson
1671100979Srwatson	MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags);
1672100979Srwatson	return (error);
1673100979Srwatson}
1674100979Srwatson
1675100979Srwatsonint
1676100979Srwatsonmac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
1677100979Srwatson{
1678100979Srwatson	int error;
1679100979Srwatson
1680100979Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode");
1681100979Srwatson
1682100979Srwatson	if (!mac_enforce_fs)
1683100979Srwatson		return (0);
1684100979Srwatson
1685100979Srwatson	MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode);
1686100979Srwatson	return (error);
1687100979Srwatson}
1688100979Srwatson
1689100979Srwatsonint
1690100979Srwatsonmac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
1691100979Srwatson    gid_t gid)
1692100979Srwatson{
1693100979Srwatson	int error;
1694100979Srwatson
1695100979Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner");
1696100979Srwatson
1697100979Srwatson	if (!mac_enforce_fs)
1698100979Srwatson		return (0);
1699100979Srwatson
1700100979Srwatson	MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid);
1701100979Srwatson	return (error);
1702100979Srwatson}
1703100979Srwatson
1704100979Srwatsonint
1705100979Srwatsonmac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
1706100979Srwatson    struct timespec atime, struct timespec mtime)
1707100979Srwatson{
1708100979Srwatson	int error;
1709100979Srwatson
1710100979Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes");
1711100979Srwatson
1712100979Srwatson	if (!mac_enforce_fs)
1713100979Srwatson		return (0);
1714100979Srwatson
1715100979Srwatson	MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime,
1716100979Srwatson	    mtime);
1717100979Srwatson	return (error);
1718100979Srwatson}
1719100979Srwatson
1720100979Srwatsonint
1721102129Srwatsonmac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
1722102129Srwatson    struct vnode *vp)
1723100979Srwatson{
1724100979Srwatson	int error;
1725100979Srwatson
1726100979Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat");
1727100979Srwatson
1728100979Srwatson	if (!mac_enforce_fs)
1729100979Srwatson		return (0);
1730100979Srwatson
1731102129Srwatson	MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp,
1732102129Srwatson	    &vp->v_label);
1733100979Srwatson	return (error);
1734100979Srwatson}
1735100979Srwatson
1736102112Srwatsonint
1737102129Srwatsonmac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
1738102129Srwatson    struct vnode *vp)
1739102112Srwatson{
1740102112Srwatson	int error;
1741102112Srwatson
1742102112Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write");
1743102112Srwatson
1744102112Srwatson	if (!mac_enforce_fs)
1745102112Srwatson		return (0);
1746102112Srwatson
1747102129Srwatson	MAC_CHECK(check_vnode_write, active_cred, file_cred, vp,
1748102129Srwatson	    &vp->v_label);
1749102112Srwatson
1750102112Srwatson	return (error);
1751102112Srwatson}
1752102112Srwatson
1753100979Srwatson/*
1754100979Srwatson * When relabeling a process, call out to the policies for the maximum
1755100979Srwatson * permission allowed for each object type we know about in its
1756100979Srwatson * memory space, and revoke access (in the least surprising ways we
1757100979Srwatson * know) when necessary.  The process lock is not held here.
1758100979Srwatson */
1759100979Srwatsonstatic void
1760100979Srwatsonmac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred)
1761100979Srwatson{
1762100979Srwatson
1763100979Srwatson	/* XXX freeze all other threads */
1764100979Srwatson	mac_cred_mmapped_drop_perms_recurse(td, cred,
1765100979Srwatson	    &td->td_proc->p_vmspace->vm_map);
1766100979Srwatson	/* XXX allow other threads to continue */
1767100979Srwatson}
1768100979Srwatson
1769100979Srwatsonstatic __inline const char *
1770100979Srwatsonprot2str(vm_prot_t prot)
1771100979Srwatson{
1772100979Srwatson
1773100979Srwatson	switch (prot & VM_PROT_ALL) {
1774100979Srwatson	case VM_PROT_READ:
1775100979Srwatson		return ("r--");
1776100979Srwatson	case VM_PROT_READ | VM_PROT_WRITE:
1777100979Srwatson		return ("rw-");
1778100979Srwatson	case VM_PROT_READ | VM_PROT_EXECUTE:
1779100979Srwatson		return ("r-x");
1780100979Srwatson	case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
1781100979Srwatson		return ("rwx");
1782100979Srwatson	case VM_PROT_WRITE:
1783100979Srwatson		return ("-w-");
1784100979Srwatson	case VM_PROT_EXECUTE:
1785100979Srwatson		return ("--x");
1786100979Srwatson	case VM_PROT_WRITE | VM_PROT_EXECUTE:
1787100979Srwatson		return ("-wx");
1788100979Srwatson	default:
1789100979Srwatson		return ("---");
1790100979Srwatson	}
1791100979Srwatson}
1792100979Srwatson
1793100979Srwatsonstatic void
1794100979Srwatsonmac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred,
1795100979Srwatson    struct vm_map *map)
1796100979Srwatson{
1797100979Srwatson	struct vm_map_entry *vme;
1798104546Srwatson	int result;
1799104546Srwatson	vm_prot_t revokeperms;
1800100979Srwatson	vm_object_t object;
1801100979Srwatson	vm_ooffset_t offset;
1802100979Srwatson	struct vnode *vp;
1803100979Srwatson
1804103136Srwatson	if (!mac_mmap_revocation)
1805103136Srwatson		return;
1806103136Srwatson
1807100979Srwatson	vm_map_lock_read(map);
1808100979Srwatson	for (vme = map->header.next; vme != &map->header; vme = vme->next) {
1809100979Srwatson		if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) {
1810100979Srwatson			mac_cred_mmapped_drop_perms_recurse(td, cred,
1811100979Srwatson			    vme->object.sub_map);
1812100979Srwatson			continue;
1813100979Srwatson		}
1814100979Srwatson		/*
1815100979Srwatson		 * Skip over entries that obviously are not shared.
1816100979Srwatson		 */
1817100979Srwatson		if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) ||
1818100979Srwatson		    !vme->max_protection)
1819100979Srwatson			continue;
1820100979Srwatson		/*
1821100979Srwatson		 * Drill down to the deepest backing object.
1822100979Srwatson		 */
1823100979Srwatson		offset = vme->offset;
1824100979Srwatson		object = vme->object.vm_object;
1825100979Srwatson		if (object == NULL)
1826100979Srwatson			continue;
1827100979Srwatson		while (object->backing_object != NULL) {
1828100979Srwatson			object = object->backing_object;
1829100979Srwatson			offset += object->backing_object_offset;
1830100979Srwatson		}
1831100979Srwatson		/*
1832100979Srwatson		 * At the moment, vm_maps and objects aren't considered
1833100979Srwatson		 * by the MAC system, so only things with backing by a
1834100979Srwatson		 * normal object (read: vnodes) are checked.
1835100979Srwatson		 */
1836100979Srwatson		if (object->type != OBJT_VNODE)
1837100979Srwatson			continue;
1838100979Srwatson		vp = (struct vnode *)object->handle;
1839100979Srwatson		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
1840104546Srwatson		result = vme->max_protection;
1841104546Srwatson		mac_check_vnode_mmap_downgrade(cred, vp, &result);
1842100979Srwatson		VOP_UNLOCK(vp, 0, td);
1843100979Srwatson		/*
1844100979Srwatson		 * Find out what maximum protection we may be allowing
1845100979Srwatson		 * now but a policy needs to get removed.
1846100979Srwatson		 */
1847100979Srwatson		revokeperms = vme->max_protection & ~result;
1848100979Srwatson		if (!revokeperms)
1849100979Srwatson			continue;
1850102949Sbde		printf("pid %ld: revoking %s perms from %#lx:%ld "
1851102949Sbde		    "(max %s/cur %s)\n", (long)td->td_proc->p_pid,
1852102949Sbde		    prot2str(revokeperms), (u_long)vme->start,
1853102949Sbde		    (long)(vme->end - vme->start),
1854100979Srwatson		    prot2str(vme->max_protection), prot2str(vme->protection));
1855100979Srwatson		vm_map_lock_upgrade(map);
1856100979Srwatson		/*
1857100979Srwatson		 * This is the really simple case: if a map has more
1858100979Srwatson		 * max_protection than is allowed, but it's not being
1859100979Srwatson		 * actually used (that is, the current protection is
1860100979Srwatson		 * still allowed), we can just wipe it out and do
1861100979Srwatson		 * nothing more.
1862100979Srwatson		 */
1863100979Srwatson		if ((vme->protection & revokeperms) == 0) {
1864100979Srwatson			vme->max_protection -= revokeperms;
1865100979Srwatson		} else {
1866100979Srwatson			if (revokeperms & VM_PROT_WRITE) {
1867100979Srwatson				/*
1868100979Srwatson				 * In the more complicated case, flush out all
1869100979Srwatson				 * pending changes to the object then turn it
1870100979Srwatson				 * copy-on-write.
1871100979Srwatson				 */
1872100979Srwatson				vm_object_reference(object);
1873100979Srwatson				vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
1874100979Srwatson				vm_object_page_clean(object,
1875100979Srwatson				    OFF_TO_IDX(offset),
1876100979Srwatson				    OFF_TO_IDX(offset + vme->end - vme->start +
1877100979Srwatson					PAGE_MASK),
1878100979Srwatson				    OBJPC_SYNC);
1879100979Srwatson				VOP_UNLOCK(vp, 0, td);
1880100979Srwatson				vm_object_deallocate(object);
1881100979Srwatson				/*
1882100979Srwatson				 * Why bother if there's no read permissions
1883100979Srwatson				 * anymore?  For the rest, we need to leave
1884100979Srwatson				 * the write permissions on for COW, or
1885100979Srwatson				 * remove them entirely if configured to.
1886100979Srwatson				 */
1887100979Srwatson				if (!mac_mmap_revocation_via_cow) {
1888100979Srwatson					vme->max_protection &= ~VM_PROT_WRITE;
1889100979Srwatson					vme->protection &= ~VM_PROT_WRITE;
1890100979Srwatson				} if ((revokeperms & VM_PROT_READ) == 0)
1891100979Srwatson					vme->eflags |= MAP_ENTRY_COW |
1892100979Srwatson					    MAP_ENTRY_NEEDS_COPY;
1893100979Srwatson			}
1894100979Srwatson			if (revokeperms & VM_PROT_EXECUTE) {
1895100979Srwatson				vme->max_protection &= ~VM_PROT_EXECUTE;
1896100979Srwatson				vme->protection &= ~VM_PROT_EXECUTE;
1897100979Srwatson			}
1898100979Srwatson			if (revokeperms & VM_PROT_READ) {
1899100979Srwatson				vme->max_protection = 0;
1900100979Srwatson				vme->protection = 0;
1901100979Srwatson			}
1902100979Srwatson			pmap_protect(map->pmap, vme->start, vme->end,
1903100979Srwatson			    vme->protection & ~revokeperms);
1904100979Srwatson			vm_map_simplify_entry(map, vme);
1905100979Srwatson		}
1906100979Srwatson		vm_map_lock_downgrade(map);
1907100979Srwatson	}
1908100979Srwatson	vm_map_unlock_read(map);
1909100979Srwatson}
1910100979Srwatson
1911100979Srwatson/*
1912100979Srwatson * When the subject's label changes, it may require revocation of privilege
1913100979Srwatson * to mapped objects.  This can't be done on-the-fly later with a unified
1914100979Srwatson * buffer cache.
1915100979Srwatson */
1916100979Srwatsonstatic void
1917100979Srwatsonmac_relabel_cred(struct ucred *cred, struct label *newlabel)
1918100979Srwatson{
1919100979Srwatson
1920100979Srwatson	MAC_PERFORM(relabel_cred, cred, newlabel);
1921100979Srwatson}
1922100979Srwatson
1923100979Srwatsonvoid
1924100979Srwatsonmac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel)
1925100979Srwatson{
1926100979Srwatson
1927100979Srwatson	MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel);
1928100979Srwatson}
1929100979Srwatson
1930100979Srwatsonvoid
1931100979Srwatsonmac_create_ifnet(struct ifnet *ifnet)
1932100979Srwatson{
1933100979Srwatson
1934100979Srwatson	MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label);
1935100979Srwatson}
1936100979Srwatson
1937100979Srwatsonvoid
1938100979Srwatsonmac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d)
1939100979Srwatson{
1940100979Srwatson
1941100979Srwatson	MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label);
1942100979Srwatson}
1943100979Srwatson
1944100979Srwatsonvoid
1945100979Srwatsonmac_create_socket(struct ucred *cred, struct socket *socket)
1946100979Srwatson{
1947100979Srwatson
1948100979Srwatson	MAC_PERFORM(create_socket, cred, socket, &socket->so_label);
1949100979Srwatson}
1950100979Srwatson
1951100979Srwatsonvoid
1952100979Srwatsonmac_create_pipe(struct ucred *cred, struct pipe *pipe)
1953100979Srwatson{
1954100979Srwatson
1955100979Srwatson	MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label);
1956100979Srwatson}
1957100979Srwatson
1958100979Srwatsonvoid
1959100979Srwatsonmac_create_socket_from_socket(struct socket *oldsocket,
1960100979Srwatson    struct socket *newsocket)
1961100979Srwatson{
1962100979Srwatson
1963100979Srwatson	MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label,
1964100979Srwatson	    newsocket, &newsocket->so_label);
1965100979Srwatson}
1966100979Srwatson
1967100979Srwatsonstatic void
1968100979Srwatsonmac_relabel_socket(struct ucred *cred, struct socket *socket,
1969100979Srwatson    struct label *newlabel)
1970100979Srwatson{
1971100979Srwatson
1972100979Srwatson	MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel);
1973100979Srwatson}
1974100979Srwatson
1975100979Srwatsonstatic void
1976100979Srwatsonmac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel)
1977100979Srwatson{
1978100979Srwatson
1979100979Srwatson	MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel);
1980100979Srwatson}
1981100979Srwatson
1982100979Srwatsonvoid
1983100979Srwatsonmac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket)
1984100979Srwatson{
1985100979Srwatson
1986100979Srwatson	MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label,
1987100979Srwatson	    socket, &socket->so_peerlabel);
1988100979Srwatson}
1989100979Srwatson
1990100979Srwatsonvoid
1991100979Srwatsonmac_set_socket_peer_from_socket(struct socket *oldsocket,
1992100979Srwatson    struct socket *newsocket)
1993100979Srwatson{
1994100979Srwatson
1995100979Srwatson	MAC_PERFORM(set_socket_peer_from_socket, oldsocket,
1996100979Srwatson	    &oldsocket->so_label, newsocket, &newsocket->so_peerlabel);
1997100979Srwatson}
1998100979Srwatson
1999100979Srwatsonvoid
2000100979Srwatsonmac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram)
2001100979Srwatson{
2002100979Srwatson
2003100979Srwatson	MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label,
2004100979Srwatson	    datagram, &datagram->m_pkthdr.label);
2005100979Srwatson}
2006100979Srwatson
2007100979Srwatsonvoid
2008100979Srwatsonmac_create_fragment(struct mbuf *datagram, struct mbuf *fragment)
2009100979Srwatson{
2010100979Srwatson
2011100979Srwatson	MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label,
2012100979Srwatson	    fragment, &fragment->m_pkthdr.label);
2013100979Srwatson}
2014100979Srwatson
2015100979Srwatsonvoid
2016100979Srwatsonmac_create_ipq(struct mbuf *fragment, struct ipq *ipq)
2017100979Srwatson{
2018100979Srwatson
2019100979Srwatson	MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq,
2020100979Srwatson	    &ipq->ipq_label);
2021100979Srwatson}
2022100979Srwatson
2023100979Srwatsonvoid
2024100979Srwatsonmac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf)
2025100979Srwatson{
2026100979Srwatson
2027100979Srwatson	MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label,
2028100979Srwatson	    newmbuf, &newmbuf->m_pkthdr.label);
2029100979Srwatson}
2030100979Srwatson
2031100979Srwatsonvoid
2032100979Srwatsonmac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf)
2033100979Srwatson{
2034100979Srwatson
2035100979Srwatson	MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf,
2036100979Srwatson	    &mbuf->m_pkthdr.label);
2037100979Srwatson}
2038100979Srwatson
2039100979Srwatsonvoid
2040100979Srwatsonmac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf)
2041100979Srwatson{
2042100979Srwatson
2043100979Srwatson	MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf,
2044100979Srwatson	    &mbuf->m_pkthdr.label);
2045100979Srwatson}
2046100979Srwatson
2047100979Srwatsonvoid
2048100979Srwatsonmac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf)
2049100979Srwatson{
2050100979Srwatson
2051100979Srwatson	MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf,
2052100979Srwatson	    &mbuf->m_pkthdr.label);
2053100979Srwatson}
2054100979Srwatson
2055100979Srwatsonvoid
2056100979Srwatsonmac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet,
2057100979Srwatson    struct mbuf *newmbuf)
2058100979Srwatson{
2059100979Srwatson
2060100979Srwatson	MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf,
2061100979Srwatson	    &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf,
2062100979Srwatson	    &newmbuf->m_pkthdr.label);
2063100979Srwatson}
2064100979Srwatson
2065100979Srwatsonvoid
2066100979Srwatsonmac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf)
2067100979Srwatson{
2068100979Srwatson
2069100979Srwatson	MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label,
2070100979Srwatson	    newmbuf, &newmbuf->m_pkthdr.label);
2071100979Srwatson}
2072100979Srwatson
2073100979Srwatsonint
2074100979Srwatsonmac_fragment_match(struct mbuf *fragment, struct ipq *ipq)
2075100979Srwatson{
2076100979Srwatson	int result;
2077100979Srwatson
2078100979Srwatson	result = 1;
2079100979Srwatson	MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label,
2080100979Srwatson	    ipq, &ipq->ipq_label);
2081100979Srwatson
2082100979Srwatson	return (result);
2083100979Srwatson}
2084100979Srwatson
2085100979Srwatsonvoid
2086100979Srwatsonmac_update_ipq(struct mbuf *fragment, struct ipq *ipq)
2087100979Srwatson{
2088100979Srwatson
2089100979Srwatson	MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq,
2090100979Srwatson	    &ipq->ipq_label);
2091100979Srwatson}
2092100979Srwatson
2093100979Srwatsonvoid
2094100979Srwatsonmac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf)
2095100979Srwatson{
2096100979Srwatson
2097100979Srwatson	MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf,
2098100979Srwatson	    &mbuf->m_pkthdr.label);
2099100979Srwatson}
2100100979Srwatson
2101100979Srwatsonvoid
2102100979Srwatsonmac_create_mount(struct ucred *cred, struct mount *mp)
2103100979Srwatson{
2104100979Srwatson
2105100979Srwatson	MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel,
2106100979Srwatson	    &mp->mnt_fslabel);
2107100979Srwatson}
2108100979Srwatson
2109100979Srwatsonvoid
2110100979Srwatsonmac_create_root_mount(struct ucred *cred, struct mount *mp)
2111100979Srwatson{
2112100979Srwatson
2113100979Srwatson	MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel,
2114100979Srwatson	    &mp->mnt_fslabel);
2115100979Srwatson}
2116100979Srwatson
2117100979Srwatsonint
2118100979Srwatsonmac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet)
2119100979Srwatson{
2120100979Srwatson	int error;
2121100979Srwatson
2122100979Srwatson	if (!mac_enforce_network)
2123100979Srwatson		return (0);
2124100979Srwatson
2125100979Srwatson	MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet,
2126100979Srwatson	    &ifnet->if_label);
2127100979Srwatson
2128100979Srwatson	return (error);
2129100979Srwatson}
2130100979Srwatson
2131100979Srwatsonstatic int
2132100979Srwatsonmac_check_cred_relabel(struct ucred *cred, struct label *newlabel)
2133100979Srwatson{
2134100979Srwatson	int error;
2135100979Srwatson
2136100979Srwatson	MAC_CHECK(check_cred_relabel, cred, newlabel);
2137100979Srwatson
2138100979Srwatson	return (error);
2139100979Srwatson}
2140100979Srwatson
2141100979Srwatsonint
2142100979Srwatsonmac_check_cred_visible(struct ucred *u1, struct ucred *u2)
2143100979Srwatson{
2144100979Srwatson	int error;
2145100979Srwatson
2146100979Srwatson	if (!mac_enforce_process)
2147100979Srwatson		return (0);
2148100979Srwatson
2149100979Srwatson	MAC_CHECK(check_cred_visible, u1, u2);
2150100979Srwatson
2151100979Srwatson	return (error);
2152100979Srwatson}
2153100979Srwatson
2154100979Srwatsonint
2155100979Srwatsonmac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf)
2156100979Srwatson{
2157100979Srwatson	int error;
2158100979Srwatson
2159100979Srwatson	if (!mac_enforce_network)
2160100979Srwatson		return (0);
2161100979Srwatson
2162100979Srwatson	KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr"));
2163100979Srwatson	if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED))
2164105598Sbrooks		if_printf(ifnet, "not initialized\n");
2165100979Srwatson
2166100979Srwatson	MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf,
2167100979Srwatson	    &mbuf->m_pkthdr.label);
2168100979Srwatson
2169100979Srwatson	return (error);
2170100979Srwatson}
2171100979Srwatson
2172100979Srwatsonint
2173106308Srwatsonmac_check_kenv_dump(struct ucred *cred)
2174106308Srwatson{
2175106308Srwatson	int error;
2176106308Srwatson
2177106308Srwatson	if (!mac_enforce_system)
2178106308Srwatson		return (0);
2179106308Srwatson
2180106308Srwatson	MAC_CHECK(check_kenv_dump, cred);
2181106308Srwatson
2182106308Srwatson	return (error);
2183106308Srwatson}
2184106308Srwatson
2185106308Srwatsonint
2186106308Srwatsonmac_check_kenv_get(struct ucred *cred, char *name)
2187106308Srwatson{
2188106308Srwatson	int error;
2189106308Srwatson
2190106308Srwatson	if (!mac_enforce_system)
2191106308Srwatson		return (0);
2192106308Srwatson
2193106308Srwatson	MAC_CHECK(check_kenv_get, cred, name);
2194106308Srwatson
2195106308Srwatson	return (error);
2196106308Srwatson}
2197106308Srwatson
2198106308Srwatsonint
2199106308Srwatsonmac_check_kenv_set(struct ucred *cred, char *name, char *value)
2200106308Srwatson{
2201106308Srwatson	int error;
2202106308Srwatson
2203106308Srwatson	if (!mac_enforce_system)
2204106308Srwatson		return (0);
2205106308Srwatson
2206106308Srwatson	MAC_CHECK(check_kenv_set, cred, name, value);
2207106308Srwatson
2208106308Srwatson	return (error);
2209106308Srwatson}
2210106308Srwatson
2211106308Srwatsonint
2212106308Srwatsonmac_check_kenv_unset(struct ucred *cred, char *name)
2213106308Srwatson{
2214106308Srwatson	int error;
2215106308Srwatson
2216106308Srwatson	if (!mac_enforce_system)
2217106308Srwatson		return (0);
2218106308Srwatson
2219106308Srwatson	MAC_CHECK(check_kenv_unset, cred, name);
2220106308Srwatson
2221106308Srwatson	return (error);
2222106308Srwatson}
2223106308Srwatson
2224106308Srwatsonint
2225100979Srwatsonmac_check_mount_stat(struct ucred *cred, struct mount *mount)
2226100979Srwatson{
2227100979Srwatson	int error;
2228100979Srwatson
2229100979Srwatson	if (!mac_enforce_fs)
2230100979Srwatson		return (0);
2231100979Srwatson
2232100979Srwatson	MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel);
2233100979Srwatson
2234100979Srwatson	return (error);
2235100979Srwatson}
2236100979Srwatson
2237100979Srwatsonint
2238100979Srwatsonmac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd,
2239100979Srwatson    void *data)
2240100979Srwatson{
2241100979Srwatson	int error;
2242100979Srwatson
2243104269Srwatson	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2244104269Srwatson
2245104269Srwatson	if (!mac_enforce_pipe)
2246104269Srwatson		return (0);
2247104269Srwatson
2248100979Srwatson	MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data);
2249100979Srwatson
2250100979Srwatson	return (error);
2251100979Srwatson}
2252100979Srwatson
2253100979Srwatsonint
2254102115Srwatsonmac_check_pipe_poll(struct ucred *cred, struct pipe *pipe)
2255100979Srwatson{
2256100979Srwatson	int error;
2257100979Srwatson
2258104269Srwatson	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2259104269Srwatson
2260104269Srwatson	if (!mac_enforce_pipe)
2261104269Srwatson		return (0);
2262104269Srwatson
2263102115Srwatson	MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label);
2264100979Srwatson
2265100979Srwatson	return (error);
2266100979Srwatson}
2267100979Srwatson
2268102115Srwatsonint
2269102115Srwatsonmac_check_pipe_read(struct ucred *cred, struct pipe *pipe)
2270102115Srwatson{
2271102115Srwatson	int error;
2272102115Srwatson
2273104269Srwatson	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2274104269Srwatson
2275104269Srwatson	if (!mac_enforce_pipe)
2276104269Srwatson		return (0);
2277104269Srwatson
2278102115Srwatson	MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label);
2279102115Srwatson
2280102115Srwatson	return (error);
2281102115Srwatson}
2282102115Srwatson
2283100979Srwatsonstatic int
2284100979Srwatsonmac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
2285100979Srwatson    struct label *newlabel)
2286100979Srwatson{
2287100979Srwatson	int error;
2288100979Srwatson
2289104269Srwatson	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2290104269Srwatson
2291104269Srwatson	if (!mac_enforce_pipe)
2292104269Srwatson		return (0);
2293104269Srwatson
2294100979Srwatson	MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel);
2295100979Srwatson
2296100979Srwatson	return (error);
2297100979Srwatson}
2298100979Srwatson
2299100979Srwatsonint
2300102115Srwatsonmac_check_pipe_stat(struct ucred *cred, struct pipe *pipe)
2301102115Srwatson{
2302102115Srwatson	int error;
2303102115Srwatson
2304104269Srwatson	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2305104269Srwatson
2306104269Srwatson	if (!mac_enforce_pipe)
2307104269Srwatson		return (0);
2308104269Srwatson
2309102115Srwatson	MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label);
2310102115Srwatson
2311102115Srwatson	return (error);
2312102115Srwatson}
2313102115Srwatson
2314102115Srwatsonint
2315102115Srwatsonmac_check_pipe_write(struct ucred *cred, struct pipe *pipe)
2316102115Srwatson{
2317102115Srwatson	int error;
2318102115Srwatson
2319104269Srwatson	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2320104269Srwatson
2321104269Srwatson	if (!mac_enforce_pipe)
2322104269Srwatson		return (0);
2323104269Srwatson
2324102115Srwatson	MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label);
2325102115Srwatson
2326102115Srwatson	return (error);
2327102115Srwatson}
2328102115Srwatson
2329102115Srwatsonint
2330100979Srwatsonmac_check_proc_debug(struct ucred *cred, struct proc *proc)
2331100979Srwatson{
2332100979Srwatson	int error;
2333100979Srwatson
2334102103Srwatson	PROC_LOCK_ASSERT(proc, MA_OWNED);
2335102103Srwatson
2336100979Srwatson	if (!mac_enforce_process)
2337100979Srwatson		return (0);
2338100979Srwatson
2339100979Srwatson	MAC_CHECK(check_proc_debug, cred, proc);
2340100979Srwatson
2341100979Srwatson	return (error);
2342100979Srwatson}
2343100979Srwatson
2344100979Srwatsonint
2345100979Srwatsonmac_check_proc_sched(struct ucred *cred, struct proc *proc)
2346100979Srwatson{
2347100979Srwatson	int error;
2348100979Srwatson
2349102103Srwatson	PROC_LOCK_ASSERT(proc, MA_OWNED);
2350102103Srwatson
2351100979Srwatson	if (!mac_enforce_process)
2352100979Srwatson		return (0);
2353100979Srwatson
2354100979Srwatson	MAC_CHECK(check_proc_sched, cred, proc);
2355100979Srwatson
2356100979Srwatson	return (error);
2357100979Srwatson}
2358100979Srwatson
2359100979Srwatsonint
2360100979Srwatsonmac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
2361100979Srwatson{
2362100979Srwatson	int error;
2363100979Srwatson
2364102103Srwatson	PROC_LOCK_ASSERT(proc, MA_OWNED);
2365102103Srwatson
2366100979Srwatson	if (!mac_enforce_process)
2367100979Srwatson		return (0);
2368100979Srwatson
2369100979Srwatson	MAC_CHECK(check_proc_signal, cred, proc, signum);
2370100979Srwatson
2371100979Srwatson	return (error);
2372100979Srwatson}
2373100979Srwatson
2374100979Srwatsonint
2375100979Srwatsonmac_check_socket_bind(struct ucred *ucred, struct socket *socket,
2376100979Srwatson    struct sockaddr *sockaddr)
2377100979Srwatson{
2378100979Srwatson	int error;
2379100979Srwatson
2380100979Srwatson	if (!mac_enforce_socket)
2381100979Srwatson		return (0);
2382100979Srwatson
2383100979Srwatson	MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label,
2384100979Srwatson	    sockaddr);
2385100979Srwatson
2386100979Srwatson	return (error);
2387100979Srwatson}
2388100979Srwatson
2389100979Srwatsonint
2390100979Srwatsonmac_check_socket_connect(struct ucred *cred, struct socket *socket,
2391100979Srwatson    struct sockaddr *sockaddr)
2392100979Srwatson{
2393100979Srwatson	int error;
2394100979Srwatson
2395100979Srwatson	if (!mac_enforce_socket)
2396100979Srwatson		return (0);
2397100979Srwatson
2398100979Srwatson	MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label,
2399100979Srwatson	    sockaddr);
2400100979Srwatson
2401100979Srwatson	return (error);
2402100979Srwatson}
2403100979Srwatson
2404100979Srwatsonint
2405101933Srwatsonmac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf)
2406100979Srwatson{
2407100979Srwatson	int error;
2408100979Srwatson
2409100979Srwatson	if (!mac_enforce_socket)
2410100979Srwatson		return (0);
2411100979Srwatson
2412101933Srwatson	MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf,
2413101933Srwatson	    &mbuf->m_pkthdr.label);
2414101933Srwatson
2415100979Srwatson	return (error);
2416100979Srwatson}
2417100979Srwatson
2418100979Srwatsonint
2419101933Srwatsonmac_check_socket_listen(struct ucred *cred, struct socket *socket)
2420100979Srwatson{
2421100979Srwatson	int error;
2422100979Srwatson
2423100979Srwatson	if (!mac_enforce_socket)
2424100979Srwatson		return (0);
2425100979Srwatson
2426101933Srwatson	MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label);
2427100979Srwatson	return (error);
2428100979Srwatson}
2429100979Srwatson
2430104571Srwatsonint
2431104571Srwatsonmac_check_socket_receive(struct ucred *cred, struct socket *so)
2432104571Srwatson{
2433104571Srwatson	int error;
2434104571Srwatson
2435104571Srwatson	if (!mac_enforce_socket)
2436104571Srwatson		return (0);
2437104571Srwatson
2438104571Srwatson	MAC_CHECK(check_socket_receive, cred, so, &so->so_label);
2439104571Srwatson
2440104571Srwatson	return (error);
2441104571Srwatson}
2442104571Srwatson
2443100979Srwatsonstatic int
2444100979Srwatsonmac_check_socket_relabel(struct ucred *cred, struct socket *socket,
2445100979Srwatson    struct label *newlabel)
2446100979Srwatson{
2447100979Srwatson	int error;
2448100979Srwatson
2449100979Srwatson	MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label,
2450100979Srwatson	    newlabel);
2451100979Srwatson
2452100979Srwatson	return (error);
2453100979Srwatson}
2454100979Srwatson
2455100979Srwatsonint
2456104571Srwatsonmac_check_socket_send(struct ucred *cred, struct socket *so)
2457104571Srwatson{
2458104571Srwatson	int error;
2459104571Srwatson
2460104571Srwatson	if (!mac_enforce_socket)
2461104571Srwatson		return (0);
2462104571Srwatson
2463104571Srwatson	MAC_CHECK(check_socket_send, cred, so, &so->so_label);
2464104571Srwatson
2465104571Srwatson	return (error);
2466104571Srwatson}
2467104571Srwatson
2468104571Srwatsonint
2469100979Srwatsonmac_check_socket_visible(struct ucred *cred, struct socket *socket)
2470100979Srwatson{
2471100979Srwatson	int error;
2472100979Srwatson
2473100979Srwatson	if (!mac_enforce_socket)
2474100979Srwatson		return (0);
2475105694Srwatson
2476100979Srwatson	MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label);
2477105694Srwatson
2478100979Srwatson	return (error);
2479100979Srwatson}
2480100979Srwatson
2481100979Srwatsonint
2482106024Srwatsonmac_check_system_reboot(struct ucred *cred, int howto)
2483106024Srwatson{
2484106024Srwatson	int error;
2485106024Srwatson
2486106045Srwatson	if (!mac_enforce_system)
2487106024Srwatson		return (0);
2488106024Srwatson
2489106024Srwatson	MAC_CHECK(check_system_reboot, cred, howto);
2490106045Srwatson
2491106024Srwatson	return (error);
2492106024Srwatson}
2493106024Srwatson
2494106024Srwatsonint
2495106369Srwatsonmac_check_system_settime(struct ucred *cred)
2496106369Srwatson{
2497106369Srwatson	int error;
2498106369Srwatson
2499106369Srwatson	if (!mac_enforce_system)
2500106369Srwatson		return (0);
2501106369Srwatson
2502106369Srwatson	MAC_CHECK(check_system_settime, cred);
2503106369Srwatson
2504106369Srwatson	return (error);
2505106369Srwatson}
2506106369Srwatson
2507106369Srwatsonint
2508106023Srwatsonmac_check_system_swapon(struct ucred *cred, struct vnode *vp)
2509106023Srwatson{
2510106023Srwatson	int error;
2511106023Srwatson
2512106023Srwatson	ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon");
2513106023Srwatson
2514106045Srwatson	if (!mac_enforce_system)
2515106023Srwatson		return (0);
2516106023Srwatson
2517106023Srwatson	MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label);
2518106023Srwatson	return (error);
2519106023Srwatson}
2520106023Srwatson
2521106023Srwatsonint
2522106025Srwatsonmac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
2523106025Srwatson    void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
2524106025Srwatson{
2525106025Srwatson	int error;
2526106025Srwatson
2527106025Srwatson	/*
2528106025Srwatson	 * XXXMAC: We're very much like to assert the SYSCTL_LOCK here,
2529106025Srwatson	 * but since it's not exported from kern_sysctl.c, we can't.
2530106025Srwatson	 */
2531106045Srwatson	if (!mac_enforce_system)
2532106025Srwatson		return (0);
2533106025Srwatson
2534106025Srwatson	MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp,
2535106025Srwatson	    inkernel, new, newlen);
2536106025Srwatson
2537106025Srwatson	return (error);
2538106025Srwatson}
2539106025Srwatson
2540106025Srwatsonint
2541100979Srwatsonmac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
2542100979Srwatson    struct ifnet *ifnet)
2543100979Srwatson{
2544105694Srwatson	char *elements, *buffer;
2545105694Srwatson	struct mac mac;
2546100979Srwatson	int error;
2547100979Srwatson
2548105694Srwatson	error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
2549100979Srwatson	if (error)
2550100979Srwatson		return (error);
2551100979Srwatson
2552105694Srwatson	error = mac_check_structmac_consistent(&mac);
2553105694Srwatson	if (error)
2554105694Srwatson		return (error);
2555105694Srwatson
2556105694Srwatson	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
2557105694Srwatson	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
2558105694Srwatson	if (error) {
2559105694Srwatson		free(elements, M_MACTEMP);
2560105694Srwatson		return (error);
2561105694Srwatson	}
2562105694Srwatson
2563105694Srwatson	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
2564105694Srwatson	error = mac_externalize_ifnet_label(&ifnet->if_label, elements,
2565105694Srwatson	    buffer, mac.m_buflen, M_WAITOK);
2566105694Srwatson	if (error == 0)
2567105694Srwatson		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
2568105694Srwatson
2569105694Srwatson	free(buffer, M_MACTEMP);
2570105694Srwatson	free(elements, M_MACTEMP);
2571105694Srwatson
2572105694Srwatson	return (error);
2573100979Srwatson}
2574100979Srwatson
2575100979Srwatsonint
2576100979Srwatsonmac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
2577100979Srwatson    struct ifnet *ifnet)
2578100979Srwatson{
2579100979Srwatson	struct label intlabel;
2580105694Srwatson	struct mac mac;
2581105694Srwatson	char *buffer;
2582100979Srwatson	int error;
2583100979Srwatson
2584105694Srwatson	error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
2585100979Srwatson	if (error)
2586100979Srwatson		return (error);
2587100979Srwatson
2588105694Srwatson	error = mac_check_structmac_consistent(&mac);
2589100979Srwatson	if (error)
2590100979Srwatson		return (error);
2591100979Srwatson
2592105694Srwatson	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
2593105694Srwatson	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
2594105694Srwatson	if (error) {
2595105694Srwatson		free(buffer, M_MACTEMP);
2596105694Srwatson		return (error);
2597105694Srwatson	}
2598105694Srwatson
2599105694Srwatson	mac_init_ifnet_label(&intlabel);
2600105694Srwatson	error = mac_internalize_ifnet_label(&intlabel, buffer);
2601105694Srwatson	free(buffer, M_MACTEMP);
2602105694Srwatson	if (error) {
2603105694Srwatson		mac_destroy_ifnet_label(&intlabel);
2604105694Srwatson		return (error);
2605105694Srwatson	}
2606105694Srwatson
2607100979Srwatson	/*
2608100979Srwatson	 * XXX: Note that this is a redundant privilege check, since
2609100979Srwatson	 * policies impose this check themselves if required by the
2610100979Srwatson	 * policy.  Eventually, this should go away.
2611100979Srwatson	 */
2612100979Srwatson	error = suser_cred(cred, 0);
2613105694Srwatson	if (error) {
2614105694Srwatson		mac_destroy_ifnet_label(&intlabel);
2615105694Srwatson		return (error);
2616105694Srwatson	}
2617100979Srwatson
2618100979Srwatson	MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label,
2619100979Srwatson	    &intlabel);
2620105694Srwatson	if (error) {
2621105694Srwatson		mac_destroy_ifnet_label(&intlabel);
2622105694Srwatson		return (error);
2623105694Srwatson	}
2624100979Srwatson
2625100979Srwatson	MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel);
2626100979Srwatson
2627105694Srwatson	mac_destroy_ifnet_label(&intlabel);
2628105694Srwatson	return (0);
2629100979Srwatson}
2630100979Srwatson
2631100979Srwatsonvoid
2632100979Srwatsonmac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp)
2633100979Srwatson{
2634100979Srwatson
2635100979Srwatson	MAC_PERFORM(create_devfs_vnode, de, &de->de_label, vp, &vp->v_label);
2636100979Srwatson}
2637100979Srwatson
2638100979Srwatsonvoid
2639100979Srwatsonmac_create_devfs_device(dev_t dev, struct devfs_dirent *de)
2640100979Srwatson{
2641100979Srwatson
2642100979Srwatson	MAC_PERFORM(create_devfs_device, dev, de, &de->de_label);
2643100979Srwatson}
2644100979Srwatson
2645104533Srwatsonvoid
2646104533Srwatsonmac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
2647104533Srwatson    struct devfs_dirent *de)
2648104533Srwatson{
2649104533Srwatson
2650104533Srwatson	MAC_PERFORM(create_devfs_symlink, cred, dd, &dd->de_label, de,
2651104533Srwatson	    &de->de_label);
2652104533Srwatson}
2653104533Srwatson
2654100979Srwatsonvoid
2655100979Srwatsonmac_create_devfs_directory(char *dirname, int dirnamelen,
2656100979Srwatson    struct devfs_dirent *de)
2657100979Srwatson{
2658100979Srwatson
2659100979Srwatson	MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de,
2660100979Srwatson	    &de->de_label);
2661100979Srwatson}
2662100979Srwatson
2663100979Srwatsonint
2664100979Srwatsonmac_setsockopt_label_set(struct ucred *cred, struct socket *so,
2665105694Srwatson    struct mac *mac)
2666100979Srwatson{
2667100979Srwatson	struct label intlabel;
2668105694Srwatson	char *buffer;
2669100979Srwatson	int error;
2670100979Srwatson
2671105694Srwatson	error = mac_check_structmac_consistent(mac);
2672100979Srwatson	if (error)
2673100979Srwatson		return (error);
2674100979Srwatson
2675105694Srwatson	buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
2676105694Srwatson	error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL);
2677105694Srwatson	if (error) {
2678105694Srwatson		free(buffer, M_MACTEMP);
2679105694Srwatson		return (error);
2680105694Srwatson	}
2681105694Srwatson
2682105694Srwatson	mac_init_socket_label(&intlabel, M_WAITOK);
2683105694Srwatson	error = mac_internalize_socket_label(&intlabel, buffer);
2684105694Srwatson	free(buffer, M_MACTEMP);
2685105694Srwatson	if (error) {
2686105694Srwatson		mac_destroy_socket_label(&intlabel);
2687105694Srwatson		return (error);
2688105694Srwatson	}
2689105694Srwatson
2690100979Srwatson	mac_check_socket_relabel(cred, so, &intlabel);
2691100979Srwatson	if (error) {
2692105694Srwatson		mac_destroy_socket_label(&intlabel);
2693100979Srwatson		return (error);
2694100979Srwatson	}
2695100979Srwatson
2696100979Srwatson	mac_relabel_socket(cred, so, &intlabel);
2697100979Srwatson
2698105694Srwatson	mac_destroy_socket_label(&intlabel);
2699100979Srwatson	return (0);
2700100979Srwatson}
2701100979Srwatson
2702100979Srwatsonint
2703100979Srwatsonmac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label)
2704100979Srwatson{
2705100979Srwatson	int error;
2706100979Srwatson
2707104269Srwatson	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2708104269Srwatson
2709100979Srwatson	error = mac_check_pipe_relabel(cred, pipe, label);
2710100979Srwatson	if (error)
2711100979Srwatson		return (error);
2712100979Srwatson
2713100979Srwatson	mac_relabel_pipe(cred, pipe, label);
2714100979Srwatson
2715100979Srwatson	return (0);
2716100979Srwatson}
2717100979Srwatson
2718100979Srwatsonint
2719100979Srwatsonmac_getsockopt_label_get(struct ucred *cred, struct socket *so,
2720105694Srwatson    struct mac *mac)
2721100979Srwatson{
2722105694Srwatson	char *buffer, *elements;
2723105694Srwatson	int error;
2724100979Srwatson
2725105694Srwatson	error = mac_check_structmac_consistent(mac);
2726105694Srwatson	if (error)
2727105694Srwatson		return (error);
2728105694Srwatson
2729105694Srwatson	elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
2730105694Srwatson	error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
2731105694Srwatson	if (error) {
2732105694Srwatson		free(elements, M_MACTEMP);
2733105694Srwatson		return (error);
2734105694Srwatson	}
2735105694Srwatson
2736105694Srwatson	buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
2737105694Srwatson	error = mac_externalize_socket_label(&so->so_label, elements,
2738105694Srwatson	    buffer, mac->m_buflen, M_WAITOK);
2739105694Srwatson	if (error == 0)
2740105694Srwatson		error = copyout(buffer, mac->m_string, strlen(buffer)+1);
2741105694Srwatson
2742105694Srwatson	free(buffer, M_MACTEMP);
2743105694Srwatson	free(elements, M_MACTEMP);
2744105694Srwatson
2745105694Srwatson	return (error);
2746100979Srwatson}
2747100979Srwatson
2748100979Srwatsonint
2749100979Srwatsonmac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
2750105694Srwatson    struct mac *mac)
2751100979Srwatson{
2752105694Srwatson	char *elements, *buffer;
2753105694Srwatson	int error;
2754100979Srwatson
2755105694Srwatson	error = mac_check_structmac_consistent(mac);
2756105694Srwatson	if (error)
2757105694Srwatson		return (error);
2758105694Srwatson
2759105694Srwatson	elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
2760105694Srwatson	error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
2761105694Srwatson	if (error) {
2762105694Srwatson		free(elements, M_MACTEMP);
2763105694Srwatson		return (error);
2764105694Srwatson	}
2765105694Srwatson
2766105694Srwatson	buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
2767105694Srwatson	error = mac_externalize_socket_peer_label(&so->so_peerlabel,
2768105694Srwatson	    elements, buffer, mac->m_buflen, M_WAITOK);
2769105694Srwatson	if (error == 0)
2770105694Srwatson		error = copyout(buffer, mac->m_string, strlen(buffer)+1);
2771105694Srwatson
2772105694Srwatson	free(buffer, M_MACTEMP);
2773105694Srwatson	free(elements, M_MACTEMP);
2774105694Srwatson
2775105694Srwatson	return (error);
2776100979Srwatson}
2777100979Srwatson
2778100979Srwatson/*
2779100979Srwatson * Implementation of VOP_SETLABEL() that relies on extended attributes
2780100979Srwatson * to store label data.  Can be referenced by filesystems supporting
2781100979Srwatson * extended attributes.
2782100979Srwatson */
2783100979Srwatsonint
2784100979Srwatsonvop_stdsetlabel_ea(struct vop_setlabel_args *ap)
2785100979Srwatson{
2786100979Srwatson	struct vnode *vp = ap->a_vp;
2787100979Srwatson	struct label *intlabel = ap->a_label;
2788100979Srwatson	int error;
2789100979Srwatson
2790100979Srwatson	ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
2791100979Srwatson
2792105988Srwatson	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
2793105988Srwatson		return (EOPNOTSUPP);
2794100979Srwatson
2795105988Srwatson	error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel);
2796100979Srwatson	if (error)
2797100979Srwatson		return (error);
2798100979Srwatson
2799100979Srwatson	mac_relabel_vnode(ap->a_cred, vp, intlabel);
2800100979Srwatson
2801100979Srwatson	return (0);
2802100979Srwatson}
2803100979Srwatson
2804100979Srwatsonstatic int
2805100979Srwatsonvn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred)
2806100979Srwatson{
2807100979Srwatson	int error;
2808100979Srwatson
2809100979Srwatson	if (vp->v_mount == NULL) {
2810100979Srwatson		/* printf("vn_setlabel: null v_mount\n"); */
2811103314Snjl		if (vp->v_type != VNON)
2812103314Snjl			printf("vn_setlabel: null v_mount with non-VNON\n");
2813100979Srwatson		return (EBADF);
2814100979Srwatson	}
2815100979Srwatson
2816100979Srwatson	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
2817100979Srwatson		return (EOPNOTSUPP);
2818100979Srwatson
2819100979Srwatson	/*
2820100979Srwatson	 * Multi-phase commit.  First check the policies to confirm the
2821100979Srwatson	 * change is OK.  Then commit via the filesystem.  Finally,
2822100979Srwatson	 * update the actual vnode label.  Question: maybe the filesystem
2823100979Srwatson	 * should update the vnode at the end as part of VOP_SETLABEL()?
2824100979Srwatson	 */
2825100979Srwatson	error = mac_check_vnode_relabel(cred, vp, intlabel);
2826100979Srwatson	if (error)
2827100979Srwatson		return (error);
2828100979Srwatson
2829100979Srwatson	/*
2830100979Srwatson	 * VADMIN provides the opportunity for the filesystem to make
2831100979Srwatson	 * decisions about who is and is not able to modify labels
2832100979Srwatson	 * and protections on files.  This might not be right.  We can't
2833100979Srwatson	 * assume VOP_SETLABEL() will do it, because we might implement
2834100979Srwatson	 * that as part of vop_stdsetlabel_ea().
2835100979Srwatson	 */
2836100979Srwatson	error = VOP_ACCESS(vp, VADMIN, cred, curthread);
2837100979Srwatson	if (error)
2838100979Srwatson		return (error);
2839100979Srwatson
2840100979Srwatson	error = VOP_SETLABEL(vp, intlabel, cred, curthread);
2841100979Srwatson	if (error)
2842100979Srwatson		return (error);
2843100979Srwatson
2844100979Srwatson	return (0);
2845100979Srwatson}
2846100979Srwatson
2847105694Srwatsonint
2848105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
2849105694Srwatson{
2850105694Srwatson	char *elements, *buffer;
2851105694Srwatson	struct mac mac;
2852105694Srwatson	struct proc *tproc;
2853105694Srwatson	struct ucred *tcred;
2854105694Srwatson	int error;
2855105694Srwatson
2856105694Srwatson	error = copyin(SCARG(uap, mac_p), &mac, sizeof(mac));
2857105694Srwatson	if (error)
2858105694Srwatson		return (error);
2859105694Srwatson
2860105694Srwatson	error = mac_check_structmac_consistent(&mac);
2861105694Srwatson	if (error)
2862105694Srwatson		return (error);
2863105694Srwatson
2864105694Srwatson	tproc = pfind(uap->pid);
2865105694Srwatson	if (tproc == NULL)
2866105694Srwatson		return (ESRCH);
2867105694Srwatson
2868105694Srwatson	tcred = NULL;				/* Satisfy gcc. */
2869105694Srwatson	error = p_cansee(td, tproc);
2870105694Srwatson	if (error == 0)
2871105694Srwatson		tcred = crhold(tproc->p_ucred);
2872105694Srwatson	PROC_UNLOCK(tproc);
2873105694Srwatson	if (error)
2874105694Srwatson		return (error);
2875105694Srwatson
2876105694Srwatson	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
2877105694Srwatson	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
2878105694Srwatson	if (error) {
2879105694Srwatson		free(elements, M_MACTEMP);
2880105694Srwatson		crfree(tcred);
2881105694Srwatson		return (error);
2882105694Srwatson	}
2883105694Srwatson
2884105694Srwatson	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
2885105694Srwatson	error = mac_externalize_cred_label(&tcred->cr_label, elements,
2886105694Srwatson	    buffer, mac.m_buflen, M_WAITOK);
2887105694Srwatson	if (error == 0)
2888105694Srwatson		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
2889105694Srwatson
2890105694Srwatson	free(buffer, M_MACTEMP);
2891105694Srwatson	free(elements, M_MACTEMP);
2892105694Srwatson	crfree(tcred);
2893105694Srwatson	return (error);
2894105694Srwatson}
2895105694Srwatson
2896100979Srwatson/*
2897100979Srwatson * MPSAFE
2898100979Srwatson */
2899100979Srwatsonint
2900100894Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
2901100894Srwatson{
2902105694Srwatson	char *elements, *buffer;
2903105694Srwatson	struct mac mac;
2904100979Srwatson	int error;
2905100894Srwatson
2906105694Srwatson	error = copyin(uap->mac_p, &mac, sizeof(mac));
2907105694Srwatson	if (error)
2908105694Srwatson		return (error);
2909105694Srwatson
2910105694Srwatson	error = mac_check_structmac_consistent(&mac);
2911105694Srwatson	if (error)
2912105694Srwatson		return (error);
2913105694Srwatson
2914105694Srwatson	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
2915105694Srwatson	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
2916105694Srwatson	if (error) {
2917105694Srwatson		free(elements, M_MACTEMP);
2918105694Srwatson		return (error);
2919105694Srwatson	}
2920105694Srwatson
2921105694Srwatson	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
2922105694Srwatson	error = mac_externalize_cred_label(&td->td_ucred->cr_label,
2923105694Srwatson	    elements, buffer, mac.m_buflen, M_WAITOK);
2924100979Srwatson	if (error == 0)
2925105694Srwatson		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
2926100979Srwatson
2927105694Srwatson	free(buffer, M_MACTEMP);
2928105694Srwatson	free(elements, M_MACTEMP);
2929100979Srwatson	return (error);
2930100979Srwatson}
2931100979Srwatson
2932100979Srwatson/*
2933100979Srwatson * MPSAFE
2934100979Srwatson */
2935100979Srwatsonint
2936100979Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
2937100979Srwatson{
2938100979Srwatson	struct ucred *newcred, *oldcred;
2939105694Srwatson	struct label intlabel;
2940100979Srwatson	struct proc *p;
2941105694Srwatson	struct mac mac;
2942105694Srwatson	char *buffer;
2943100979Srwatson	int error;
2944100979Srwatson
2945105694Srwatson	error = copyin(uap->mac_p, &mac, sizeof(mac));
2946100979Srwatson	if (error)
2947100979Srwatson		return (error);
2948100979Srwatson
2949105694Srwatson	error = mac_check_structmac_consistent(&mac);
2950100979Srwatson	if (error)
2951100979Srwatson		return (error);
2952100979Srwatson
2953105694Srwatson	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
2954105694Srwatson	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
2955105694Srwatson	if (error) {
2956105694Srwatson		free(buffer, M_MACTEMP);
2957105694Srwatson		return (error);
2958105694Srwatson	}
2959105694Srwatson
2960105694Srwatson	mac_init_cred_label(&intlabel);
2961105694Srwatson	error = mac_internalize_cred_label(&intlabel, buffer);
2962105694Srwatson	free(buffer, M_MACTEMP);
2963105694Srwatson	if (error) {
2964105694Srwatson		mac_destroy_cred_label(&intlabel);
2965105694Srwatson		return (error);
2966105694Srwatson	}
2967105694Srwatson
2968100979Srwatson	newcred = crget();
2969100979Srwatson
2970100979Srwatson	p = td->td_proc;
2971100979Srwatson	PROC_LOCK(p);
2972100979Srwatson	oldcred = p->p_ucred;
2973100979Srwatson
2974100979Srwatson	error = mac_check_cred_relabel(oldcred, &intlabel);
2975100979Srwatson	if (error) {
2976100979Srwatson		PROC_UNLOCK(p);
2977100979Srwatson		crfree(newcred);
2978105694Srwatson		goto out;
2979100979Srwatson	}
2980100979Srwatson
2981100979Srwatson	setsugid(p);
2982100979Srwatson	crcopy(newcred, oldcred);
2983100979Srwatson	mac_relabel_cred(newcred, &intlabel);
2984102136Srwatson	p->p_ucred = newcred;
2985100979Srwatson
2986102136Srwatson	/*
2987102136Srwatson	 * Grab additional reference for use while revoking mmaps, prior
2988102136Srwatson	 * to releasing the proc lock and sharing the cred.
2989102136Srwatson	 */
2990102136Srwatson	crhold(newcred);
2991100979Srwatson	PROC_UNLOCK(p);
2992102136Srwatson
2993105694Srwatson	if (mac_enforce_vm) {
2994105694Srwatson		mtx_lock(&Giant);
2995105694Srwatson		mac_cred_mmapped_drop_perms(td, newcred);
2996105694Srwatson		mtx_unlock(&Giant);
2997105694Srwatson	}
2998102136Srwatson
2999102136Srwatson	crfree(newcred);	/* Free revocation reference. */
3000100979Srwatson	crfree(oldcred);
3001105694Srwatson
3002105694Srwatsonout:
3003105694Srwatson	mac_destroy_cred_label(&intlabel);
3004105694Srwatson	return (error);
3005100979Srwatson}
3006100979Srwatson
3007100979Srwatson/*
3008100979Srwatson * MPSAFE
3009100979Srwatson */
3010100979Srwatsonint
3011100979Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
3012100979Srwatson{
3013105694Srwatson	char *elements, *buffer;
3014105694Srwatson	struct label intlabel;
3015100979Srwatson	struct file *fp;
3016105694Srwatson	struct mac mac;
3017100979Srwatson	struct vnode *vp;
3018100979Srwatson	struct pipe *pipe;
3019105694Srwatson	short label_type;
3020100979Srwatson	int error;
3021100979Srwatson
3022105694Srwatson	error = copyin(uap->mac_p, &mac, sizeof(mac));
3023105694Srwatson	if (error)
3024105694Srwatson		return (error);
3025100979Srwatson
3026105694Srwatson	error = mac_check_structmac_consistent(&mac);
3027105694Srwatson	if (error)
3028105694Srwatson		return (error);
3029105694Srwatson
3030105694Srwatson	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3031105694Srwatson	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
3032105694Srwatson	if (error) {
3033105694Srwatson		free(elements, M_MACTEMP);
3034105694Srwatson		return (error);
3035105694Srwatson	}
3036105694Srwatson
3037105694Srwatson	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3038105694Srwatson	mtx_lock(&Giant);				/* VFS */
3039100979Srwatson	error = fget(td, SCARG(uap, fd), &fp);
3040100979Srwatson	if (error)
3041100979Srwatson		goto out;
3042100979Srwatson
3043105694Srwatson	label_type = fp->f_type;
3044100979Srwatson	switch (fp->f_type) {
3045100979Srwatson	case DTYPE_FIFO:
3046100979Srwatson	case DTYPE_VNODE:
3047100979Srwatson		vp = (struct vnode *)fp->f_data;
3048100979Srwatson
3049105694Srwatson		mac_init_vnode_label(&intlabel);
3050105694Srwatson
3051100979Srwatson		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3052105988Srwatson		mac_copy_vnode_label(&vp->v_label, &intlabel);
3053100979Srwatson		VOP_UNLOCK(vp, 0, td);
3054105694Srwatson
3055100979Srwatson		break;
3056100979Srwatson	case DTYPE_PIPE:
3057100979Srwatson		pipe = (struct pipe *)fp->f_data;
3058105694Srwatson
3059105694Srwatson		mac_init_pipe_label(&intlabel);
3060105694Srwatson
3061105694Srwatson		PIPE_LOCK(pipe);
3062105694Srwatson		mac_copy_pipe_label(pipe->pipe_label, &intlabel);
3063105694Srwatson		PIPE_UNLOCK(pipe);
3064100979Srwatson		break;
3065100979Srwatson	default:
3066100979Srwatson		error = EINVAL;
3067105694Srwatson		fdrop(fp, td);
3068105694Srwatson		goto out;
3069100979Srwatson	}
3070105694Srwatson	fdrop(fp, td);
3071100979Srwatson
3072105694Srwatson	switch (label_type) {
3073105694Srwatson	case DTYPE_FIFO:
3074105694Srwatson	case DTYPE_VNODE:
3075105694Srwatson		if (error == 0)
3076105694Srwatson			error = mac_externalize_vnode_label(&intlabel,
3077105694Srwatson			    elements, buffer, mac.m_buflen, M_WAITOK);
3078105694Srwatson		mac_destroy_vnode_label(&intlabel);
3079105694Srwatson		break;
3080105694Srwatson	case DTYPE_PIPE:
3081105694Srwatson		error = mac_externalize_pipe_label(&intlabel, elements,
3082105694Srwatson		    buffer, mac.m_buflen, M_WAITOK);
3083105694Srwatson		mac_destroy_pipe_label(&intlabel);
3084105694Srwatson		break;
3085105694Srwatson	default:
3086105694Srwatson		panic("__mac_get_fd: corrupted label_type");
3087105694Srwatson	}
3088105694Srwatson
3089100979Srwatson	if (error == 0)
3090105694Srwatson		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
3091100979Srwatson
3092105694Srwatsonout:
3093105694Srwatson	mtx_unlock(&Giant);				/* VFS */
3094105694Srwatson	free(buffer, M_MACTEMP);
3095105694Srwatson	free(elements, M_MACTEMP);
3096100979Srwatson
3097100979Srwatson	return (error);
3098100979Srwatson}
3099100979Srwatson
3100100979Srwatson/*
3101100979Srwatson * MPSAFE
3102100979Srwatson */
3103100979Srwatsonint
3104100979Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
3105100979Srwatson{
3106105694Srwatson	char *elements, *buffer;
3107100979Srwatson	struct nameidata nd;
3108105694Srwatson	struct label intlabel;
3109105694Srwatson	struct mac mac;
3110100979Srwatson	int error;
3111100979Srwatson
3112105694Srwatson	error = copyin(uap->mac_p, &mac, sizeof(mac));
3113105694Srwatson	if (error)
3114105694Srwatson		return (error);
3115105694Srwatson
3116105694Srwatson	error = mac_check_structmac_consistent(&mac);
3117105694Srwatson	if (error)
3118105694Srwatson		return (error);
3119105694Srwatson
3120105694Srwatson	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3121105694Srwatson	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
3122105694Srwatson	if (error) {
3123105694Srwatson		free(elements, M_MACTEMP);
3124105694Srwatson		return (error);
3125105694Srwatson	}
3126105694Srwatson
3127105694Srwatson	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3128105694Srwatson	mtx_lock(&Giant);				/* VFS */
3129105694Srwatson	NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p,
3130105694Srwatson	    td);
3131100979Srwatson	error = namei(&nd);
3132100979Srwatson	if (error)
3133100979Srwatson		goto out;
3134100979Srwatson
3135105694Srwatson	mac_init_vnode_label(&intlabel);
3136105988Srwatson	mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
3137105988Srwatson	error = mac_externalize_vnode_label(&intlabel, elements, buffer,
3138105988Srwatson	    mac.m_buflen, M_WAITOK);
3139105694Srwatson
3140100979Srwatson	NDFREE(&nd, 0);
3141105694Srwatson	mac_destroy_vnode_label(&intlabel);
3142105694Srwatson
3143105694Srwatson	if (error == 0)
3144105694Srwatson		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
3145105694Srwatson
3146105694Srwatsonout:
3147105694Srwatson	mtx_unlock(&Giant);				/* VFS */
3148105694Srwatson
3149105694Srwatson	free(buffer, M_MACTEMP);
3150105694Srwatson	free(elements, M_MACTEMP);
3151105694Srwatson
3152105694Srwatson	return (error);
3153105694Srwatson}
3154105694Srwatson
3155105694Srwatson/*
3156105694Srwatson * MPSAFE
3157105694Srwatson */
3158105694Srwatsonint
3159105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
3160105694Srwatson{
3161105694Srwatson	char *elements, *buffer;
3162105694Srwatson	struct nameidata nd;
3163105694Srwatson	struct label intlabel;
3164105694Srwatson	struct mac mac;
3165105694Srwatson	int error;
3166105694Srwatson
3167105694Srwatson	error = copyin(uap->mac_p, &mac, sizeof(mac));
3168100979Srwatson	if (error)
3169105694Srwatson		return (error);
3170105694Srwatson
3171105694Srwatson	error = mac_check_structmac_consistent(&mac);
3172105694Srwatson	if (error)
3173105694Srwatson		return (error);
3174105694Srwatson
3175105694Srwatson	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3176105694Srwatson	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
3177105694Srwatson	if (error) {
3178105694Srwatson		free(elements, M_MACTEMP);
3179105694Srwatson		return (error);
3180105694Srwatson	}
3181105694Srwatson
3182105694Srwatson	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3183105694Srwatson	mtx_lock(&Giant);				/* VFS */
3184105694Srwatson	NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p,
3185105694Srwatson	    td);
3186105694Srwatson	error = namei(&nd);
3187105694Srwatson	if (error)
3188100979Srwatson		goto out;
3189100979Srwatson
3190105694Srwatson	mac_init_vnode_label(&intlabel);
3191105988Srwatson	mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
3192105988Srwatson	error = mac_externalize_vnode_label(&intlabel, elements, buffer,
3193105988Srwatson	    mac.m_buflen, M_WAITOK);
3194105694Srwatson	NDFREE(&nd, 0);
3195105694Srwatson	mac_destroy_vnode_label(&intlabel);
3196100979Srwatson
3197105694Srwatson	if (error == 0)
3198105694Srwatson		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
3199105694Srwatson
3200100979Srwatsonout:
3201105694Srwatson	mtx_unlock(&Giant);				/* VFS */
3202105694Srwatson
3203105694Srwatson	free(buffer, M_MACTEMP);
3204105694Srwatson	free(elements, M_MACTEMP);
3205105694Srwatson
3206100979Srwatson	return (error);
3207100979Srwatson}
3208100979Srwatson
3209100979Srwatson/*
3210100979Srwatson * MPSAFE
3211100979Srwatson */
3212100979Srwatsonint
3213100979Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
3214100979Srwatson{
3215105694Srwatson	struct label intlabel;
3216105694Srwatson	struct pipe *pipe;
3217100979Srwatson	struct file *fp;
3218100979Srwatson	struct mount *mp;
3219100979Srwatson	struct vnode *vp;
3220105694Srwatson	struct mac mac;
3221105694Srwatson	char *buffer;
3222100979Srwatson	int error;
3223100979Srwatson
3224105694Srwatson	error = copyin(uap->mac_p, &mac, sizeof(mac));
3225100979Srwatson	if (error)
3226105694Srwatson		return (error);
3227100979Srwatson
3228105694Srwatson	error = mac_check_structmac_consistent(&mac);
3229100979Srwatson	if (error)
3230105694Srwatson		return (error);
3231100979Srwatson
3232105694Srwatson	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3233105694Srwatson	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
3234105694Srwatson	if (error) {
3235105694Srwatson		free(buffer, M_MACTEMP);
3236105694Srwatson		return (error);
3237105694Srwatson	}
3238105694Srwatson
3239105694Srwatson	mtx_lock(&Giant);				/* VFS */
3240105694Srwatson
3241105694Srwatson	error = fget(td, SCARG(uap, fd), &fp);
3242100979Srwatson	if (error)
3243105694Srwatson		goto out;
3244100979Srwatson
3245100979Srwatson	switch (fp->f_type) {
3246100979Srwatson	case DTYPE_FIFO:
3247100979Srwatson	case DTYPE_VNODE:
3248105694Srwatson		mac_init_vnode_label(&intlabel);
3249105694Srwatson		error = mac_internalize_vnode_label(&intlabel, buffer);
3250105694Srwatson		if (error) {
3251105694Srwatson			mac_destroy_vnode_label(&intlabel);
3252105694Srwatson			break;
3253105694Srwatson		}
3254105694Srwatson
3255100979Srwatson		vp = (struct vnode *)fp->f_data;
3256100979Srwatson		error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
3257105694Srwatson		if (error != 0) {
3258105694Srwatson			mac_destroy_vnode_label(&intlabel);
3259100979Srwatson			break;
3260105694Srwatson		}
3261100979Srwatson
3262100979Srwatson		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3263100979Srwatson		error = vn_setlabel(vp, &intlabel, td->td_ucred);
3264100979Srwatson		VOP_UNLOCK(vp, 0, td);
3265100979Srwatson		vn_finished_write(mp);
3266105694Srwatson
3267105694Srwatson		mac_destroy_vnode_label(&intlabel);
3268100979Srwatson		break;
3269105694Srwatson
3270100979Srwatson	case DTYPE_PIPE:
3271105694Srwatson		mac_init_pipe_label(&intlabel);
3272105694Srwatson		error = mac_internalize_pipe_label(&intlabel, buffer);
3273105694Srwatson		if (error == 0) {
3274105694Srwatson			pipe = (struct pipe *)fp->f_data;
3275105694Srwatson			PIPE_LOCK(pipe);
3276105694Srwatson			error = mac_pipe_label_set(td->td_ucred, pipe,
3277105694Srwatson			    &intlabel);
3278105694Srwatson			PIPE_UNLOCK(pipe);
3279105694Srwatson		}
3280105694Srwatson
3281105694Srwatson		mac_destroy_pipe_label(&intlabel);
3282100979Srwatson		break;
3283105694Srwatson
3284100979Srwatson	default:
3285100979Srwatson		error = EINVAL;
3286100979Srwatson	}
3287100979Srwatson
3288100979Srwatson	fdrop(fp, td);
3289105694Srwatsonout:
3290105694Srwatson	mtx_unlock(&Giant);				/* VFS */
3291105694Srwatson
3292105694Srwatson	free(buffer, M_MACTEMP);
3293105694Srwatson
3294100979Srwatson	return (error);
3295100979Srwatson}
3296100979Srwatson
3297100979Srwatson/*
3298100979Srwatson * MPSAFE
3299100979Srwatson */
3300100979Srwatsonint
3301100979Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
3302100979Srwatson{
3303105694Srwatson	struct label intlabel;
3304100979Srwatson	struct nameidata nd;
3305100979Srwatson	struct mount *mp;
3306105694Srwatson	struct mac mac;
3307105694Srwatson	char *buffer;
3308100979Srwatson	int error;
3309100979Srwatson
3310105694Srwatson	error = copyin(uap->mac_p, &mac, sizeof(mac));
3311100979Srwatson	if (error)
3312105694Srwatson		return (error);
3313100979Srwatson
3314105694Srwatson	error = mac_check_structmac_consistent(&mac);
3315100979Srwatson	if (error)
3316105694Srwatson		return (error);
3317100979Srwatson
3318105694Srwatson	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3319105694Srwatson	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
3320105694Srwatson	if (error) {
3321105694Srwatson		free(buffer, M_MACTEMP);
3322105694Srwatson		return (error);
3323105694Srwatson	}
3324105694Srwatson
3325105694Srwatson	mac_init_vnode_label(&intlabel);
3326105694Srwatson	error = mac_internalize_vnode_label(&intlabel, buffer);
3327105694Srwatson	free(buffer, M_MACTEMP);
3328105694Srwatson	if (error) {
3329105694Srwatson		mac_destroy_vnode_label(&intlabel);
3330105694Srwatson		return (error);
3331105694Srwatson	}
3332105694Srwatson
3333105694Srwatson	mtx_lock(&Giant);				/* VFS */
3334105694Srwatson
3335105694Srwatson	NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p,
3336105694Srwatson	    td);
3337100979Srwatson	error = namei(&nd);
3338105694Srwatson	if (error == 0) {
3339105694Srwatson		error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
3340105694Srwatson		if (error == 0)
3341105694Srwatson			error = vn_setlabel(nd.ni_vp, &intlabel,
3342105694Srwatson			    td->td_ucred);
3343105694Srwatson		vn_finished_write(mp);
3344105694Srwatson	}
3345105694Srwatson
3346105694Srwatson	NDFREE(&nd, 0);
3347105694Srwatson	mtx_unlock(&Giant);				/* VFS */
3348105694Srwatson	mac_destroy_vnode_label(&intlabel);
3349105694Srwatson
3350105694Srwatson	return (error);
3351105694Srwatson}
3352105694Srwatson
3353105694Srwatson/*
3354105694Srwatson * MPSAFE
3355105694Srwatson */
3356105694Srwatsonint
3357105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
3358105694Srwatson{
3359105694Srwatson	struct label intlabel;
3360105694Srwatson	struct nameidata nd;
3361105694Srwatson	struct mount *mp;
3362105694Srwatson	struct mac mac;
3363105694Srwatson	char *buffer;
3364105694Srwatson	int error;
3365105694Srwatson
3366105694Srwatson	error = copyin(uap->mac_p, &mac, sizeof(mac));
3367100979Srwatson	if (error)
3368105694Srwatson		return (error);
3369105694Srwatson
3370105694Srwatson	error = mac_check_structmac_consistent(&mac);
3371100979Srwatson	if (error)
3372105694Srwatson		return (error);
3373100979Srwatson
3374105694Srwatson	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3375105694Srwatson	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
3376105694Srwatson	if (error) {
3377105694Srwatson		free(buffer, M_MACTEMP);
3378105694Srwatson		return (error);
3379105694Srwatson	}
3380105694Srwatson
3381105694Srwatson	mac_init_vnode_label(&intlabel);
3382105694Srwatson	error = mac_internalize_vnode_label(&intlabel, buffer);
3383105694Srwatson	free(buffer, M_MACTEMP);
3384105694Srwatson	if (error) {
3385105694Srwatson		mac_destroy_vnode_label(&intlabel);
3386105694Srwatson		return (error);
3387105694Srwatson	}
3388105694Srwatson
3389105694Srwatson	mtx_lock(&Giant);				/* VFS */
3390105694Srwatson
3391105694Srwatson	NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p,
3392105694Srwatson	    td);
3393105694Srwatson	error = namei(&nd);
3394105694Srwatson	if (error == 0) {
3395105694Srwatson		error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
3396105694Srwatson		if (error == 0)
3397105694Srwatson			error = vn_setlabel(nd.ni_vp, &intlabel,
3398105694Srwatson			    td->td_ucred);
3399105694Srwatson		vn_finished_write(mp);
3400105694Srwatson	}
3401105694Srwatson
3402100979Srwatson	NDFREE(&nd, 0);
3403105694Srwatson	mtx_unlock(&Giant);				/* VFS */
3404105694Srwatson	mac_destroy_vnode_label(&intlabel);
3405105694Srwatson
3406100979Srwatson	return (error);
3407100979Srwatson}
3408100979Srwatson
3409105694Srwatson/*
3410105694Srwatson * MPSAFE
3411105694Srwatson */
3412102123Srwatsonint
3413102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap)
3414102123Srwatson{
3415102123Srwatson	struct mac_policy_conf *mpc;
3416102123Srwatson	char target[MAC_MAX_POLICY_NAME];
3417102123Srwatson	int error;
3418102123Srwatson
3419102123Srwatson	error = copyinstr(SCARG(uap, policy), target, sizeof(target), NULL);
3420102123Srwatson	if (error)
3421102123Srwatson		return (error);
3422102123Srwatson
3423102123Srwatson	error = ENOSYS;
3424102123Srwatson	MAC_POLICY_LIST_BUSY();
3425102123Srwatson	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {
3426102123Srwatson		if (strcmp(mpc->mpc_name, target) == 0 &&
3427102123Srwatson		    mpc->mpc_ops->mpo_syscall != NULL) {
3428102123Srwatson			error = mpc->mpc_ops->mpo_syscall(td,
3429102123Srwatson			    SCARG(uap, call), SCARG(uap, arg));
3430102123Srwatson			goto out;
3431102123Srwatson		}
3432102123Srwatson	}
3433102123Srwatson
3434102123Srwatsonout:
3435102123Srwatson	MAC_POLICY_LIST_UNBUSY();
3436102123Srwatson	return (error);
3437102123Srwatson}
3438102123Srwatson
3439100979SrwatsonSYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL);
3440100979SrwatsonSYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL);
3441100979Srwatson
3442100979Srwatson#else /* !MAC */
3443100979Srwatson
3444100979Srwatsonint
3445105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
3446105694Srwatson{
3447105694Srwatson
3448105694Srwatson	return (ENOSYS);
3449105694Srwatson}
3450105694Srwatson
3451105694Srwatsonint
3452100979Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
3453100979Srwatson{
3454100979Srwatson
3455100894Srwatson	return (ENOSYS);
3456100894Srwatson}
3457100894Srwatson
3458100894Srwatsonint
3459100894Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
3460100894Srwatson{
3461100894Srwatson
3462100894Srwatson	return (ENOSYS);
3463100894Srwatson}
3464100894Srwatson
3465100894Srwatsonint
3466100894Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
3467100894Srwatson{
3468100894Srwatson
3469100894Srwatson	return (ENOSYS);
3470100894Srwatson}
3471100894Srwatson
3472100894Srwatsonint
3473100894Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
3474100894Srwatson{
3475100894Srwatson
3476100894Srwatson	return (ENOSYS);
3477100894Srwatson}
3478100894Srwatson
3479100894Srwatsonint
3480105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
3481105694Srwatson{
3482105694Srwatson
3483105694Srwatson	return (ENOSYS);
3484105694Srwatson}
3485105694Srwatson
3486105694Srwatsonint
3487100894Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
3488100894Srwatson{
3489100894Srwatson
3490100894Srwatson	return (ENOSYS);
3491100894Srwatson}
3492100894Srwatson
3493100894Srwatsonint
3494100894Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
3495100894Srwatson{
3496100894Srwatson
3497100894Srwatson	return (ENOSYS);
3498100894Srwatson}
3499100979Srwatson
3500102123Srwatsonint
3501105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
3502105694Srwatson{
3503105694Srwatson
3504105694Srwatson	return (ENOSYS);
3505105694Srwatson}
3506105694Srwatson
3507105694Srwatsonint
3508102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap)
3509102123Srwatson{
3510102123Srwatson
3511102123Srwatson	return (ENOSYS);
3512102123Srwatson}
3513102123Srwatson
3514105694Srwatson#endif
3515