xref: /freebsd/sys/security/mac/mac_framework.c (revision 9e7bf51ca8a1418958e8ab694669407545c35b8d)
17bc82500SRobert Watson /*-
27bc82500SRobert Watson  * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
37bc82500SRobert Watson  * Copyright (c) 2001 Ilmar S. Habibulin
42d3db0b8SRobert Watson  * Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc.
57bc82500SRobert Watson  * All rights reserved.
67bc82500SRobert Watson  *
77bc82500SRobert Watson  * This software was developed by Robert Watson and Ilmar Habibulin for the
87bc82500SRobert Watson  * TrustedBSD Project.
97bc82500SRobert Watson  *
106201265bSRobert Watson  * This software was developed for the FreeBSD Project in part by Network
116201265bSRobert Watson  * Associates Laboratories, the Security Research Division of Network
126201265bSRobert Watson  * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
136201265bSRobert Watson  * as part of the DARPA CHATS research program.
147bc82500SRobert Watson  *
157bc82500SRobert Watson  * Redistribution and use in source and binary forms, with or without
167bc82500SRobert Watson  * modification, are permitted provided that the following conditions
177bc82500SRobert Watson  * are met:
187bc82500SRobert Watson  * 1. Redistributions of source code must retain the above copyright
197bc82500SRobert Watson  *    notice, this list of conditions and the following disclaimer.
207bc82500SRobert Watson  * 2. Redistributions in binary form must reproduce the above copyright
217bc82500SRobert Watson  *    notice, this list of conditions and the following disclaimer in the
227bc82500SRobert Watson  *    documentation and/or other materials provided with the distribution.
237bc82500SRobert Watson  *
247bc82500SRobert Watson  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
257bc82500SRobert Watson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
267bc82500SRobert Watson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
277bc82500SRobert Watson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
287bc82500SRobert Watson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
297bc82500SRobert Watson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
307bc82500SRobert Watson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
317bc82500SRobert Watson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
327bc82500SRobert Watson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
337bc82500SRobert Watson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
347bc82500SRobert Watson  * SUCH DAMAGE.
357bc82500SRobert Watson  */
36677b542eSDavid E. O'Brien 
377bc82500SRobert Watson /*
387bc82500SRobert Watson  * Framework for extensible kernel access control.  Kernel and userland
397bc82500SRobert Watson  * interface to the framework, policy registration and composition.
407bc82500SRobert Watson  */
417bc82500SRobert Watson 
42677b542eSDavid E. O'Brien #include <sys/cdefs.h>
43677b542eSDavid E. O'Brien __FBSDID("$FreeBSD$");
44677b542eSDavid E. O'Brien 
457bc82500SRobert Watson #include "opt_mac.h"
46328048bcSPoul-Henning Kamp #include "opt_devfs.h"
47f9d0d524SRobert Watson 
487bc82500SRobert Watson #include <sys/param.h>
49a96acd1aSRobert Watson #include <sys/condvar.h>
5095fab37eSRobert Watson #include <sys/extattr.h>
51670cb89bSRobert Watson #include <sys/imgact.h>
5295fab37eSRobert Watson #include <sys/kernel.h>
5395fab37eSRobert Watson #include <sys/lock.h>
54b656366bSBruce Evans #include <sys/malloc.h>
5595fab37eSRobert Watson #include <sys/mutex.h>
5695fab37eSRobert Watson #include <sys/mac.h>
577ba28492SRobert Watson #include <sys/module.h>
5895fab37eSRobert Watson #include <sys/proc.h>
59f51e5803SRobert Watson #include <sys/sbuf.h>
6095fab37eSRobert Watson #include <sys/systm.h>
617bc82500SRobert Watson #include <sys/sysproto.h>
627bc82500SRobert Watson #include <sys/sysent.h>
6395fab37eSRobert Watson #include <sys/vnode.h>
6495fab37eSRobert Watson #include <sys/mount.h>
6595fab37eSRobert Watson #include <sys/file.h>
6695fab37eSRobert Watson #include <sys/namei.h>
6795fab37eSRobert Watson #include <sys/socket.h>
6895fab37eSRobert Watson #include <sys/pipe.h>
6995fab37eSRobert Watson #include <sys/socketvar.h>
7095fab37eSRobert Watson #include <sys/sysctl.h>
7195fab37eSRobert Watson 
7295fab37eSRobert Watson #include <vm/vm.h>
7395fab37eSRobert Watson #include <vm/pmap.h>
7495fab37eSRobert Watson #include <vm/vm_map.h>
7595fab37eSRobert Watson #include <vm/vm_object.h>
7695fab37eSRobert Watson 
7795fab37eSRobert Watson #include <sys/mac_policy.h>
7895fab37eSRobert Watson 
7995fab37eSRobert Watson #include <fs/devfs/devfs.h>
8095fab37eSRobert Watson 
8195fab37eSRobert Watson #include <net/bpfdesc.h>
8295fab37eSRobert Watson #include <net/if.h>
8395fab37eSRobert Watson #include <net/if_var.h>
8495fab37eSRobert Watson 
8595fab37eSRobert Watson #include <netinet/in.h>
8695fab37eSRobert Watson #include <netinet/ip_var.h>
8795fab37eSRobert Watson 
8895fab37eSRobert Watson #ifdef MAC
8995fab37eSRobert Watson 
907ba28492SRobert Watson /*
917ba28492SRobert Watson  * Declare that the kernel provides MAC support, version 1.  This permits
927ba28492SRobert Watson  * modules to refuse to be loaded if the necessary support isn't present,
937ba28492SRobert Watson  * even if it's pre-boot.
947ba28492SRobert Watson  */
957ba28492SRobert Watson MODULE_VERSION(kernel_mac_support, 1);
967ba28492SRobert Watson 
9795fab37eSRobert Watson SYSCTL_DECL(_security);
9895fab37eSRobert Watson 
9995fab37eSRobert Watson SYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0,
10095fab37eSRobert Watson     "TrustedBSD MAC policy controls");
101b2f0927aSRobert Watson 
102b2aef571SRobert Watson #if MAC_MAX_SLOTS > 32
103b2aef571SRobert Watson #error "MAC_MAX_SLOTS too large"
10495fab37eSRobert Watson #endif
105a13c67daSRobert Watson 
106b2aef571SRobert Watson static unsigned int mac_max_slots = MAC_MAX_SLOTS;
107b2aef571SRobert Watson static unsigned int mac_slot_offsets_free = (1 << MAC_MAX_SLOTS) - 1;
108b2aef571SRobert Watson SYSCTL_UINT(_security_mac, OID_AUTO, max_slots, CTLFLAG_RD,
109b2aef571SRobert Watson     &mac_max_slots, 0, "");
11095fab37eSRobert Watson 
111a67fe518SRobert Watson /*
112a67fe518SRobert Watson  * Has the kernel started generating labeled objects yet?  All read/write
113a67fe518SRobert Watson  * access to this variable is serialized during the boot process.  Following
114a67fe518SRobert Watson  * the end of serialization, we don't update this flag; no locking.
115a67fe518SRobert Watson  */
11695fab37eSRobert Watson static int	mac_late = 0;
11795fab37eSRobert Watson 
118763bbd2fSRobert Watson /*
119763bbd2fSRobert Watson  * Warn about EA transactions only the first time they happen.
120763bbd2fSRobert Watson  * Weak coherency, no locking.
121763bbd2fSRobert Watson  */
122763bbd2fSRobert Watson static int	ea_warn_once = 0;
123763bbd2fSRobert Watson 
124225bff6fSRobert Watson /*
125225bff6fSRobert Watson  * Flag to indicate whether or not we should allocate label storage for
126225bff6fSRobert Watson  * new mbufs.  Since most dynamic policies we currently work with don't
127225bff6fSRobert Watson  * rely on mbuf labeling, try to avoid paying the cost of mtag allocation
128225bff6fSRobert Watson  * unless specifically notified of interest.  One result of this is
129225bff6fSRobert Watson  * that if a dynamically loaded policy requests mbuf labels, it must
130225bff6fSRobert Watson  * be able to deal with a NULL label being returned on any mbufs that
131225bff6fSRobert Watson  * were already in flight when the policy was loaded.  Since the policy
132225bff6fSRobert Watson  * already has to deal with uninitialized labels, this probably won't
133225bff6fSRobert Watson  * be a problem.  Note: currently no locking.  Will this be a problem?
134225bff6fSRobert Watson  */
13519c3e120SRobert Watson #ifndef MAC_ALWAYS_LABEL_MBUF
136225bff6fSRobert Watson static int	mac_labelmbufs = 0;
137225bff6fSRobert Watson #endif
138225bff6fSRobert Watson 
13995fab37eSRobert Watson static int	mac_enforce_fs = 1;
14095fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
14195fab37eSRobert Watson     &mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
14295fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
14395fab37eSRobert Watson 
144a3df768bSRobert Watson static int	mac_enforce_kld = 1;
145a3df768bSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW,
146a3df768bSRobert Watson     &mac_enforce_kld, 0, "Enforce MAC policy on kld operations");
147a3df768bSRobert Watson TUNABLE_INT("security.mac.enforce_kld", &mac_enforce_kld);
148a3df768bSRobert Watson 
14995fab37eSRobert Watson static int	mac_enforce_network = 1;
15095fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
15195fab37eSRobert Watson     &mac_enforce_network, 0, "Enforce MAC policy on network packets");
15295fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_network", &mac_enforce_network);
15395fab37eSRobert Watson 
154b88c98f6SRobert Watson static int	mac_enforce_pipe = 1;
155b88c98f6SRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW,
156b88c98f6SRobert Watson     &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations");
157c031391bSRobert Watson TUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe);
158b88c98f6SRobert Watson 
15995fab37eSRobert Watson static int	mac_enforce_process = 1;
16095fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW,
16195fab37eSRobert Watson     &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations");
16295fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_process", &mac_enforce_process);
16395fab37eSRobert Watson 
16495fab37eSRobert Watson static int	mac_enforce_socket = 1;
16595fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
16695fab37eSRobert Watson     &mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
16795fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
16895fab37eSRobert Watson 
1699e913ebdSRobert Watson static int	mac_enforce_system = 1;
1709e913ebdSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_system, CTLFLAG_RW,
1719e913ebdSRobert Watson     &mac_enforce_system, 0, "Enforce MAC policy on system operations");
1729e913ebdSRobert Watson TUNABLE_INT("security.mac.enforce_system", &mac_enforce_system);
173d3fc69eeSRobert Watson 
174ca7850c3SRobert Watson static int	mac_enforce_vm = 1;
175ca7850c3SRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
176ca7850c3SRobert Watson     &mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
177c031391bSRobert Watson TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm);
178ca7850c3SRobert Watson 
179c0f39905SRobert Watson static int	mac_mmap_revocation = 1;
180c0f39905SRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW,
181c0f39905SRobert Watson     &mac_mmap_revocation, 0, "Revoke mmap access to files on subject "
182c0f39905SRobert Watson     "relabel");
18399fa64f8SRobert Watson static int	mac_mmap_revocation_via_cow = 0;
18495fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW,
18595fab37eSRobert Watson     &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via "
18695fab37eSRobert Watson     "copy-on-write semantics, or by removing all write access");
18795fab37eSRobert Watson 
188f050add5SRobert Watson #ifdef MAC_DEBUG
1896be0c25eSRobert Watson SYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0,
1906be0c25eSRobert Watson     "TrustedBSD MAC debug info");
1916be0c25eSRobert Watson 
1926be0c25eSRobert Watson static int	mac_debug_label_fallback = 0;
1936be0c25eSRobert Watson SYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW,
1946be0c25eSRobert Watson     &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label"
1956be0c25eSRobert Watson     "when label is corrupted.");
1966be0c25eSRobert Watson TUNABLE_INT("security.mac.debug_label_fallback",
1976be0c25eSRobert Watson     &mac_debug_label_fallback);
1986be0c25eSRobert Watson 
199b2f0927aSRobert Watson SYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0,
200b2f0927aSRobert Watson     "TrustedBSD MAC object counters");
201b2f0927aSRobert Watson 
20295fab37eSRobert Watson static unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs,
20395fab37eSRobert Watson     nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents,
2042555374cSRobert Watson     nmacipqs, nmacpipes, nmacprocs;
205b2f0927aSRobert Watson 
2068d8d5ea8SRobert Watson #define	MAC_DEBUG_COUNTER_INC(x)	atomic_add_int(x, 1);
2078d8d5ea8SRobert Watson #define	MAC_DEBUG_COUNTER_DEC(x)	atomic_subtract_int(x, 1);
2088d8d5ea8SRobert Watson 
209b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD,
21095fab37eSRobert Watson     &nmacmbufs, 0, "number of mbufs in use");
211b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD,
21295fab37eSRobert Watson     &nmaccreds, 0, "number of ucreds in use");
213b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD,
21495fab37eSRobert Watson     &nmacifnets, 0, "number of ifnets in use");
215b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD,
21695fab37eSRobert Watson     &nmacipqs, 0, "number of ipqs in use");
217b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD,
21895fab37eSRobert Watson     &nmacbpfdescs, 0, "number of bpfdescs in use");
219b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD,
22095fab37eSRobert Watson     &nmacsockets, 0, "number of sockets in use");
221b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, pipes, CTLFLAG_RD,
22295fab37eSRobert Watson     &nmacpipes, 0, "number of pipes in use");
2232555374cSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, procs, CTLFLAG_RD,
2242555374cSRobert Watson     &nmacprocs, 0, "number of procs in use");
225b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD,
22695fab37eSRobert Watson     &nmacmounts, 0, "number of mounts in use");
227b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD,
22895fab37eSRobert Watson     &nmactemp, 0, "number of temporary labels in use");
229b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD,
23095fab37eSRobert Watson     &nmacvnodes, 0, "number of vnodes in use");
231b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD,
23295fab37eSRobert Watson     &nmacdevfsdirents, 0, "number of devfs dirents inuse");
2338d8d5ea8SRobert Watson #else
2348d8d5ea8SRobert Watson #define	MAC_DEBUG_COUNTER_INC(x)
2358d8d5ea8SRobert Watson #define	MAC_DEBUG_COUNTER_DEC(x)
236f050add5SRobert Watson #endif
23795fab37eSRobert Watson 
23895fab37eSRobert Watson static int	mac_policy_register(struct mac_policy_conf *mpc);
23995fab37eSRobert Watson static int	mac_policy_unregister(struct mac_policy_conf *mpc);
24095fab37eSRobert Watson 
241e183f80eSRobert Watson static void	mac_check_vnode_mmap_downgrade(struct ucred *cred,
242e183f80eSRobert Watson 		    struct vnode *vp, int *prot);
24395fab37eSRobert Watson static void	mac_cred_mmapped_drop_perms_recurse(struct thread *td,
24495fab37eSRobert Watson 		    struct ucred *cred, struct vm_map *map);
24595fab37eSRobert Watson 
24683985c26SRobert Watson static void	mac_destroy_socket_label(struct label *label);
24783985c26SRobert Watson 
248763bbd2fSRobert Watson static int	mac_setlabel_vnode_extattr(struct ucred *cred,
249763bbd2fSRobert Watson 		    struct vnode *vp, struct label *intlabel);
250763bbd2fSRobert Watson 
25195fab37eSRobert Watson MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes");
252f7b951a8SRobert Watson MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
25395fab37eSRobert Watson 
25495fab37eSRobert Watson /*
25541a17fe3SRobert Watson  * mac_static_policy_list holds a list of policy modules that are not
25641a17fe3SRobert Watson  * loaded while the system is "live", and cannot be unloaded.  These
25741a17fe3SRobert Watson  * policies can be invoked without holding the busy count.
25841a17fe3SRobert Watson  *
25941a17fe3SRobert Watson  * mac_policy_list stores the list of dynamic policies.  A busy count is
260a96acd1aSRobert Watson  * maintained for the list, stored in mac_policy_busy.  The busy count
26141a17fe3SRobert Watson  * is protected by mac_policy_mtx; the list may be modified only
262a96acd1aSRobert Watson  * while the busy count is 0, requiring that the lock be held to
263a96acd1aSRobert Watson  * prevent new references to the list from being acquired.  For almost
264a96acd1aSRobert Watson  * all operations, incrementing the busy count is sufficient to
265a96acd1aSRobert Watson  * guarantee consistency, as the list cannot be modified while the
266a96acd1aSRobert Watson  * busy count is elevated.  For a few special operations involving a
26741a17fe3SRobert Watson  * change to the list of active policies, the mtx itself must be held.
26841a17fe3SRobert Watson  * A condition variable, mac_policy_cv, is used to signal potential
26941a17fe3SRobert Watson  * exclusive consumers that they should try to acquire the lock if a
27041a17fe3SRobert Watson  * first attempt at exclusive access fails.
27195fab37eSRobert Watson  */
27241a17fe3SRobert Watson static struct mtx mac_policy_mtx;
27341a17fe3SRobert Watson static struct cv mac_policy_cv;
27441a17fe3SRobert Watson static int mac_policy_count;
27595fab37eSRobert Watson static LIST_HEAD(, mac_policy_conf) mac_policy_list;
27641a17fe3SRobert Watson static LIST_HEAD(, mac_policy_conf) mac_static_policy_list;
277a96acd1aSRobert Watson 
278a96acd1aSRobert Watson /*
27926306795SJohn Baldwin  * We manually invoke WITNESS_WARN() to allow Witness to generate
280a96acd1aSRobert Watson  * warnings even if we don't end up ever triggering the wait at
281a96acd1aSRobert Watson  * run-time.  The consumer of the exclusive interface must not hold
282a96acd1aSRobert Watson  * any locks (other than potentially Giant) since we may sleep for
283a96acd1aSRobert Watson  * long (potentially indefinite) periods of time waiting for the
284a96acd1aSRobert Watson  * framework to become quiescent so that a policy list change may
285a96acd1aSRobert Watson  * be made.
286a96acd1aSRobert Watson  */
28741a17fe3SRobert Watson static __inline void
28841a17fe3SRobert Watson mac_policy_grab_exclusive(void)
28941a17fe3SRobert Watson {
29041a17fe3SRobert Watson 	WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
29141a17fe3SRobert Watson  	    "mac_policy_grab_exclusive() at %s:%d", __FILE__, __LINE__);
29241a17fe3SRobert Watson 	mtx_lock(&mac_policy_mtx);
29341a17fe3SRobert Watson 	while (mac_policy_count != 0)
29441a17fe3SRobert Watson 		cv_wait(&mac_policy_cv, &mac_policy_mtx);
29541a17fe3SRobert Watson }
29695fab37eSRobert Watson 
29741a17fe3SRobert Watson static __inline void
29841a17fe3SRobert Watson mac_policy_assert_exclusive(void)
29941a17fe3SRobert Watson {
30041a17fe3SRobert Watson 	mtx_assert(&mac_policy_mtx, MA_OWNED);
30141a17fe3SRobert Watson 	KASSERT(mac_policy_count == 0,
30241a17fe3SRobert Watson 	    ("mac_policy_assert_exclusive(): not exclusive"));
30341a17fe3SRobert Watson }
304225bff6fSRobert Watson 
30541a17fe3SRobert Watson static __inline void
30641a17fe3SRobert Watson mac_policy_release_exclusive(void)
30741a17fe3SRobert Watson {
30895fab37eSRobert Watson 
30941a17fe3SRobert Watson 	KASSERT(mac_policy_count == 0,
31041a17fe3SRobert Watson 	    ("mac_policy_release_exclusive(): not exclusive"));
31141a17fe3SRobert Watson 	mtx_unlock(&mac_policy_mtx);
31241a17fe3SRobert Watson 	cv_signal(&mac_policy_cv);
31341a17fe3SRobert Watson }
31441a17fe3SRobert Watson 
31541a17fe3SRobert Watson static __inline void
31641a17fe3SRobert Watson mac_policy_list_busy(void)
31741a17fe3SRobert Watson {
31841a17fe3SRobert Watson 	mtx_lock(&mac_policy_mtx);
31941a17fe3SRobert Watson 	mac_policy_count++;
32041a17fe3SRobert Watson 	mtx_unlock(&mac_policy_mtx);
32141a17fe3SRobert Watson }
32241a17fe3SRobert Watson 
32341a17fe3SRobert Watson static __inline int
32441a17fe3SRobert Watson mac_policy_list_conditional_busy(void)
32541a17fe3SRobert Watson {
32641a17fe3SRobert Watson 	int ret;
32741a17fe3SRobert Watson 
32841a17fe3SRobert Watson 	mtx_lock(&mac_policy_mtx);
32941a17fe3SRobert Watson 	if (!LIST_EMPTY(&mac_policy_list)) {
33041a17fe3SRobert Watson 		mac_policy_count++;
33141a17fe3SRobert Watson 		ret = 1;
33241a17fe3SRobert Watson 	} else
33341a17fe3SRobert Watson 		ret = 0;
33441a17fe3SRobert Watson 	mtx_unlock(&mac_policy_mtx);
33541a17fe3SRobert Watson 	return (ret);
33641a17fe3SRobert Watson }
33741a17fe3SRobert Watson 
33841a17fe3SRobert Watson static __inline void
33941a17fe3SRobert Watson mac_policy_list_unbusy(void)
34041a17fe3SRobert Watson {
34141a17fe3SRobert Watson 	mtx_lock(&mac_policy_mtx);
34241a17fe3SRobert Watson 	mac_policy_count--;
34341a17fe3SRobert Watson 	KASSERT(mac_policy_count >= 0, ("MAC_POLICY_LIST_LOCK"));
34441a17fe3SRobert Watson 	if (mac_policy_count == 0)
34541a17fe3SRobert Watson 		cv_signal(&mac_policy_cv);
34641a17fe3SRobert Watson 	mtx_unlock(&mac_policy_mtx);
34741a17fe3SRobert Watson }
34895fab37eSRobert Watson 
34995fab37eSRobert Watson /*
35095fab37eSRobert Watson  * MAC_CHECK performs the designated check by walking the policy
35195fab37eSRobert Watson  * module list and checking with each as to how it feels about the
35295fab37eSRobert Watson  * request.  Note that it returns its value via 'error' in the scope
35395fab37eSRobert Watson  * of the caller.
35495fab37eSRobert Watson  */
35595fab37eSRobert Watson #define	MAC_CHECK(check, args...) do {					\
35695fab37eSRobert Watson 	struct mac_policy_conf *mpc;					\
35741a17fe3SRobert Watson 	int entrycount;							\
35895fab37eSRobert Watson 									\
35995fab37eSRobert Watson 	error = 0;							\
36041a17fe3SRobert Watson 	LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {		\
36141a17fe3SRobert Watson 		if (mpc->mpc_ops->mpo_ ## check != NULL)		\
3629e7bf51cSRobert Watson 			error = mac_error_select(			\
36341a17fe3SRobert Watson 			    mpc->mpc_ops->mpo_ ## check (args),		\
36441a17fe3SRobert Watson 			    error);					\
36541a17fe3SRobert Watson 	}								\
36641a17fe3SRobert Watson 	if ((entrycount = mac_policy_list_conditional_busy()) != 0) {	\
36795fab37eSRobert Watson 		LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {		\
36895fab37eSRobert Watson 			if (mpc->mpc_ops->mpo_ ## check != NULL)	\
3699e7bf51cSRobert Watson 				error = mac_error_select(		\
37095fab37eSRobert Watson 				    mpc->mpc_ops->mpo_ ## check (args),	\
37195fab37eSRobert Watson 				    error);				\
37295fab37eSRobert Watson 		}							\
37341a17fe3SRobert Watson 		mac_policy_list_unbusy();				\
37441a17fe3SRobert Watson 	}								\
37595fab37eSRobert Watson } while (0)
37695fab37eSRobert Watson 
37795fab37eSRobert Watson /*
37895fab37eSRobert Watson  * MAC_BOOLEAN performs the designated boolean composition by walking
37995fab37eSRobert Watson  * the module list, invoking each instance of the operation, and
38095fab37eSRobert Watson  * combining the results using the passed C operator.  Note that it
38195fab37eSRobert Watson  * returns its value via 'result' in the scope of the caller, which
38295fab37eSRobert Watson  * should be initialized by the caller in a meaningful way to get
38395fab37eSRobert Watson  * a meaningful result.
38495fab37eSRobert Watson  */
38595fab37eSRobert Watson #define	MAC_BOOLEAN(operation, composition, args...) do {		\
38695fab37eSRobert Watson 	struct mac_policy_conf *mpc;					\
38741a17fe3SRobert Watson 	int entrycount;							\
38895fab37eSRobert Watson 									\
38941a17fe3SRobert Watson 	LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {		\
39095fab37eSRobert Watson 		if (mpc->mpc_ops->mpo_ ## operation != NULL)		\
39195fab37eSRobert Watson 			result = result composition			\
39295fab37eSRobert Watson 			    mpc->mpc_ops->mpo_ ## operation (args);	\
39395fab37eSRobert Watson 	}								\
39441a17fe3SRobert Watson 	if ((entrycount = mac_policy_list_conditional_busy()) != 0) {	\
39541a17fe3SRobert Watson 		LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {		\
39641a17fe3SRobert Watson 			if (mpc->mpc_ops->mpo_ ## operation != NULL)	\
39741a17fe3SRobert Watson 				result = result composition		\
39841a17fe3SRobert Watson 				    mpc->mpc_ops->mpo_ ## operation	\
39941a17fe3SRobert Watson 				    (args);				\
40041a17fe3SRobert Watson 		}							\
40141a17fe3SRobert Watson 		mac_policy_list_unbusy();				\
40241a17fe3SRobert Watson 	}								\
40395fab37eSRobert Watson } while (0)
40495fab37eSRobert Watson 
405f7b951a8SRobert Watson #define	MAC_EXTERNALIZE(type, label, elementlist, outbuf, 		\
406f7b951a8SRobert Watson     outbuflen) do {							\
407f51e5803SRobert Watson 	int claimed, first, ignorenotfound, savedlen;			\
408f51e5803SRobert Watson 	char *element_name, *element_temp;				\
409f51e5803SRobert Watson 	struct sbuf sb;							\
410f7b951a8SRobert Watson 									\
411f7b951a8SRobert Watson 	error = 0;							\
412f7b951a8SRobert Watson 	first = 1;							\
413f51e5803SRobert Watson 	sbuf_new(&sb, outbuf, outbuflen, SBUF_FIXEDLEN);		\
414f51e5803SRobert Watson 	element_temp = elementlist;					\
415f7b951a8SRobert Watson 	while ((element_name = strsep(&element_temp, ",")) != NULL) {	\
416f7b951a8SRobert Watson 		if (element_name[0] == '?') {				\
417f7b951a8SRobert Watson 			element_name++;					\
418f7b951a8SRobert Watson 			ignorenotfound = 1;				\
419f7b951a8SRobert Watson 		 } else							\
420f7b951a8SRobert Watson 			ignorenotfound = 0;				\
421f51e5803SRobert Watson 		savedlen = sbuf_len(&sb);				\
422f7b951a8SRobert Watson 		if (first) {						\
423f51e5803SRobert Watson 			error = sbuf_printf(&sb, "%s/", element_name);	\
424f7b951a8SRobert Watson 			first = 0;					\
425f7b951a8SRobert Watson 		} else							\
426f51e5803SRobert Watson 			error = sbuf_printf(&sb, ",%s/", element_name);	\
427f51e5803SRobert Watson 		if (error == -1) {					\
428f51e5803SRobert Watson 			error = EINVAL;	/* XXX: E2BIG? */		\
429f7b951a8SRobert Watson 			break;						\
430f7b951a8SRobert Watson 		}							\
431f51e5803SRobert Watson 		claimed = 0;						\
432f7b951a8SRobert Watson 		MAC_CHECK(externalize_ ## type, label, element_name,	\
433f51e5803SRobert Watson 		    &sb, &claimed);					\
434f7b951a8SRobert Watson 		if (error)						\
435f7b951a8SRobert Watson 			break;						\
436f51e5803SRobert Watson 		if (claimed == 0 && ignorenotfound) {			\
437f51e5803SRobert Watson 			/* Revert last label name. */			\
438f51e5803SRobert Watson 			sbuf_setpos(&sb, savedlen);			\
439f51e5803SRobert Watson 		} else if (claimed != 1) {				\
440f51e5803SRobert Watson 			error = EINVAL;	/* XXX: ENOLABEL? */		\
441f7b951a8SRobert Watson 			break;						\
442f7b951a8SRobert Watson 		}							\
443f7b951a8SRobert Watson 	}								\
444f51e5803SRobert Watson 	sbuf_finish(&sb);						\
445f7b951a8SRobert Watson } while (0)
446f7b951a8SRobert Watson 
447f7b951a8SRobert Watson #define	MAC_INTERNALIZE(type, label, instring) do {			\
448f7b951a8SRobert Watson 	char *element, *element_name, *element_data;			\
449f7b951a8SRobert Watson 	int claimed;							\
450f7b951a8SRobert Watson 									\
451f7b951a8SRobert Watson 	error = 0;							\
452f7b951a8SRobert Watson 	element = instring;						\
453f7b951a8SRobert Watson 	while ((element_name = strsep(&element, ",")) != NULL) {	\
454f7b951a8SRobert Watson 		element_data = element_name;				\
455f7b951a8SRobert Watson 		element_name = strsep(&element_data, "/");		\
456f7b951a8SRobert Watson 		if (element_data == NULL) {				\
457f7b951a8SRobert Watson 			error = EINVAL;					\
458f7b951a8SRobert Watson 			break;						\
459f7b951a8SRobert Watson 		}							\
460f7b951a8SRobert Watson 		claimed = 0;						\
461f7b951a8SRobert Watson 		MAC_CHECK(internalize_ ## type, label, element_name,	\
462f7b951a8SRobert Watson 		    element_data, &claimed);				\
463f7b951a8SRobert Watson 		if (error)						\
464f7b951a8SRobert Watson 			break;						\
465f7b951a8SRobert Watson 		if (claimed != 1) {					\
466f7b951a8SRobert Watson 			/* XXXMAC: Another error here? */		\
467f7b951a8SRobert Watson 			error = EINVAL;					\
468f7b951a8SRobert Watson 			break;						\
469f7b951a8SRobert Watson 		}							\
470f7b951a8SRobert Watson 	}								\
471f7b951a8SRobert Watson } while (0)
472f7b951a8SRobert Watson 
47395fab37eSRobert Watson /*
47495fab37eSRobert Watson  * MAC_PERFORM performs the designated operation by walking the policy
47595fab37eSRobert Watson  * module list and invoking that operation for each policy.
47695fab37eSRobert Watson  */
47795fab37eSRobert Watson #define	MAC_PERFORM(operation, args...) do {				\
47895fab37eSRobert Watson 	struct mac_policy_conf *mpc;					\
47941a17fe3SRobert Watson 	int entrycount;							\
48095fab37eSRobert Watson 									\
48141a17fe3SRobert Watson 	LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {		\
48241a17fe3SRobert Watson 		if (mpc->mpc_ops->mpo_ ## operation != NULL)		\
48341a17fe3SRobert Watson 			mpc->mpc_ops->mpo_ ## operation (args);		\
48441a17fe3SRobert Watson 	}								\
48541a17fe3SRobert Watson 	if ((entrycount = mac_policy_list_conditional_busy()) != 0) {	\
48695fab37eSRobert Watson 		LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {		\
48795fab37eSRobert Watson 			if (mpc->mpc_ops->mpo_ ## operation != NULL)	\
48895fab37eSRobert Watson 				mpc->mpc_ops->mpo_ ## operation (args);	\
48995fab37eSRobert Watson 		}							\
49041a17fe3SRobert Watson 		mac_policy_list_unbusy();				\
49141a17fe3SRobert Watson 	}								\
49295fab37eSRobert Watson } while (0)
49395fab37eSRobert Watson 
49495fab37eSRobert Watson /*
49595fab37eSRobert Watson  * Initialize the MAC subsystem, including appropriate SMP locks.
49695fab37eSRobert Watson  */
49795fab37eSRobert Watson static void
49895fab37eSRobert Watson mac_init(void)
49995fab37eSRobert Watson {
50095fab37eSRobert Watson 
50141a17fe3SRobert Watson 	LIST_INIT(&mac_static_policy_list);
50295fab37eSRobert Watson 	LIST_INIT(&mac_policy_list);
50341a17fe3SRobert Watson 
50441a17fe3SRobert Watson 	mtx_init(&mac_policy_mtx, "mac_policy_mtx", NULL, MTX_DEF);
50541a17fe3SRobert Watson 	cv_init(&mac_policy_cv, "mac_policy_cv");
50695fab37eSRobert Watson }
50795fab37eSRobert Watson 
50895fab37eSRobert Watson /*
50995fab37eSRobert Watson  * For the purposes of modules that want to know if they were loaded
51095fab37eSRobert Watson  * "early", set the mac_late flag once we've processed modules either
51195fab37eSRobert Watson  * linked into the kernel, or loaded before the kernel startup.
51295fab37eSRobert Watson  */
51395fab37eSRobert Watson static void
51495fab37eSRobert Watson mac_late_init(void)
51595fab37eSRobert Watson {
51695fab37eSRobert Watson 
51795fab37eSRobert Watson 	mac_late = 1;
51895fab37eSRobert Watson }
51995fab37eSRobert Watson 
52095fab37eSRobert Watson /*
521225bff6fSRobert Watson  * After the policy list has changed, walk the list to update any global
52219c3e120SRobert Watson  * flags.  Currently, we support only one flag, and it's conditionally
52319c3e120SRobert Watson  * defined; as a result, the entire function is conditional.  Eventually,
52419c3e120SRobert Watson  * the #else case might also iterate across the policies.
525225bff6fSRobert Watson  */
526225bff6fSRobert Watson static void
527225bff6fSRobert Watson mac_policy_updateflags(void)
528225bff6fSRobert Watson {
529225bff6fSRobert Watson #ifndef MAC_ALWAYS_LABEL_MBUF
53019c3e120SRobert Watson 	struct mac_policy_conf *tmpc;
531225bff6fSRobert Watson 	int labelmbufs;
532225bff6fSRobert Watson 
53341a17fe3SRobert Watson 	mac_policy_assert_exclusive();
534225bff6fSRobert Watson 
535225bff6fSRobert Watson 	labelmbufs = 0;
53641a17fe3SRobert Watson 	LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) {
53741a17fe3SRobert Watson 		if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS)
53841a17fe3SRobert Watson 			labelmbufs++;
53941a17fe3SRobert Watson 	}
540225bff6fSRobert Watson 	LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) {
541225bff6fSRobert Watson 		if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS)
542225bff6fSRobert Watson 			labelmbufs++;
543225bff6fSRobert Watson 	}
544225bff6fSRobert Watson 	mac_labelmbufs = (labelmbufs != 0);
545225bff6fSRobert Watson #endif
546225bff6fSRobert Watson }
547225bff6fSRobert Watson 
548225bff6fSRobert Watson /*
54995fab37eSRobert Watson  * Allow MAC policy modules to register during boot, etc.
55095fab37eSRobert Watson  */
55195fab37eSRobert Watson int
55295fab37eSRobert Watson mac_policy_modevent(module_t mod, int type, void *data)
55395fab37eSRobert Watson {
55495fab37eSRobert Watson 	struct mac_policy_conf *mpc;
55595fab37eSRobert Watson 	int error;
55695fab37eSRobert Watson 
55795fab37eSRobert Watson 	error = 0;
55895fab37eSRobert Watson 	mpc = (struct mac_policy_conf *) data;
55995fab37eSRobert Watson 
56095fab37eSRobert Watson 	switch (type) {
56195fab37eSRobert Watson 	case MOD_LOAD:
56295fab37eSRobert Watson 		if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE &&
56395fab37eSRobert Watson 		    mac_late) {
56495fab37eSRobert Watson 			printf("mac_policy_modevent: can't load %s policy "
56595fab37eSRobert Watson 			    "after booting\n", mpc->mpc_name);
56695fab37eSRobert Watson 			error = EBUSY;
56795fab37eSRobert Watson 			break;
56895fab37eSRobert Watson 		}
56995fab37eSRobert Watson 		error = mac_policy_register(mpc);
57095fab37eSRobert Watson 		break;
57195fab37eSRobert Watson 	case MOD_UNLOAD:
57295fab37eSRobert Watson 		/* Don't unregister the module if it was never registered. */
57395fab37eSRobert Watson 		if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED)
57495fab37eSRobert Watson 		    != 0)
57595fab37eSRobert Watson 			error = mac_policy_unregister(mpc);
57695fab37eSRobert Watson 		else
57795fab37eSRobert Watson 			error = 0;
57895fab37eSRobert Watson 		break;
57995fab37eSRobert Watson 	default:
58095fab37eSRobert Watson 		break;
58195fab37eSRobert Watson 	}
58295fab37eSRobert Watson 
58395fab37eSRobert Watson 	return (error);
58495fab37eSRobert Watson }
58595fab37eSRobert Watson 
58695fab37eSRobert Watson static int
58795fab37eSRobert Watson mac_policy_register(struct mac_policy_conf *mpc)
58895fab37eSRobert Watson {
58995fab37eSRobert Watson 	struct mac_policy_conf *tmpc;
59041a17fe3SRobert Watson 	int error, slot, static_entry;
59195fab37eSRobert Watson 
59241a17fe3SRobert Watson 	error = 0;
59341a17fe3SRobert Watson 
59441a17fe3SRobert Watson 	/*
59541a17fe3SRobert Watson 	 * We don't technically need exclusive access while !mac_late,
59641a17fe3SRobert Watson 	 * but hold it for assertion consistency.
59741a17fe3SRobert Watson 	 */
59841a17fe3SRobert Watson 	mac_policy_grab_exclusive();
59941a17fe3SRobert Watson 
60041a17fe3SRobert Watson 	/*
60141a17fe3SRobert Watson 	 * If the module can potentially be unloaded, or we're loading
60241a17fe3SRobert Watson 	 * late, we have to stick it in the non-static list and pay
60341a17fe3SRobert Watson 	 * an extra performance overhead.  Otherwise, we can pay a
60441a17fe3SRobert Watson 	 * light locking cost and stick it in the static list.
60541a17fe3SRobert Watson 	 */
60641a17fe3SRobert Watson 	static_entry = (!mac_late &&
60741a17fe3SRobert Watson 	    !(mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK));
60841a17fe3SRobert Watson 
60941a17fe3SRobert Watson 	if (static_entry) {
61041a17fe3SRobert Watson 		LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) {
61141a17fe3SRobert Watson 			if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) {
61241a17fe3SRobert Watson 				error = EEXIST;
61341a17fe3SRobert Watson 				goto out;
61441a17fe3SRobert Watson 			}
61541a17fe3SRobert Watson 		}
61641a17fe3SRobert Watson 	} else {
61795fab37eSRobert Watson 		LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) {
61895fab37eSRobert Watson 			if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) {
61941a17fe3SRobert Watson 				error = EEXIST;
62041a17fe3SRobert Watson 				goto out;
62141a17fe3SRobert Watson 			}
62295fab37eSRobert Watson 		}
62395fab37eSRobert Watson 	}
62495fab37eSRobert Watson 	if (mpc->mpc_field_off != NULL) {
625b2aef571SRobert Watson 		slot = ffs(mac_slot_offsets_free);
62695fab37eSRobert Watson 		if (slot == 0) {
62741a17fe3SRobert Watson 			error = ENOMEM;
62841a17fe3SRobert Watson 			goto out;
62995fab37eSRobert Watson 		}
63095fab37eSRobert Watson 		slot--;
631b2aef571SRobert Watson 		mac_slot_offsets_free &= ~(1 << slot);
63295fab37eSRobert Watson 		*mpc->mpc_field_off = slot;
63395fab37eSRobert Watson 	}
63495fab37eSRobert Watson 	mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED;
63541a17fe3SRobert Watson 
63641a17fe3SRobert Watson 	/*
63741a17fe3SRobert Watson 	 * If we're loading a MAC module after the framework has
63841a17fe3SRobert Watson 	 * initialized, it has to go into the dynamic list.  If
63941a17fe3SRobert Watson 	 * we're loading it before we've finished initializing,
64041a17fe3SRobert Watson 	 * it can go into the static list with weaker locker
64141a17fe3SRobert Watson 	 * requirements.
64241a17fe3SRobert Watson 	 */
64341a17fe3SRobert Watson 	if (static_entry)
64441a17fe3SRobert Watson 		LIST_INSERT_HEAD(&mac_static_policy_list, mpc, mpc_list);
64541a17fe3SRobert Watson 	else
64695fab37eSRobert Watson 		LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list);
64795fab37eSRobert Watson 
64895fab37eSRobert Watson 	/* Per-policy initialization. */
64995fab37eSRobert Watson 	if (mpc->mpc_ops->mpo_init != NULL)
65095fab37eSRobert Watson 		(*(mpc->mpc_ops->mpo_init))(mpc);
651225bff6fSRobert Watson 	mac_policy_updateflags();
65295fab37eSRobert Watson 
65395fab37eSRobert Watson 	printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname,
65495fab37eSRobert Watson 	    mpc->mpc_name);
65595fab37eSRobert Watson 
65641a17fe3SRobert Watson out:
65741a17fe3SRobert Watson 	mac_policy_release_exclusive();
65841a17fe3SRobert Watson 	return (error);
65995fab37eSRobert Watson }
66095fab37eSRobert Watson 
66195fab37eSRobert Watson static int
66295fab37eSRobert Watson mac_policy_unregister(struct mac_policy_conf *mpc)
66395fab37eSRobert Watson {
66495fab37eSRobert Watson 
665ea599aa0SRobert Watson 	/*
666ea599aa0SRobert Watson 	 * If we fail the load, we may get a request to unload.  Check
667ea599aa0SRobert Watson 	 * to see if we did the run-time registration, and if not,
668ea599aa0SRobert Watson 	 * silently succeed.
669ea599aa0SRobert Watson 	 */
67041a17fe3SRobert Watson 	mac_policy_grab_exclusive();
671ea599aa0SRobert Watson 	if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) {
67241a17fe3SRobert Watson 		mac_policy_release_exclusive();
673ea599aa0SRobert Watson 		return (0);
674ea599aa0SRobert Watson 	}
67595fab37eSRobert Watson #if 0
67695fab37eSRobert Watson 	/*
67795fab37eSRobert Watson 	 * Don't allow unloading modules with private data.
67895fab37eSRobert Watson 	 */
679ea599aa0SRobert Watson 	if (mpc->mpc_field_off != NULL) {
680ea599aa0SRobert Watson 		MAC_POLICY_LIST_UNLOCK();
68195fab37eSRobert Watson 		return (EBUSY);
682ea599aa0SRobert Watson 	}
68395fab37eSRobert Watson #endif
684ea599aa0SRobert Watson 	/*
685ea599aa0SRobert Watson 	 * Only allow the unload to proceed if the module is unloadable
686ea599aa0SRobert Watson 	 * by its own definition.
687ea599aa0SRobert Watson 	 */
688ea599aa0SRobert Watson 	if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) {
68941a17fe3SRobert Watson 		mac_policy_release_exclusive();
69095fab37eSRobert Watson 		return (EBUSY);
691ea599aa0SRobert Watson 	}
69295fab37eSRobert Watson 	if (mpc->mpc_ops->mpo_destroy != NULL)
69395fab37eSRobert Watson 		(*(mpc->mpc_ops->mpo_destroy))(mpc);
69495fab37eSRobert Watson 
69595fab37eSRobert Watson 	LIST_REMOVE(mpc, mpc_list);
6969aeffb2bSRobert Watson 	mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED;
697225bff6fSRobert Watson 	mac_policy_updateflags();
69841a17fe3SRobert Watson 
69941a17fe3SRobert Watson 	mac_policy_release_exclusive();
700a96acd1aSRobert Watson 
70195fab37eSRobert Watson 	printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname,
70295fab37eSRobert Watson 	    mpc->mpc_name);
70395fab37eSRobert Watson 
70495fab37eSRobert Watson 	return (0);
70595fab37eSRobert Watson }
70695fab37eSRobert Watson 
70795fab37eSRobert Watson /*
70895fab37eSRobert Watson  * Define an error value precedence, and given two arguments, selects the
70995fab37eSRobert Watson  * value with the higher precedence.
71095fab37eSRobert Watson  */
7119e7bf51cSRobert Watson int
7129e7bf51cSRobert Watson mac_error_select(int error1, int error2)
71395fab37eSRobert Watson {
71495fab37eSRobert Watson 
71595fab37eSRobert Watson 	/* Certain decision-making errors take top priority. */
71695fab37eSRobert Watson 	if (error1 == EDEADLK || error2 == EDEADLK)
71795fab37eSRobert Watson 		return (EDEADLK);
71895fab37eSRobert Watson 
71995fab37eSRobert Watson 	/* Invalid arguments should be reported where possible. */
72095fab37eSRobert Watson 	if (error1 == EINVAL || error2 == EINVAL)
72195fab37eSRobert Watson 		return (EINVAL);
72295fab37eSRobert Watson 
72395fab37eSRobert Watson 	/* Precedence goes to "visibility", with both process and file. */
72495fab37eSRobert Watson 	if (error1 == ESRCH || error2 == ESRCH)
72595fab37eSRobert Watson 		return (ESRCH);
72695fab37eSRobert Watson 
72795fab37eSRobert Watson 	if (error1 == ENOENT || error2 == ENOENT)
72895fab37eSRobert Watson 		return (ENOENT);
72995fab37eSRobert Watson 
73095fab37eSRobert Watson 	/* Precedence goes to DAC/MAC protections. */
73195fab37eSRobert Watson 	if (error1 == EACCES || error2 == EACCES)
73295fab37eSRobert Watson 		return (EACCES);
73395fab37eSRobert Watson 
73495fab37eSRobert Watson 	/* Precedence goes to privilege. */
73595fab37eSRobert Watson 	if (error1 == EPERM || error2 == EPERM)
73695fab37eSRobert Watson 		return (EPERM);
73795fab37eSRobert Watson 
73895fab37eSRobert Watson 	/* Precedence goes to error over success; otherwise, arbitrary. */
73995fab37eSRobert Watson 	if (error1 != 0)
74095fab37eSRobert Watson 		return (error1);
74195fab37eSRobert Watson 	return (error2);
74295fab37eSRobert Watson }
74395fab37eSRobert Watson 
74410eeb10cSRobert Watson static struct label *
74510eeb10cSRobert Watson mbuf_to_label(struct mbuf *mbuf)
74610eeb10cSRobert Watson {
747225bff6fSRobert Watson 	struct m_tag *tag;
74810eeb10cSRobert Watson 	struct label *label;
74910eeb10cSRobert Watson 
750225bff6fSRobert Watson 	tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL);
751225bff6fSRobert Watson 	label = (struct label *)(tag+1);
75210eeb10cSRobert Watson 
75310eeb10cSRobert Watson 	return (label);
75410eeb10cSRobert Watson }
75510eeb10cSRobert Watson 
75608bcdc58SRobert Watson static void
75708bcdc58SRobert Watson mac_init_label(struct label *label)
75808bcdc58SRobert Watson {
75908bcdc58SRobert Watson 
76008bcdc58SRobert Watson 	bzero(label, sizeof(*label));
76108bcdc58SRobert Watson 	label->l_flags = MAC_FLAG_INITIALIZED;
76208bcdc58SRobert Watson }
76308bcdc58SRobert Watson 
76408bcdc58SRobert Watson static void
76508bcdc58SRobert Watson mac_destroy_label(struct label *label)
76608bcdc58SRobert Watson {
76708bcdc58SRobert Watson 
76808bcdc58SRobert Watson 	KASSERT(label->l_flags & MAC_FLAG_INITIALIZED,
76908bcdc58SRobert Watson 	    ("destroying uninitialized label"));
77008bcdc58SRobert Watson 
77108bcdc58SRobert Watson 	bzero(label, sizeof(*label));
77208bcdc58SRobert Watson 	/* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */
77308bcdc58SRobert Watson }
77408bcdc58SRobert Watson 
77508bcdc58SRobert Watson void
77687807196SRobert Watson mac_init_bpfdesc(struct bpf_d *bpf_d)
77708bcdc58SRobert Watson {
77808bcdc58SRobert Watson 
77987807196SRobert Watson 	mac_init_label(&bpf_d->bd_label);
78087807196SRobert Watson 	MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label);
7818d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_INC(&nmacbpfdescs);
78208bcdc58SRobert Watson }
78308bcdc58SRobert Watson 
784f7b951a8SRobert Watson static void
785f7b951a8SRobert Watson mac_init_cred_label(struct label *label)
78608bcdc58SRobert Watson {
78708bcdc58SRobert Watson 
788f7b951a8SRobert Watson 	mac_init_label(label);
789f7b951a8SRobert Watson 	MAC_PERFORM(init_cred_label, label);
7908d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_INC(&nmaccreds);
79108bcdc58SRobert Watson }
79208bcdc58SRobert Watson 
79308bcdc58SRobert Watson void
794f7b951a8SRobert Watson mac_init_cred(struct ucred *cred)
795f7b951a8SRobert Watson {
796f7b951a8SRobert Watson 
797f7b951a8SRobert Watson 	mac_init_cred_label(&cred->cr_label);
798f7b951a8SRobert Watson }
799f7b951a8SRobert Watson 
800f7b951a8SRobert Watson void
80187807196SRobert Watson mac_init_devfsdirent(struct devfs_dirent *de)
80208bcdc58SRobert Watson {
80308bcdc58SRobert Watson 
80487807196SRobert Watson 	mac_init_label(&de->de_label);
80587807196SRobert Watson 	MAC_PERFORM(init_devfsdirent_label, &de->de_label);
8068d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_INC(&nmacdevfsdirents);
80708bcdc58SRobert Watson }
80808bcdc58SRobert Watson 
809f7b951a8SRobert Watson static void
810f7b951a8SRobert Watson mac_init_ifnet_label(struct label *label)
811f7b951a8SRobert Watson {
812f7b951a8SRobert Watson 
813f7b951a8SRobert Watson 	mac_init_label(label);
814f7b951a8SRobert Watson 	MAC_PERFORM(init_ifnet_label, label);
8158d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_INC(&nmacifnets);
816f7b951a8SRobert Watson }
817f7b951a8SRobert Watson 
81808bcdc58SRobert Watson void
81908bcdc58SRobert Watson mac_init_ifnet(struct ifnet *ifp)
82008bcdc58SRobert Watson {
82108bcdc58SRobert Watson 
822f7b951a8SRobert Watson 	mac_init_ifnet_label(&ifp->if_label);
82308bcdc58SRobert Watson }
82408bcdc58SRobert Watson 
8255e7ce478SRobert Watson int
8265e7ce478SRobert Watson mac_init_ipq(struct ipq *ipq, int flag)
82708bcdc58SRobert Watson {
8285e7ce478SRobert Watson 	int error;
82908bcdc58SRobert Watson 
83008bcdc58SRobert Watson 	mac_init_label(&ipq->ipq_label);
8315e7ce478SRobert Watson 
8325e7ce478SRobert Watson 	MAC_CHECK(init_ipq_label, &ipq->ipq_label, flag);
8335e7ce478SRobert Watson 	if (error) {
8345e7ce478SRobert Watson 		MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label);
8355e7ce478SRobert Watson 		mac_destroy_label(&ipq->ipq_label);
8368d8d5ea8SRobert Watson 	} else {
8378d8d5ea8SRobert Watson 		MAC_DEBUG_COUNTER_INC(&nmacipqs);
8385e7ce478SRobert Watson 	}
8395e7ce478SRobert Watson 	return (error);
84008bcdc58SRobert Watson }
84108bcdc58SRobert Watson 
84287807196SRobert Watson int
843225bff6fSRobert Watson mac_init_mbuf_tag(struct m_tag *tag, int flag)
84408bcdc58SRobert Watson {
845225bff6fSRobert Watson 	struct label *label;
8466d1a6a9aSRobert Watson 	int error;
84756c15412SRobert Watson 
848225bff6fSRobert Watson 	label = (struct label *) (tag + 1);
849225bff6fSRobert Watson 	mac_init_label(label);
85008bcdc58SRobert Watson 
8516d1a6a9aSRobert Watson 	MAC_CHECK(init_mbuf_label, label, flag);
85256c15412SRobert Watson 	if (error) {
853225bff6fSRobert Watson 		MAC_PERFORM(destroy_mbuf_label, label);
854225bff6fSRobert Watson 		mac_destroy_label(label);
8558d8d5ea8SRobert Watson 	} else {
8568d8d5ea8SRobert Watson 		MAC_DEBUG_COUNTER_INC(&nmacmbufs);
85756c15412SRobert Watson 	}
85856c15412SRobert Watson 	return (error);
85908bcdc58SRobert Watson }
86008bcdc58SRobert Watson 
861225bff6fSRobert Watson int
862225bff6fSRobert Watson mac_init_mbuf(struct mbuf *m, int flag)
863225bff6fSRobert Watson {
864225bff6fSRobert Watson 	struct m_tag *tag;
865225bff6fSRobert Watson 	int error;
866225bff6fSRobert Watson 
867225bff6fSRobert Watson 	M_ASSERTPKTHDR(m);
868225bff6fSRobert Watson 
869225bff6fSRobert Watson #ifndef MAC_ALWAYS_LABEL_MBUF
870225bff6fSRobert Watson 	/*
87119c3e120SRobert Watson 	 * If conditionally allocating mbuf labels, don't allocate unless
87219c3e120SRobert Watson 	 * they are required.
873225bff6fSRobert Watson 	 */
87419c3e120SRobert Watson 	if (!mac_labelmbufs)
87519c3e120SRobert Watson 		return (0);
876225bff6fSRobert Watson #endif
877225bff6fSRobert Watson 	tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label),
878225bff6fSRobert Watson 	    flag);
879225bff6fSRobert Watson 	if (tag == NULL)
880225bff6fSRobert Watson 		return (ENOMEM);
881225bff6fSRobert Watson 	error = mac_init_mbuf_tag(tag, flag);
882225bff6fSRobert Watson 	if (error) {
883225bff6fSRobert Watson 		m_tag_free(tag);
884225bff6fSRobert Watson 		return (error);
885225bff6fSRobert Watson 	}
886225bff6fSRobert Watson 	m_tag_prepend(m, tag);
887225bff6fSRobert Watson 	return (0);
888225bff6fSRobert Watson }
889225bff6fSRobert Watson 
89008bcdc58SRobert Watson void
89187807196SRobert Watson mac_init_mount(struct mount *mp)
89208bcdc58SRobert Watson {
89308bcdc58SRobert Watson 
89487807196SRobert Watson 	mac_init_label(&mp->mnt_mntlabel);
89587807196SRobert Watson 	mac_init_label(&mp->mnt_fslabel);
89687807196SRobert Watson 	MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel);
89787807196SRobert Watson 	MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel);
8988d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_INC(&nmacmounts);
89908bcdc58SRobert Watson }
90008bcdc58SRobert Watson 
901f7b951a8SRobert Watson static void
902f7b951a8SRobert Watson mac_init_pipe_label(struct label *label)
903f7b951a8SRobert Watson {
904f7b951a8SRobert Watson 
905f7b951a8SRobert Watson 	mac_init_label(label);
906f7b951a8SRobert Watson 	MAC_PERFORM(init_pipe_label, label);
9078d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_INC(&nmacpipes);
908f7b951a8SRobert Watson }
909f7b951a8SRobert Watson 
91008bcdc58SRobert Watson void
91108bcdc58SRobert Watson mac_init_pipe(struct pipe *pipe)
91208bcdc58SRobert Watson {
91308bcdc58SRobert Watson 	struct label *label;
91408bcdc58SRobert Watson 
915a163d034SWarner Losh 	label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK);
91608bcdc58SRobert Watson 	pipe->pipe_label = label;
91708bcdc58SRobert Watson 	pipe->pipe_peer->pipe_label = label;
918f7b951a8SRobert Watson 	mac_init_pipe_label(label);
91908bcdc58SRobert Watson }
92008bcdc58SRobert Watson 
9212555374cSRobert Watson void
9222555374cSRobert Watson mac_init_proc(struct proc *p)
9232555374cSRobert Watson {
9242555374cSRobert Watson 
9252555374cSRobert Watson 	mac_init_label(&p->p_label);
9262555374cSRobert Watson 	MAC_PERFORM(init_proc_label, &p->p_label);
9278d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_INC(&nmacprocs);
9282555374cSRobert Watson }
9292555374cSRobert Watson 
93083985c26SRobert Watson static int
93183985c26SRobert Watson mac_init_socket_label(struct label *label, int flag)
93208bcdc58SRobert Watson {
93383985c26SRobert Watson 	int error;
93408bcdc58SRobert Watson 
93583985c26SRobert Watson 	mac_init_label(label);
93683985c26SRobert Watson 
93783985c26SRobert Watson 	MAC_CHECK(init_socket_label, label, flag);
93883985c26SRobert Watson 	if (error) {
93983985c26SRobert Watson 		MAC_PERFORM(destroy_socket_label, label);
94083985c26SRobert Watson 		mac_destroy_label(label);
9418d8d5ea8SRobert Watson 	} else {
9428d8d5ea8SRobert Watson 		MAC_DEBUG_COUNTER_INC(&nmacsockets);
94383985c26SRobert Watson 	}
94483985c26SRobert Watson 
94583985c26SRobert Watson 	return (error);
94683985c26SRobert Watson }
94783985c26SRobert Watson 
94883985c26SRobert Watson static int
94983985c26SRobert Watson mac_init_socket_peer_label(struct label *label, int flag)
95083985c26SRobert Watson {
95183985c26SRobert Watson 	int error;
95283985c26SRobert Watson 
95383985c26SRobert Watson 	mac_init_label(label);
95483985c26SRobert Watson 
95583985c26SRobert Watson 	MAC_CHECK(init_socket_peer_label, label, flag);
95683985c26SRobert Watson 	if (error) {
95783985c26SRobert Watson 		MAC_PERFORM(destroy_socket_label, label);
95883985c26SRobert Watson 		mac_destroy_label(label);
95983985c26SRobert Watson 	}
96083985c26SRobert Watson 
96183985c26SRobert Watson 	return (error);
96283985c26SRobert Watson }
96383985c26SRobert Watson 
96483985c26SRobert Watson int
96583985c26SRobert Watson mac_init_socket(struct socket *socket, int flag)
96683985c26SRobert Watson {
96783985c26SRobert Watson 	int error;
96883985c26SRobert Watson 
96983985c26SRobert Watson 	error = mac_init_socket_label(&socket->so_label, flag);
97083985c26SRobert Watson 	if (error)
97183985c26SRobert Watson 		return (error);
97283985c26SRobert Watson 
97383985c26SRobert Watson 	error = mac_init_socket_peer_label(&socket->so_peerlabel, flag);
97483985c26SRobert Watson 	if (error)
97583985c26SRobert Watson 		mac_destroy_socket_label(&socket->so_label);
97683985c26SRobert Watson 
97783985c26SRobert Watson 	return (error);
97887807196SRobert Watson }
97987807196SRobert Watson 
980763bbd2fSRobert Watson void
981f7b951a8SRobert Watson mac_init_vnode_label(struct label *label)
98287807196SRobert Watson {
98387807196SRobert Watson 
98487807196SRobert Watson 	mac_init_label(label);
985f7b951a8SRobert Watson 	MAC_PERFORM(init_vnode_label, label);
9868d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_INC(&nmacvnodes);
98708bcdc58SRobert Watson }
98808bcdc58SRobert Watson 
98908bcdc58SRobert Watson void
99087807196SRobert Watson mac_init_vnode(struct vnode *vp)
99108bcdc58SRobert Watson {
99208bcdc58SRobert Watson 
993f7b951a8SRobert Watson 	mac_init_vnode_label(&vp->v_label);
99408bcdc58SRobert Watson }
99508bcdc58SRobert Watson 
99608bcdc58SRobert Watson void
99708bcdc58SRobert Watson mac_destroy_bpfdesc(struct bpf_d *bpf_d)
99808bcdc58SRobert Watson {
99908bcdc58SRobert Watson 
100008bcdc58SRobert Watson 	MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label);
100108bcdc58SRobert Watson 	mac_destroy_label(&bpf_d->bd_label);
10028d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacbpfdescs);
100308bcdc58SRobert Watson }
100408bcdc58SRobert Watson 
1005f7b951a8SRobert Watson static void
1006f7b951a8SRobert Watson mac_destroy_cred_label(struct label *label)
100708bcdc58SRobert Watson {
100808bcdc58SRobert Watson 
1009f7b951a8SRobert Watson 	MAC_PERFORM(destroy_cred_label, label);
1010f7b951a8SRobert Watson 	mac_destroy_label(label);
10118d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmaccreds);
101287807196SRobert Watson }
101387807196SRobert Watson 
101487807196SRobert Watson void
1015f7b951a8SRobert Watson mac_destroy_cred(struct ucred *cred)
1016f7b951a8SRobert Watson {
1017f7b951a8SRobert Watson 
1018f7b951a8SRobert Watson 	mac_destroy_cred_label(&cred->cr_label);
1019f7b951a8SRobert Watson }
1020f7b951a8SRobert Watson 
1021f7b951a8SRobert Watson void
102287807196SRobert Watson mac_destroy_devfsdirent(struct devfs_dirent *de)
102387807196SRobert Watson {
102487807196SRobert Watson 
102587807196SRobert Watson 	MAC_PERFORM(destroy_devfsdirent_label, &de->de_label);
102687807196SRobert Watson 	mac_destroy_label(&de->de_label);
10278d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacdevfsdirents);
102887807196SRobert Watson }
102987807196SRobert Watson 
1030f7b951a8SRobert Watson static void
1031f7b951a8SRobert Watson mac_destroy_ifnet_label(struct label *label)
1032f7b951a8SRobert Watson {
1033f7b951a8SRobert Watson 
1034f7b951a8SRobert Watson 	MAC_PERFORM(destroy_ifnet_label, label);
1035f7b951a8SRobert Watson 	mac_destroy_label(label);
10368d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacifnets);
1037f7b951a8SRobert Watson }
1038f7b951a8SRobert Watson 
103987807196SRobert Watson void
104087807196SRobert Watson mac_destroy_ifnet(struct ifnet *ifp)
104187807196SRobert Watson {
104287807196SRobert Watson 
1043f7b951a8SRobert Watson 	mac_destroy_ifnet_label(&ifp->if_label);
104487807196SRobert Watson }
104587807196SRobert Watson 
104687807196SRobert Watson void
104787807196SRobert Watson mac_destroy_ipq(struct ipq *ipq)
104887807196SRobert Watson {
104987807196SRobert Watson 
105087807196SRobert Watson 	MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label);
105187807196SRobert Watson 	mac_destroy_label(&ipq->ipq_label);
10528d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacipqs);
105387807196SRobert Watson }
105487807196SRobert Watson 
105587807196SRobert Watson void
1056225bff6fSRobert Watson mac_destroy_mbuf_tag(struct m_tag *tag)
105787807196SRobert Watson {
1058225bff6fSRobert Watson 	struct label *label;
105987807196SRobert Watson 
1060225bff6fSRobert Watson 	label = (struct label *)(tag+1);
1061225bff6fSRobert Watson 
1062225bff6fSRobert Watson 	MAC_PERFORM(destroy_mbuf_label, label);
1063225bff6fSRobert Watson 	mac_destroy_label(label);
10648d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacmbufs);
106508bcdc58SRobert Watson }
106608bcdc58SRobert Watson 
106708bcdc58SRobert Watson void
106808bcdc58SRobert Watson mac_destroy_mount(struct mount *mp)
106908bcdc58SRobert Watson {
107008bcdc58SRobert Watson 
107108bcdc58SRobert Watson 	MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel);
107208bcdc58SRobert Watson 	MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel);
107308bcdc58SRobert Watson 	mac_destroy_label(&mp->mnt_fslabel);
107408bcdc58SRobert Watson 	mac_destroy_label(&mp->mnt_mntlabel);
10758d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacmounts);
107608bcdc58SRobert Watson }
107708bcdc58SRobert Watson 
1078f7b951a8SRobert Watson static void
1079f7b951a8SRobert Watson mac_destroy_pipe_label(struct label *label)
1080f7b951a8SRobert Watson {
1081f7b951a8SRobert Watson 
1082f7b951a8SRobert Watson 	MAC_PERFORM(destroy_pipe_label, label);
1083f7b951a8SRobert Watson 	mac_destroy_label(label);
10848d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacpipes);
1085f7b951a8SRobert Watson }
1086f7b951a8SRobert Watson 
108787807196SRobert Watson void
108887807196SRobert Watson mac_destroy_pipe(struct pipe *pipe)
108908bcdc58SRobert Watson {
109008bcdc58SRobert Watson 
1091f7b951a8SRobert Watson 	mac_destroy_pipe_label(pipe->pipe_label);
109287807196SRobert Watson 	free(pipe->pipe_label, M_MACPIPELABEL);
109387807196SRobert Watson }
109487807196SRobert Watson 
10952555374cSRobert Watson void
10962555374cSRobert Watson mac_destroy_proc(struct proc *p)
10972555374cSRobert Watson {
10982555374cSRobert Watson 
10992555374cSRobert Watson 	MAC_PERFORM(destroy_proc_label, &p->p_label);
11002555374cSRobert Watson 	mac_destroy_label(&p->p_label);
11018d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacprocs);
11022555374cSRobert Watson }
11032555374cSRobert Watson 
110483985c26SRobert Watson static void
110583985c26SRobert Watson mac_destroy_socket_label(struct label *label)
110683985c26SRobert Watson {
110783985c26SRobert Watson 
110883985c26SRobert Watson 	MAC_PERFORM(destroy_socket_label, label);
110983985c26SRobert Watson 	mac_destroy_label(label);
11108d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacsockets);
111183985c26SRobert Watson }
111283985c26SRobert Watson 
111383985c26SRobert Watson static void
111483985c26SRobert Watson mac_destroy_socket_peer_label(struct label *label)
111583985c26SRobert Watson {
111683985c26SRobert Watson 
111783985c26SRobert Watson 	MAC_PERFORM(destroy_socket_peer_label, label);
111883985c26SRobert Watson 	mac_destroy_label(label);
111983985c26SRobert Watson }
112083985c26SRobert Watson 
112187807196SRobert Watson void
112287807196SRobert Watson mac_destroy_socket(struct socket *socket)
112387807196SRobert Watson {
112487807196SRobert Watson 
112583985c26SRobert Watson 	mac_destroy_socket_label(&socket->so_label);
112683985c26SRobert Watson 	mac_destroy_socket_peer_label(&socket->so_peerlabel);
112708bcdc58SRobert Watson }
112808bcdc58SRobert Watson 
1129763bbd2fSRobert Watson void
1130f7b951a8SRobert Watson mac_destroy_vnode_label(struct label *label)
113108bcdc58SRobert Watson {
113208bcdc58SRobert Watson 
1133f7b951a8SRobert Watson 	MAC_PERFORM(destroy_vnode_label, label);
113408bcdc58SRobert Watson 	mac_destroy_label(label);
11358d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacvnodes);
113608bcdc58SRobert Watson }
113708bcdc58SRobert Watson 
113808bcdc58SRobert Watson void
113908bcdc58SRobert Watson mac_destroy_vnode(struct vnode *vp)
114008bcdc58SRobert Watson {
114108bcdc58SRobert Watson 
1142f7b951a8SRobert Watson 	mac_destroy_vnode_label(&vp->v_label);
1143f7b951a8SRobert Watson }
1144f7b951a8SRobert Watson 
1145225bff6fSRobert Watson void
1146225bff6fSRobert Watson mac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest)
1147225bff6fSRobert Watson {
1148225bff6fSRobert Watson 	struct label *src_label, *dest_label;
1149225bff6fSRobert Watson 
1150225bff6fSRobert Watson 	src_label = (struct label *)(src+1);
1151225bff6fSRobert Watson 	dest_label = (struct label *)(dest+1);
1152225bff6fSRobert Watson 
1153225bff6fSRobert Watson 	/*
1154225bff6fSRobert Watson 	 * mac_init_mbuf_tag() is called on the target tag in
1155225bff6fSRobert Watson 	 * m_tag_copy(), so we don't need to call it here.
1156225bff6fSRobert Watson 	 */
1157225bff6fSRobert Watson 	MAC_PERFORM(copy_mbuf_label, src_label, dest_label);
1158225bff6fSRobert Watson }
1159225bff6fSRobert Watson 
1160f7b951a8SRobert Watson static void
1161f7b951a8SRobert Watson mac_copy_pipe_label(struct label *src, struct label *dest)
1162f7b951a8SRobert Watson {
1163f7b951a8SRobert Watson 
1164f7b951a8SRobert Watson 	MAC_PERFORM(copy_pipe_label, src, dest);
1165f7b951a8SRobert Watson }
1166f7b951a8SRobert Watson 
1167763bbd2fSRobert Watson void
1168f7b951a8SRobert Watson mac_copy_vnode_label(struct label *src, struct label *dest)
1169f7b951a8SRobert Watson {
1170f7b951a8SRobert Watson 
1171f7b951a8SRobert Watson 	MAC_PERFORM(copy_vnode_label, src, dest);
117208bcdc58SRobert Watson }
117308bcdc58SRobert Watson 
117469bbb5b1SRobert Watson static int
1175f7b951a8SRobert Watson mac_check_structmac_consistent(struct mac *mac)
1176f7b951a8SRobert Watson {
1177f7b951a8SRobert Watson 
1178cc7b13bfSRobert Watson 	if (mac->m_buflen < 0 ||
1179cc7b13bfSRobert Watson 	    mac->m_buflen > MAC_MAX_LABEL_BUF_LEN)
1180f7b951a8SRobert Watson 		return (EINVAL);
1181f7b951a8SRobert Watson 
1182f7b951a8SRobert Watson 	return (0);
1183f7b951a8SRobert Watson }
1184f7b951a8SRobert Watson 
1185f7b951a8SRobert Watson static int
1186f7b951a8SRobert Watson mac_externalize_cred_label(struct label *label, char *elements,
1187f7b951a8SRobert Watson     char *outbuf, size_t outbuflen, int flags)
118869bbb5b1SRobert Watson {
118969bbb5b1SRobert Watson 	int error;
119069bbb5b1SRobert Watson 
1191f7b951a8SRobert Watson 	MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen);
119269bbb5b1SRobert Watson 
119369bbb5b1SRobert Watson 	return (error);
119469bbb5b1SRobert Watson }
119569bbb5b1SRobert Watson 
119669bbb5b1SRobert Watson static int
1197f7b951a8SRobert Watson mac_externalize_ifnet_label(struct label *label, char *elements,
1198f7b951a8SRobert Watson     char *outbuf, size_t outbuflen, int flags)
119969bbb5b1SRobert Watson {
120069bbb5b1SRobert Watson 	int error;
120169bbb5b1SRobert Watson 
1202f7b951a8SRobert Watson 	MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen);
1203f7b951a8SRobert Watson 
1204f7b951a8SRobert Watson 	return (error);
1205f7b951a8SRobert Watson }
1206f7b951a8SRobert Watson 
1207f7b951a8SRobert Watson static int
1208f7b951a8SRobert Watson mac_externalize_pipe_label(struct label *label, char *elements,
1209f7b951a8SRobert Watson     char *outbuf, size_t outbuflen, int flags)
1210f7b951a8SRobert Watson {
1211f7b951a8SRobert Watson 	int error;
1212f7b951a8SRobert Watson 
1213f7b951a8SRobert Watson 	MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen);
1214f7b951a8SRobert Watson 
1215f7b951a8SRobert Watson 	return (error);
1216f7b951a8SRobert Watson }
1217f7b951a8SRobert Watson 
1218f7b951a8SRobert Watson static int
1219f7b951a8SRobert Watson mac_externalize_socket_label(struct label *label, char *elements,
1220f7b951a8SRobert Watson     char *outbuf, size_t outbuflen, int flags)
1221f7b951a8SRobert Watson {
1222f7b951a8SRobert Watson 	int error;
1223f7b951a8SRobert Watson 
1224f7b951a8SRobert Watson 	MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen);
1225f7b951a8SRobert Watson 
1226f7b951a8SRobert Watson 	return (error);
1227f7b951a8SRobert Watson }
1228f7b951a8SRobert Watson 
1229f7b951a8SRobert Watson static int
1230f7b951a8SRobert Watson mac_externalize_socket_peer_label(struct label *label, char *elements,
1231f7b951a8SRobert Watson     char *outbuf, size_t outbuflen, int flags)
1232f7b951a8SRobert Watson {
1233f7b951a8SRobert Watson 	int error;
1234f7b951a8SRobert Watson 
1235f7b951a8SRobert Watson 	MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen);
1236f7b951a8SRobert Watson 
1237f7b951a8SRobert Watson 	return (error);
1238f7b951a8SRobert Watson }
1239f7b951a8SRobert Watson 
1240f7b951a8SRobert Watson static int
1241f7b951a8SRobert Watson mac_externalize_vnode_label(struct label *label, char *elements,
1242f7b951a8SRobert Watson     char *outbuf, size_t outbuflen, int flags)
1243f7b951a8SRobert Watson {
1244f7b951a8SRobert Watson 	int error;
1245f7b951a8SRobert Watson 
1246f7b951a8SRobert Watson 	MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen);
1247f7b951a8SRobert Watson 
1248f7b951a8SRobert Watson 	return (error);
1249f7b951a8SRobert Watson }
1250f7b951a8SRobert Watson 
1251f7b951a8SRobert Watson static int
1252f7b951a8SRobert Watson mac_internalize_cred_label(struct label *label, char *string)
1253f7b951a8SRobert Watson {
1254f7b951a8SRobert Watson 	int error;
1255f7b951a8SRobert Watson 
1256f7b951a8SRobert Watson 	MAC_INTERNALIZE(cred_label, label, string);
1257f7b951a8SRobert Watson 
1258f7b951a8SRobert Watson 	return (error);
1259f7b951a8SRobert Watson }
1260f7b951a8SRobert Watson 
1261f7b951a8SRobert Watson static int
1262f7b951a8SRobert Watson mac_internalize_ifnet_label(struct label *label, char *string)
1263f7b951a8SRobert Watson {
1264f7b951a8SRobert Watson 	int error;
1265f7b951a8SRobert Watson 
1266f7b951a8SRobert Watson 	MAC_INTERNALIZE(ifnet_label, label, string);
1267f7b951a8SRobert Watson 
1268f7b951a8SRobert Watson 	return (error);
1269f7b951a8SRobert Watson }
1270f7b951a8SRobert Watson 
1271f7b951a8SRobert Watson static int
1272f7b951a8SRobert Watson mac_internalize_pipe_label(struct label *label, char *string)
1273f7b951a8SRobert Watson {
1274f7b951a8SRobert Watson 	int error;
1275f7b951a8SRobert Watson 
1276f7b951a8SRobert Watson 	MAC_INTERNALIZE(pipe_label, label, string);
1277f7b951a8SRobert Watson 
1278f7b951a8SRobert Watson 	return (error);
1279f7b951a8SRobert Watson }
1280f7b951a8SRobert Watson 
1281f7b951a8SRobert Watson static int
1282f7b951a8SRobert Watson mac_internalize_socket_label(struct label *label, char *string)
1283f7b951a8SRobert Watson {
1284f7b951a8SRobert Watson 	int error;
1285f7b951a8SRobert Watson 
1286f7b951a8SRobert Watson 	MAC_INTERNALIZE(socket_label, label, string);
1287f7b951a8SRobert Watson 
1288f7b951a8SRobert Watson 	return (error);
1289f7b951a8SRobert Watson }
1290f7b951a8SRobert Watson 
1291f7b951a8SRobert Watson static int
1292f7b951a8SRobert Watson mac_internalize_vnode_label(struct label *label, char *string)
1293f7b951a8SRobert Watson {
1294f7b951a8SRobert Watson 	int error;
1295f7b951a8SRobert Watson 
1296f7b951a8SRobert Watson 	MAC_INTERNALIZE(vnode_label, label, string);
129769bbb5b1SRobert Watson 
129869bbb5b1SRobert Watson 	return (error);
129969bbb5b1SRobert Watson }
130069bbb5b1SRobert Watson 
130169bbb5b1SRobert Watson /*
130269bbb5b1SRobert Watson  * Initialize MAC label for the first kernel process, from which other
130369bbb5b1SRobert Watson  * kernel processes and threads are spawned.
130469bbb5b1SRobert Watson  */
130569bbb5b1SRobert Watson void
130669bbb5b1SRobert Watson mac_create_proc0(struct ucred *cred)
130769bbb5b1SRobert Watson {
130869bbb5b1SRobert Watson 
130969bbb5b1SRobert Watson 	MAC_PERFORM(create_proc0, cred);
131069bbb5b1SRobert Watson }
131169bbb5b1SRobert Watson 
131269bbb5b1SRobert Watson /*
131369bbb5b1SRobert Watson  * Initialize MAC label for the first userland process, from which other
131469bbb5b1SRobert Watson  * userland processes and threads are spawned.
131569bbb5b1SRobert Watson  */
131669bbb5b1SRobert Watson void
131769bbb5b1SRobert Watson mac_create_proc1(struct ucred *cred)
131869bbb5b1SRobert Watson {
131969bbb5b1SRobert Watson 
132069bbb5b1SRobert Watson 	MAC_PERFORM(create_proc1, cred);
132169bbb5b1SRobert Watson }
132269bbb5b1SRobert Watson 
132369bbb5b1SRobert Watson void
132469bbb5b1SRobert Watson mac_thread_userret(struct thread *td)
132569bbb5b1SRobert Watson {
132669bbb5b1SRobert Watson 
132769bbb5b1SRobert Watson 	MAC_PERFORM(thread_userret, td);
132869bbb5b1SRobert Watson }
132969bbb5b1SRobert Watson 
133069bbb5b1SRobert Watson /*
133169bbb5b1SRobert Watson  * When a new process is created, its label must be initialized.  Generally,
133269bbb5b1SRobert Watson  * this involves inheritence from the parent process, modulo possible
133369bbb5b1SRobert Watson  * deltas.  This function allows that processing to take place.
133469bbb5b1SRobert Watson  */
133569bbb5b1SRobert Watson void
133669bbb5b1SRobert Watson mac_create_cred(struct ucred *parent_cred, struct ucred *child_cred)
133769bbb5b1SRobert Watson {
133869bbb5b1SRobert Watson 
133969bbb5b1SRobert Watson 	MAC_PERFORM(create_cred, parent_cred, child_cred);
134069bbb5b1SRobert Watson }
134169bbb5b1SRobert Watson 
134295fab37eSRobert Watson void
1343990b4b2dSRobert Watson mac_update_devfsdirent(struct mount *mp, struct devfs_dirent *de,
1344990b4b2dSRobert Watson     struct vnode *vp)
134595fab37eSRobert Watson {
134695fab37eSRobert Watson 
1347990b4b2dSRobert Watson 	MAC_PERFORM(update_devfsdirent, mp, de, &de->de_label, vp,
1348990b4b2dSRobert Watson 	    &vp->v_label);
134995fab37eSRobert Watson }
135095fab37eSRobert Watson 
135195fab37eSRobert Watson void
1352763bbd2fSRobert Watson mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de,
1353763bbd2fSRobert Watson     struct vnode *vp)
135495fab37eSRobert Watson {
135595fab37eSRobert Watson 
1356763bbd2fSRobert Watson 	MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de,
1357763bbd2fSRobert Watson 	    &de->de_label, vp, &vp->v_label);
135895fab37eSRobert Watson }
135995fab37eSRobert Watson 
1360763bbd2fSRobert Watson int
1361763bbd2fSRobert Watson mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp)
136295fab37eSRobert Watson {
136395fab37eSRobert Watson 	int error;
136495fab37eSRobert Watson 
1365763bbd2fSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr");
1366763bbd2fSRobert Watson 
1367763bbd2fSRobert Watson 	MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp,
1368763bbd2fSRobert Watson 	    &vp->v_label);
136995fab37eSRobert Watson 
137095fab37eSRobert Watson 	return (error);
137195fab37eSRobert Watson }
137295fab37eSRobert Watson 
137395fab37eSRobert Watson void
1374763bbd2fSRobert Watson mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp)
137595fab37eSRobert Watson {
137695fab37eSRobert Watson 
1377763bbd2fSRobert Watson 	MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp,
1378763bbd2fSRobert Watson 	    &vp->v_label);
137995fab37eSRobert Watson }
138095fab37eSRobert Watson 
138195fab37eSRobert Watson int
1382763bbd2fSRobert Watson mac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
1383763bbd2fSRobert Watson     struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
138495fab37eSRobert Watson {
1385763bbd2fSRobert Watson 	int error;
138695fab37eSRobert Watson 
1387763bbd2fSRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr");
1388763bbd2fSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr");
138995fab37eSRobert Watson 
1390763bbd2fSRobert Watson 	error = VOP_OPENEXTATTR(vp, cred, curthread);
1391763bbd2fSRobert Watson 	if (error == EOPNOTSUPP) {
1392763bbd2fSRobert Watson 		/* XXX: Optionally abort if transactions not supported. */
1393763bbd2fSRobert Watson 		if (ea_warn_once == 0) {
1394763bbd2fSRobert Watson 			printf("Warning: transactions not supported "
1395763bbd2fSRobert Watson 			    "in EA write.\n");
1396763bbd2fSRobert Watson 			ea_warn_once = 1;
1397763bbd2fSRobert Watson 		}
1398763bbd2fSRobert Watson 	} else if (error)
139995fab37eSRobert Watson 		return (error);
140095fab37eSRobert Watson 
1401763bbd2fSRobert Watson 	MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel,
1402763bbd2fSRobert Watson 	    dvp, &dvp->v_label, vp, &vp->v_label, cnp);
140395fab37eSRobert Watson 
1404763bbd2fSRobert Watson 	if (error) {
1405763bbd2fSRobert Watson 		VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
140695fab37eSRobert Watson 		return (error);
140795fab37eSRobert Watson 	}
140895fab37eSRobert Watson 
1409763bbd2fSRobert Watson 	error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
141095fab37eSRobert Watson 
1411763bbd2fSRobert Watson 	if (error == EOPNOTSUPP)
1412763bbd2fSRobert Watson 		error = 0;				/* XXX */
141395fab37eSRobert Watson 
141495fab37eSRobert Watson 	return (error);
141595fab37eSRobert Watson }
141695fab37eSRobert Watson 
141795fab37eSRobert Watson static int
1418763bbd2fSRobert Watson mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
1419763bbd2fSRobert Watson     struct label *intlabel)
142095fab37eSRobert Watson {
142195fab37eSRobert Watson 	int error;
142295fab37eSRobert Watson 
1423763bbd2fSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr");
142495fab37eSRobert Watson 
1425763bbd2fSRobert Watson 	error = VOP_OPENEXTATTR(vp, cred, curthread);
1426763bbd2fSRobert Watson 	if (error == EOPNOTSUPP) {
1427763bbd2fSRobert Watson 		/* XXX: Optionally abort if transactions not supported. */
1428763bbd2fSRobert Watson 		if (ea_warn_once == 0) {
1429763bbd2fSRobert Watson 			printf("Warning: transactions not supported "
1430763bbd2fSRobert Watson 			    "in EA write.\n");
1431763bbd2fSRobert Watson 			ea_warn_once = 1;
143295fab37eSRobert Watson 		}
1433763bbd2fSRobert Watson 	} else if (error)
143495fab37eSRobert Watson 		return (error);
143595fab37eSRobert Watson 
1436763bbd2fSRobert Watson 	MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel);
143795fab37eSRobert Watson 
1438763bbd2fSRobert Watson 	if (error) {
1439763bbd2fSRobert Watson 		VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
144095fab37eSRobert Watson 		return (error);
144195fab37eSRobert Watson 	}
144295fab37eSRobert Watson 
1443763bbd2fSRobert Watson 	error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
1444763bbd2fSRobert Watson 
1445763bbd2fSRobert Watson 	if (error == EOPNOTSUPP)
1446763bbd2fSRobert Watson 		error = 0;				/* XXX */
1447763bbd2fSRobert Watson 
1448763bbd2fSRobert Watson 	return (error);
144995fab37eSRobert Watson }
145095fab37eSRobert Watson 
1451670cb89bSRobert Watson int
1452670cb89bSRobert Watson mac_execve_enter(struct image_params *imgp, struct mac *mac_p,
1453670cb89bSRobert Watson     struct label *execlabelstorage)
1454670cb89bSRobert Watson {
1455670cb89bSRobert Watson 	struct mac mac;
1456670cb89bSRobert Watson 	char *buffer;
1457670cb89bSRobert Watson 	int error;
1458670cb89bSRobert Watson 
1459670cb89bSRobert Watson 	if (mac_p == NULL)
1460670cb89bSRobert Watson 		return (0);
1461670cb89bSRobert Watson 
1462670cb89bSRobert Watson 	error = copyin(mac_p, &mac, sizeof(mac));
1463670cb89bSRobert Watson 	if (error)
1464670cb89bSRobert Watson 		return (error);
1465670cb89bSRobert Watson 
1466670cb89bSRobert Watson 	error = mac_check_structmac_consistent(&mac);
1467670cb89bSRobert Watson 	if (error)
1468670cb89bSRobert Watson 		return (error);
1469670cb89bSRobert Watson 
1470a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
1471670cb89bSRobert Watson 	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
1472670cb89bSRobert Watson 	if (error) {
1473670cb89bSRobert Watson 		free(buffer, M_MACTEMP);
1474670cb89bSRobert Watson 		return (error);
1475670cb89bSRobert Watson 	}
1476670cb89bSRobert Watson 
1477670cb89bSRobert Watson 	mac_init_cred_label(execlabelstorage);
1478670cb89bSRobert Watson 	error = mac_internalize_cred_label(execlabelstorage, buffer);
1479670cb89bSRobert Watson 	free(buffer, M_MACTEMP);
1480670cb89bSRobert Watson 	if (error) {
1481670cb89bSRobert Watson 		mac_destroy_cred_label(execlabelstorage);
1482670cb89bSRobert Watson 		return (error);
1483670cb89bSRobert Watson 	}
1484670cb89bSRobert Watson 	imgp->execlabel = execlabelstorage;
1485670cb89bSRobert Watson 	return (0);
1486670cb89bSRobert Watson }
1487670cb89bSRobert Watson 
148895fab37eSRobert Watson void
1489670cb89bSRobert Watson mac_execve_exit(struct image_params *imgp)
1490670cb89bSRobert Watson {
1491670cb89bSRobert Watson 	if (imgp->execlabel != NULL)
1492670cb89bSRobert Watson 		mac_destroy_cred_label(imgp->execlabel);
1493670cb89bSRobert Watson }
1494670cb89bSRobert Watson 
1495670cb89bSRobert Watson void
1496670cb89bSRobert Watson mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp,
1497670cb89bSRobert Watson     struct label *interpvnodelabel, struct image_params *imgp)
149895fab37eSRobert Watson {
149995fab37eSRobert Watson 
150095fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_execve_transition");
150195fab37eSRobert Watson 
15024443e9ffSRobert Watson 	if (!mac_enforce_process && !mac_enforce_fs)
15034443e9ffSRobert Watson 		return;
15044443e9ffSRobert Watson 
1505670cb89bSRobert Watson 	MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label,
15069fa3506eSRobert Watson 	    interpvnodelabel, imgp, imgp->execlabel);
150795fab37eSRobert Watson }
150895fab37eSRobert Watson 
150995fab37eSRobert Watson int
1510670cb89bSRobert Watson mac_execve_will_transition(struct ucred *old, struct vnode *vp,
1511670cb89bSRobert Watson     struct label *interpvnodelabel, struct image_params *imgp)
151295fab37eSRobert Watson {
1513763bbd2fSRobert Watson 	int result;
151495fab37eSRobert Watson 
15154443e9ffSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_execve_will_transition");
15164443e9ffSRobert Watson 
15174443e9ffSRobert Watson 	if (!mac_enforce_process && !mac_enforce_fs)
15184443e9ffSRobert Watson 		return (0);
15194443e9ffSRobert Watson 
152095fab37eSRobert Watson 	result = 0;
1521670cb89bSRobert Watson 	MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label,
15229fa3506eSRobert Watson 	    interpvnodelabel, imgp, imgp->execlabel);
152395fab37eSRobert Watson 
152495fab37eSRobert Watson 	return (result);
152595fab37eSRobert Watson }
152695fab37eSRobert Watson 
152795fab37eSRobert Watson int
1528b914de36SRobert Watson mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode)
152995fab37eSRobert Watson {
153095fab37eSRobert Watson 	int error;
153195fab37eSRobert Watson 
153295fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access");
153395fab37eSRobert Watson 
153495fab37eSRobert Watson 	if (!mac_enforce_fs)
153595fab37eSRobert Watson 		return (0);
153695fab37eSRobert Watson 
1537b914de36SRobert Watson 	MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, acc_mode);
153895fab37eSRobert Watson 	return (error);
153995fab37eSRobert Watson }
154095fab37eSRobert Watson 
154195fab37eSRobert Watson int
154295fab37eSRobert Watson mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp)
154395fab37eSRobert Watson {
154495fab37eSRobert Watson 	int error;
154595fab37eSRobert Watson 
154695fab37eSRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir");
154795fab37eSRobert Watson 
154895fab37eSRobert Watson 	if (!mac_enforce_fs)
154995fab37eSRobert Watson 		return (0);
155095fab37eSRobert Watson 
155195fab37eSRobert Watson 	MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label);
155295fab37eSRobert Watson 	return (error);
155395fab37eSRobert Watson }
155495fab37eSRobert Watson 
155595fab37eSRobert Watson int
155695fab37eSRobert Watson mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp)
155795fab37eSRobert Watson {
155895fab37eSRobert Watson 	int error;
155995fab37eSRobert Watson 
156095fab37eSRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot");
156195fab37eSRobert Watson 
156295fab37eSRobert Watson 	if (!mac_enforce_fs)
156395fab37eSRobert Watson 		return (0);
156495fab37eSRobert Watson 
156595fab37eSRobert Watson 	MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label);
156695fab37eSRobert Watson 	return (error);
156795fab37eSRobert Watson }
156895fab37eSRobert Watson 
156995fab37eSRobert Watson int
157095fab37eSRobert Watson mac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
157195fab37eSRobert Watson     struct componentname *cnp, struct vattr *vap)
157295fab37eSRobert Watson {
157395fab37eSRobert Watson 	int error;
157495fab37eSRobert Watson 
157595fab37eSRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create");
157695fab37eSRobert Watson 
157795fab37eSRobert Watson 	if (!mac_enforce_fs)
157895fab37eSRobert Watson 		return (0);
157995fab37eSRobert Watson 
158095fab37eSRobert Watson 	MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap);
158195fab37eSRobert Watson 	return (error);
158295fab37eSRobert Watson }
158395fab37eSRobert Watson 
158495fab37eSRobert Watson int
158595fab37eSRobert Watson mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp,
158695fab37eSRobert Watson     struct componentname *cnp)
158795fab37eSRobert Watson {
158895fab37eSRobert Watson 	int error;
158995fab37eSRobert Watson 
159095fab37eSRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete");
159195fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete");
159295fab37eSRobert Watson 
159395fab37eSRobert Watson 	if (!mac_enforce_fs)
159495fab37eSRobert Watson 		return (0);
159595fab37eSRobert Watson 
159695fab37eSRobert Watson 	MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp,
159795fab37eSRobert Watson 	    &vp->v_label, cnp);
159895fab37eSRobert Watson 	return (error);
159995fab37eSRobert Watson }
160095fab37eSRobert Watson 
160195fab37eSRobert Watson int
160295fab37eSRobert Watson mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
160395fab37eSRobert Watson     acl_type_t type)
160495fab37eSRobert Watson {
160595fab37eSRobert Watson 	int error;
160695fab37eSRobert Watson 
160795fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl");
160895fab37eSRobert Watson 
160995fab37eSRobert Watson 	if (!mac_enforce_fs)
161095fab37eSRobert Watson 		return (0);
161195fab37eSRobert Watson 
161295fab37eSRobert Watson 	MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type);
161395fab37eSRobert Watson 	return (error);
161495fab37eSRobert Watson }
161595fab37eSRobert Watson 
161695fab37eSRobert Watson int
1617c096756cSRobert Watson mac_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
1618c096756cSRobert Watson     int attrnamespace, const char *name)
1619c096756cSRobert Watson {
1620c096756cSRobert Watson 	int error;
1621c096756cSRobert Watson 
1622c096756cSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteextattr");
1623c096756cSRobert Watson 
1624c096756cSRobert Watson 	if (!mac_enforce_fs)
1625c096756cSRobert Watson 		return (0);
1626c096756cSRobert Watson 
1627c096756cSRobert Watson 	MAC_CHECK(check_vnode_deleteextattr, cred, vp, &vp->v_label,
1628c096756cSRobert Watson 	    attrnamespace, name);
1629c096756cSRobert Watson 	return (error);
1630c096756cSRobert Watson }
1631c096756cSRobert Watson 
1632c096756cSRobert Watson int
1633670cb89bSRobert Watson mac_check_vnode_exec(struct ucred *cred, struct vnode *vp,
1634670cb89bSRobert Watson     struct image_params *imgp)
163595fab37eSRobert Watson {
163695fab37eSRobert Watson 	int error;
163795fab37eSRobert Watson 
1638851704bbSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec");
1639851704bbSRobert Watson 
164095fab37eSRobert Watson 	if (!mac_enforce_process && !mac_enforce_fs)
164195fab37eSRobert Watson 		return (0);
164295fab37eSRobert Watson 
16439fa3506eSRobert Watson 	MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label, imgp,
16449fa3506eSRobert Watson 	    imgp->execlabel);
164595fab37eSRobert Watson 
164695fab37eSRobert Watson 	return (error);
164795fab37eSRobert Watson }
164895fab37eSRobert Watson 
164995fab37eSRobert Watson int
165095fab37eSRobert Watson mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
165195fab37eSRobert Watson {
165295fab37eSRobert Watson 	int error;
165395fab37eSRobert Watson 
165495fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl");
165595fab37eSRobert Watson 
165695fab37eSRobert Watson 	if (!mac_enforce_fs)
165795fab37eSRobert Watson 		return (0);
165895fab37eSRobert Watson 
165995fab37eSRobert Watson 	MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type);
166095fab37eSRobert Watson 	return (error);
166195fab37eSRobert Watson }
166295fab37eSRobert Watson 
166395fab37eSRobert Watson int
166495fab37eSRobert Watson mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
166595fab37eSRobert Watson     int attrnamespace, const char *name, struct uio *uio)
166695fab37eSRobert Watson {
166795fab37eSRobert Watson 	int error;
166895fab37eSRobert Watson 
166995fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr");
167095fab37eSRobert Watson 
167195fab37eSRobert Watson 	if (!mac_enforce_fs)
167295fab37eSRobert Watson 		return (0);
167395fab37eSRobert Watson 
167495fab37eSRobert Watson 	MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label,
167595fab37eSRobert Watson 	    attrnamespace, name, uio);
167695fab37eSRobert Watson 	return (error);
167795fab37eSRobert Watson }
167895fab37eSRobert Watson 
167995fab37eSRobert Watson int
16800a694196SRobert Watson mac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
16810a694196SRobert Watson     struct vnode *vp, struct componentname *cnp)
16820a694196SRobert Watson {
16830a694196SRobert Watson 	int error;
16840a694196SRobert Watson 
16850a694196SRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link");
16860a694196SRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link");
16870a694196SRobert Watson 
16880a694196SRobert Watson 	if (!mac_enforce_fs)
16890a694196SRobert Watson 		return (0);
16900a694196SRobert Watson 
16910a694196SRobert Watson 	MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp,
16920a694196SRobert Watson 	    &vp->v_label, cnp);
16930a694196SRobert Watson 	return (error);
16940a694196SRobert Watson }
16950a694196SRobert Watson 
16960a694196SRobert Watson int
1697c096756cSRobert Watson mac_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
1698c096756cSRobert Watson     int attrnamespace)
1699c096756cSRobert Watson {
1700c096756cSRobert Watson 	int error;
1701c096756cSRobert Watson 
1702c096756cSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_listextattr");
1703c096756cSRobert Watson 
1704c096756cSRobert Watson 	if (!mac_enforce_fs)
1705c096756cSRobert Watson 		return (0);
1706c096756cSRobert Watson 
1707c096756cSRobert Watson 	MAC_CHECK(check_vnode_listextattr, cred, vp, &vp->v_label,
1708c096756cSRobert Watson 	    attrnamespace);
1709c096756cSRobert Watson 	return (error);
1710c096756cSRobert Watson }
1711c096756cSRobert Watson 
1712c096756cSRobert Watson int
171395fab37eSRobert Watson mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
171495fab37eSRobert Watson     struct componentname *cnp)
171595fab37eSRobert Watson {
171695fab37eSRobert Watson 	int error;
171795fab37eSRobert Watson 
171895fab37eSRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup");
171995fab37eSRobert Watson 
172095fab37eSRobert Watson 	if (!mac_enforce_fs)
172195fab37eSRobert Watson 		return (0);
172295fab37eSRobert Watson 
172395fab37eSRobert Watson 	MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp);
172495fab37eSRobert Watson 	return (error);
172595fab37eSRobert Watson }
172695fab37eSRobert Watson 
1727e183f80eSRobert Watson int
1728e183f80eSRobert Watson mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot)
172995fab37eSRobert Watson {
1730e183f80eSRobert Watson 	int error;
173195fab37eSRobert Watson 
1732e183f80eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap");
1733ca7850c3SRobert Watson 
1734e183f80eSRobert Watson 	if (!mac_enforce_fs || !mac_enforce_vm)
1735e183f80eSRobert Watson 		return (0);
1736e183f80eSRobert Watson 
1737e183f80eSRobert Watson 	MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot);
1738e183f80eSRobert Watson 	return (error);
1739e183f80eSRobert Watson }
1740e183f80eSRobert Watson 
1741e183f80eSRobert Watson void
1742e183f80eSRobert Watson mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot)
1743e183f80eSRobert Watson {
1744e183f80eSRobert Watson 	int result = *prot;
1745e183f80eSRobert Watson 
1746e183f80eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade");
1747e183f80eSRobert Watson 
1748e183f80eSRobert Watson 	if (!mac_enforce_fs || !mac_enforce_vm)
1749e183f80eSRobert Watson 		return;
1750e183f80eSRobert Watson 
1751e183f80eSRobert Watson 	MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label,
1752e183f80eSRobert Watson 	    &result);
1753e183f80eSRobert Watson 
1754e183f80eSRobert Watson 	*prot = result;
1755e183f80eSRobert Watson }
1756e183f80eSRobert Watson 
1757e183f80eSRobert Watson int
1758e183f80eSRobert Watson mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot)
1759e183f80eSRobert Watson {
1760e183f80eSRobert Watson 	int error;
1761e183f80eSRobert Watson 
1762e183f80eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect");
1763e183f80eSRobert Watson 
1764e183f80eSRobert Watson 	if (!mac_enforce_fs || !mac_enforce_vm)
1765e183f80eSRobert Watson 		return (0);
1766e183f80eSRobert Watson 
1767e183f80eSRobert Watson 	MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot);
1768e183f80eSRobert Watson 	return (error);
176995fab37eSRobert Watson }
177095fab37eSRobert Watson 
177195fab37eSRobert Watson int
1772b914de36SRobert Watson mac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode)
177395fab37eSRobert Watson {
177495fab37eSRobert Watson 	int error;
177595fab37eSRobert Watson 
177695fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open");
177795fab37eSRobert Watson 
177895fab37eSRobert Watson 	if (!mac_enforce_fs)
177995fab37eSRobert Watson 		return (0);
178095fab37eSRobert Watson 
178195fab37eSRobert Watson 	MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode);
178295fab37eSRobert Watson 	return (error);
178395fab37eSRobert Watson }
178495fab37eSRobert Watson 
178595fab37eSRobert Watson int
1786177142e4SRobert Watson mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
1787177142e4SRobert Watson     struct vnode *vp)
17887f724f8bSRobert Watson {
17897f724f8bSRobert Watson 	int error;
17907f724f8bSRobert Watson 
17917f724f8bSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll");
17927f724f8bSRobert Watson 
17937f724f8bSRobert Watson 	if (!mac_enforce_fs)
17947f724f8bSRobert Watson 		return (0);
17957f724f8bSRobert Watson 
1796177142e4SRobert Watson 	MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp,
1797177142e4SRobert Watson 	    &vp->v_label);
17987f724f8bSRobert Watson 
17997f724f8bSRobert Watson 	return (error);
18007f724f8bSRobert Watson }
18017f724f8bSRobert Watson 
18027f724f8bSRobert Watson int
1803177142e4SRobert Watson mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
1804177142e4SRobert Watson     struct vnode *vp)
18057f724f8bSRobert Watson {
18067f724f8bSRobert Watson 	int error;
18077f724f8bSRobert Watson 
18087f724f8bSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read");
18097f724f8bSRobert Watson 
18107f724f8bSRobert Watson 	if (!mac_enforce_fs)
18117f724f8bSRobert Watson 		return (0);
18127f724f8bSRobert Watson 
1813177142e4SRobert Watson 	MAC_CHECK(check_vnode_read, active_cred, file_cred, vp,
1814177142e4SRobert Watson 	    &vp->v_label);
18157f724f8bSRobert Watson 
18167f724f8bSRobert Watson 	return (error);
18177f724f8bSRobert Watson }
18187f724f8bSRobert Watson 
18197f724f8bSRobert Watson int
182095fab37eSRobert Watson mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp)
182195fab37eSRobert Watson {
182295fab37eSRobert Watson 	int error;
182395fab37eSRobert Watson 
182495fab37eSRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir");
182595fab37eSRobert Watson 
182695fab37eSRobert Watson 	if (!mac_enforce_fs)
182795fab37eSRobert Watson 		return (0);
182895fab37eSRobert Watson 
182995fab37eSRobert Watson 	MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label);
183095fab37eSRobert Watson 	return (error);
183195fab37eSRobert Watson }
183295fab37eSRobert Watson 
183395fab37eSRobert Watson int
183495fab37eSRobert Watson mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp)
183595fab37eSRobert Watson {
183695fab37eSRobert Watson 	int error;
183795fab37eSRobert Watson 
183895fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink");
183995fab37eSRobert Watson 
184095fab37eSRobert Watson 	if (!mac_enforce_fs)
184195fab37eSRobert Watson 		return (0);
184295fab37eSRobert Watson 
184395fab37eSRobert Watson 	MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label);
184495fab37eSRobert Watson 	return (error);
184595fab37eSRobert Watson }
184695fab37eSRobert Watson 
184795fab37eSRobert Watson static int
184895fab37eSRobert Watson mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
184995fab37eSRobert Watson     struct label *newlabel)
185095fab37eSRobert Watson {
185195fab37eSRobert Watson 	int error;
185295fab37eSRobert Watson 
185395fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel");
185495fab37eSRobert Watson 
185595fab37eSRobert Watson 	MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel);
185695fab37eSRobert Watson 
185795fab37eSRobert Watson 	return (error);
185895fab37eSRobert Watson }
185995fab37eSRobert Watson 
186095fab37eSRobert Watson int
186195fab37eSRobert Watson mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
186295fab37eSRobert Watson     struct vnode *vp, struct componentname *cnp)
186395fab37eSRobert Watson {
186495fab37eSRobert Watson 	int error;
186595fab37eSRobert Watson 
186695fab37eSRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from");
186795fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from");
186895fab37eSRobert Watson 
186995fab37eSRobert Watson 	if (!mac_enforce_fs)
187095fab37eSRobert Watson 		return (0);
187195fab37eSRobert Watson 
187295fab37eSRobert Watson 	MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp,
187395fab37eSRobert Watson 	    &vp->v_label, cnp);
187495fab37eSRobert Watson 	return (error);
187595fab37eSRobert Watson }
187695fab37eSRobert Watson 
187795fab37eSRobert Watson int
187895fab37eSRobert Watson mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
187995fab37eSRobert Watson     struct vnode *vp, int samedir, struct componentname *cnp)
188095fab37eSRobert Watson {
188195fab37eSRobert Watson 	int error;
188295fab37eSRobert Watson 
188395fab37eSRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to");
188495fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to");
188595fab37eSRobert Watson 
188695fab37eSRobert Watson 	if (!mac_enforce_fs)
188795fab37eSRobert Watson 		return (0);
188895fab37eSRobert Watson 
188995fab37eSRobert Watson 	MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp,
189095fab37eSRobert Watson 	    vp != NULL ? &vp->v_label : NULL, samedir, cnp);
189195fab37eSRobert Watson 	return (error);
189295fab37eSRobert Watson }
189395fab37eSRobert Watson 
189495fab37eSRobert Watson int
189595fab37eSRobert Watson mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp)
189695fab37eSRobert Watson {
189795fab37eSRobert Watson 	int error;
189895fab37eSRobert Watson 
189995fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke");
190095fab37eSRobert Watson 
190195fab37eSRobert Watson 	if (!mac_enforce_fs)
190295fab37eSRobert Watson 		return (0);
190395fab37eSRobert Watson 
190495fab37eSRobert Watson 	MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label);
190595fab37eSRobert Watson 	return (error);
190695fab37eSRobert Watson }
190795fab37eSRobert Watson 
190895fab37eSRobert Watson int
190995fab37eSRobert Watson mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
191095fab37eSRobert Watson     struct acl *acl)
191195fab37eSRobert Watson {
191295fab37eSRobert Watson 	int error;
191395fab37eSRobert Watson 
191495fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl");
191595fab37eSRobert Watson 
191695fab37eSRobert Watson 	if (!mac_enforce_fs)
191795fab37eSRobert Watson 		return (0);
191895fab37eSRobert Watson 
191995fab37eSRobert Watson 	MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl);
192095fab37eSRobert Watson 	return (error);
192195fab37eSRobert Watson }
192295fab37eSRobert Watson 
192395fab37eSRobert Watson int
192495fab37eSRobert Watson mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
192595fab37eSRobert Watson     int attrnamespace, const char *name, struct uio *uio)
192695fab37eSRobert Watson {
192795fab37eSRobert Watson 	int error;
192895fab37eSRobert Watson 
192995fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr");
193095fab37eSRobert Watson 
193195fab37eSRobert Watson 	if (!mac_enforce_fs)
193295fab37eSRobert Watson 		return (0);
193395fab37eSRobert Watson 
193495fab37eSRobert Watson 	MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label,
193595fab37eSRobert Watson 	    attrnamespace, name, uio);
193695fab37eSRobert Watson 	return (error);
193795fab37eSRobert Watson }
193895fab37eSRobert Watson 
193995fab37eSRobert Watson int
194095fab37eSRobert Watson mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
194195fab37eSRobert Watson {
194295fab37eSRobert Watson 	int error;
194395fab37eSRobert Watson 
194495fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags");
194595fab37eSRobert Watson 
194695fab37eSRobert Watson 	if (!mac_enforce_fs)
194795fab37eSRobert Watson 		return (0);
194895fab37eSRobert Watson 
194995fab37eSRobert Watson 	MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags);
195095fab37eSRobert Watson 	return (error);
195195fab37eSRobert Watson }
195295fab37eSRobert Watson 
195395fab37eSRobert Watson int
195495fab37eSRobert Watson mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
195595fab37eSRobert Watson {
195695fab37eSRobert Watson 	int error;
195795fab37eSRobert Watson 
195895fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode");
195995fab37eSRobert Watson 
196095fab37eSRobert Watson 	if (!mac_enforce_fs)
196195fab37eSRobert Watson 		return (0);
196295fab37eSRobert Watson 
196395fab37eSRobert Watson 	MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode);
196495fab37eSRobert Watson 	return (error);
196595fab37eSRobert Watson }
196695fab37eSRobert Watson 
196795fab37eSRobert Watson int
196895fab37eSRobert Watson mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
196995fab37eSRobert Watson     gid_t gid)
197095fab37eSRobert Watson {
197195fab37eSRobert Watson 	int error;
197295fab37eSRobert Watson 
197395fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner");
197495fab37eSRobert Watson 
197595fab37eSRobert Watson 	if (!mac_enforce_fs)
197695fab37eSRobert Watson 		return (0);
197795fab37eSRobert Watson 
197895fab37eSRobert Watson 	MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid);
197995fab37eSRobert Watson 	return (error);
198095fab37eSRobert Watson }
198195fab37eSRobert Watson 
198295fab37eSRobert Watson int
198395fab37eSRobert Watson mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
198495fab37eSRobert Watson     struct timespec atime, struct timespec mtime)
198595fab37eSRobert Watson {
198695fab37eSRobert Watson 	int error;
198795fab37eSRobert Watson 
198895fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes");
198995fab37eSRobert Watson 
199095fab37eSRobert Watson 	if (!mac_enforce_fs)
199195fab37eSRobert Watson 		return (0);
199295fab37eSRobert Watson 
199395fab37eSRobert Watson 	MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime,
199495fab37eSRobert Watson 	    mtime);
199595fab37eSRobert Watson 	return (error);
199695fab37eSRobert Watson }
199795fab37eSRobert Watson 
199895fab37eSRobert Watson int
1999177142e4SRobert Watson mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2000177142e4SRobert Watson     struct vnode *vp)
200195fab37eSRobert Watson {
200295fab37eSRobert Watson 	int error;
200395fab37eSRobert Watson 
200495fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat");
200595fab37eSRobert Watson 
200695fab37eSRobert Watson 	if (!mac_enforce_fs)
200795fab37eSRobert Watson 		return (0);
200895fab37eSRobert Watson 
2009177142e4SRobert Watson 	MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp,
2010177142e4SRobert Watson 	    &vp->v_label);
201195fab37eSRobert Watson 	return (error);
201295fab37eSRobert Watson }
201395fab37eSRobert Watson 
20147f724f8bSRobert Watson int
2015177142e4SRobert Watson mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
2016177142e4SRobert Watson     struct vnode *vp)
20177f724f8bSRobert Watson {
20187f724f8bSRobert Watson 	int error;
20197f724f8bSRobert Watson 
20207f724f8bSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write");
20217f724f8bSRobert Watson 
20227f724f8bSRobert Watson 	if (!mac_enforce_fs)
20237f724f8bSRobert Watson 		return (0);
20247f724f8bSRobert Watson 
2025177142e4SRobert Watson 	MAC_CHECK(check_vnode_write, active_cred, file_cred, vp,
2026177142e4SRobert Watson 	    &vp->v_label);
20277f724f8bSRobert Watson 
20287f724f8bSRobert Watson 	return (error);
20297f724f8bSRobert Watson }
20307f724f8bSRobert Watson 
203195fab37eSRobert Watson /*
203295fab37eSRobert Watson  * When relabeling a process, call out to the policies for the maximum
203395fab37eSRobert Watson  * permission allowed for each object type we know about in its
203495fab37eSRobert Watson  * memory space, and revoke access (in the least surprising ways we
203595fab37eSRobert Watson  * know) when necessary.  The process lock is not held here.
203695fab37eSRobert Watson  */
20374d10c0ceSRobert Watson void
203895fab37eSRobert Watson mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred)
203995fab37eSRobert Watson {
204095fab37eSRobert Watson 
204195fab37eSRobert Watson 	/* XXX freeze all other threads */
204295fab37eSRobert Watson 	mac_cred_mmapped_drop_perms_recurse(td, cred,
204395fab37eSRobert Watson 	    &td->td_proc->p_vmspace->vm_map);
204495fab37eSRobert Watson 	/* XXX allow other threads to continue */
204595fab37eSRobert Watson }
204695fab37eSRobert Watson 
204795fab37eSRobert Watson static __inline const char *
204895fab37eSRobert Watson prot2str(vm_prot_t prot)
204995fab37eSRobert Watson {
205095fab37eSRobert Watson 
205195fab37eSRobert Watson 	switch (prot & VM_PROT_ALL) {
205295fab37eSRobert Watson 	case VM_PROT_READ:
205395fab37eSRobert Watson 		return ("r--");
205495fab37eSRobert Watson 	case VM_PROT_READ | VM_PROT_WRITE:
205595fab37eSRobert Watson 		return ("rw-");
205695fab37eSRobert Watson 	case VM_PROT_READ | VM_PROT_EXECUTE:
205795fab37eSRobert Watson 		return ("r-x");
205895fab37eSRobert Watson 	case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
205995fab37eSRobert Watson 		return ("rwx");
206095fab37eSRobert Watson 	case VM_PROT_WRITE:
206195fab37eSRobert Watson 		return ("-w-");
206295fab37eSRobert Watson 	case VM_PROT_EXECUTE:
206395fab37eSRobert Watson 		return ("--x");
206495fab37eSRobert Watson 	case VM_PROT_WRITE | VM_PROT_EXECUTE:
206595fab37eSRobert Watson 		return ("-wx");
206695fab37eSRobert Watson 	default:
206795fab37eSRobert Watson 		return ("---");
206895fab37eSRobert Watson 	}
206995fab37eSRobert Watson }
207095fab37eSRobert Watson 
207195fab37eSRobert Watson static void
207295fab37eSRobert Watson mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred,
207395fab37eSRobert Watson     struct vm_map *map)
207495fab37eSRobert Watson {
207595fab37eSRobert Watson 	struct vm_map_entry *vme;
2076e183f80eSRobert Watson 	int result;
2077e183f80eSRobert Watson 	vm_prot_t revokeperms;
207895fab37eSRobert Watson 	vm_object_t object;
207995fab37eSRobert Watson 	vm_ooffset_t offset;
208095fab37eSRobert Watson 	struct vnode *vp;
208195fab37eSRobert Watson 
2082c0f39905SRobert Watson 	if (!mac_mmap_revocation)
2083c0f39905SRobert Watson 		return;
2084c0f39905SRobert Watson 
208595fab37eSRobert Watson 	vm_map_lock_read(map);
208695fab37eSRobert Watson 	for (vme = map->header.next; vme != &map->header; vme = vme->next) {
208795fab37eSRobert Watson 		if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) {
208895fab37eSRobert Watson 			mac_cred_mmapped_drop_perms_recurse(td, cred,
208995fab37eSRobert Watson 			    vme->object.sub_map);
209095fab37eSRobert Watson 			continue;
209195fab37eSRobert Watson 		}
209295fab37eSRobert Watson 		/*
209395fab37eSRobert Watson 		 * Skip over entries that obviously are not shared.
209495fab37eSRobert Watson 		 */
209595fab37eSRobert Watson 		if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) ||
209695fab37eSRobert Watson 		    !vme->max_protection)
209795fab37eSRobert Watson 			continue;
209895fab37eSRobert Watson 		/*
209995fab37eSRobert Watson 		 * Drill down to the deepest backing object.
210095fab37eSRobert Watson 		 */
210195fab37eSRobert Watson 		offset = vme->offset;
210295fab37eSRobert Watson 		object = vme->object.vm_object;
210395fab37eSRobert Watson 		if (object == NULL)
210495fab37eSRobert Watson 			continue;
210595fab37eSRobert Watson 		while (object->backing_object != NULL) {
210695fab37eSRobert Watson 			object = object->backing_object;
210795fab37eSRobert Watson 			offset += object->backing_object_offset;
210895fab37eSRobert Watson 		}
210995fab37eSRobert Watson 		/*
211095fab37eSRobert Watson 		 * At the moment, vm_maps and objects aren't considered
211195fab37eSRobert Watson 		 * by the MAC system, so only things with backing by a
211295fab37eSRobert Watson 		 * normal object (read: vnodes) are checked.
211395fab37eSRobert Watson 		 */
211495fab37eSRobert Watson 		if (object->type != OBJT_VNODE)
211595fab37eSRobert Watson 			continue;
211695fab37eSRobert Watson 		vp = (struct vnode *)object->handle;
211795fab37eSRobert Watson 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2118e183f80eSRobert Watson 		result = vme->max_protection;
2119e183f80eSRobert Watson 		mac_check_vnode_mmap_downgrade(cred, vp, &result);
212095fab37eSRobert Watson 		VOP_UNLOCK(vp, 0, td);
212195fab37eSRobert Watson 		/*
212295fab37eSRobert Watson 		 * Find out what maximum protection we may be allowing
212395fab37eSRobert Watson 		 * now but a policy needs to get removed.
212495fab37eSRobert Watson 		 */
212595fab37eSRobert Watson 		revokeperms = vme->max_protection & ~result;
212695fab37eSRobert Watson 		if (!revokeperms)
212795fab37eSRobert Watson 			continue;
2128b656366bSBruce Evans 		printf("pid %ld: revoking %s perms from %#lx:%ld "
2129b656366bSBruce Evans 		    "(max %s/cur %s)\n", (long)td->td_proc->p_pid,
2130b656366bSBruce Evans 		    prot2str(revokeperms), (u_long)vme->start,
2131b656366bSBruce Evans 		    (long)(vme->end - vme->start),
213295fab37eSRobert Watson 		    prot2str(vme->max_protection), prot2str(vme->protection));
213395fab37eSRobert Watson 		vm_map_lock_upgrade(map);
213495fab37eSRobert Watson 		/*
213595fab37eSRobert Watson 		 * This is the really simple case: if a map has more
213695fab37eSRobert Watson 		 * max_protection than is allowed, but it's not being
213795fab37eSRobert Watson 		 * actually used (that is, the current protection is
213895fab37eSRobert Watson 		 * still allowed), we can just wipe it out and do
213995fab37eSRobert Watson 		 * nothing more.
214095fab37eSRobert Watson 		 */
214195fab37eSRobert Watson 		if ((vme->protection & revokeperms) == 0) {
214295fab37eSRobert Watson 			vme->max_protection -= revokeperms;
214395fab37eSRobert Watson 		} else {
214495fab37eSRobert Watson 			if (revokeperms & VM_PROT_WRITE) {
214595fab37eSRobert Watson 				/*
214695fab37eSRobert Watson 				 * In the more complicated case, flush out all
214795fab37eSRobert Watson 				 * pending changes to the object then turn it
214895fab37eSRobert Watson 				 * copy-on-write.
214995fab37eSRobert Watson 				 */
215095fab37eSRobert Watson 				vm_object_reference(object);
215195fab37eSRobert Watson 				vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2152b6e48e03SAlan Cox 				VM_OBJECT_LOCK(object);
215395fab37eSRobert Watson 				vm_object_page_clean(object,
215495fab37eSRobert Watson 				    OFF_TO_IDX(offset),
215595fab37eSRobert Watson 				    OFF_TO_IDX(offset + vme->end - vme->start +
215695fab37eSRobert Watson 					PAGE_MASK),
215795fab37eSRobert Watson 				    OBJPC_SYNC);
2158b6e48e03SAlan Cox 				VM_OBJECT_UNLOCK(object);
215995fab37eSRobert Watson 				VOP_UNLOCK(vp, 0, td);
216095fab37eSRobert Watson 				vm_object_deallocate(object);
216195fab37eSRobert Watson 				/*
216295fab37eSRobert Watson 				 * Why bother if there's no read permissions
216395fab37eSRobert Watson 				 * anymore?  For the rest, we need to leave
216495fab37eSRobert Watson 				 * the write permissions on for COW, or
216595fab37eSRobert Watson 				 * remove them entirely if configured to.
216695fab37eSRobert Watson 				 */
216795fab37eSRobert Watson 				if (!mac_mmap_revocation_via_cow) {
216895fab37eSRobert Watson 					vme->max_protection &= ~VM_PROT_WRITE;
216995fab37eSRobert Watson 					vme->protection &= ~VM_PROT_WRITE;
217095fab37eSRobert Watson 				} if ((revokeperms & VM_PROT_READ) == 0)
217195fab37eSRobert Watson 					vme->eflags |= MAP_ENTRY_COW |
217295fab37eSRobert Watson 					    MAP_ENTRY_NEEDS_COPY;
217395fab37eSRobert Watson 			}
217495fab37eSRobert Watson 			if (revokeperms & VM_PROT_EXECUTE) {
217595fab37eSRobert Watson 				vme->max_protection &= ~VM_PROT_EXECUTE;
217695fab37eSRobert Watson 				vme->protection &= ~VM_PROT_EXECUTE;
217795fab37eSRobert Watson 			}
217895fab37eSRobert Watson 			if (revokeperms & VM_PROT_READ) {
217995fab37eSRobert Watson 				vme->max_protection = 0;
218095fab37eSRobert Watson 				vme->protection = 0;
218195fab37eSRobert Watson 			}
218295fab37eSRobert Watson 			pmap_protect(map->pmap, vme->start, vme->end,
218395fab37eSRobert Watson 			    vme->protection & ~revokeperms);
218495fab37eSRobert Watson 			vm_map_simplify_entry(map, vme);
218595fab37eSRobert Watson 		}
218695fab37eSRobert Watson 		vm_map_lock_downgrade(map);
218795fab37eSRobert Watson 	}
218895fab37eSRobert Watson 	vm_map_unlock_read(map);
218995fab37eSRobert Watson }
219095fab37eSRobert Watson 
219195fab37eSRobert Watson /*
219295fab37eSRobert Watson  * When the subject's label changes, it may require revocation of privilege
219395fab37eSRobert Watson  * to mapped objects.  This can't be done on-the-fly later with a unified
219495fab37eSRobert Watson  * buffer cache.
219595fab37eSRobert Watson  */
219695fab37eSRobert Watson static void
219795fab37eSRobert Watson mac_relabel_cred(struct ucred *cred, struct label *newlabel)
219895fab37eSRobert Watson {
219995fab37eSRobert Watson 
220095fab37eSRobert Watson 	MAC_PERFORM(relabel_cred, cred, newlabel);
220195fab37eSRobert Watson }
220295fab37eSRobert Watson 
220395fab37eSRobert Watson void
220495fab37eSRobert Watson mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel)
220595fab37eSRobert Watson {
220695fab37eSRobert Watson 
220795fab37eSRobert Watson 	MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel);
220895fab37eSRobert Watson }
220995fab37eSRobert Watson 
221095fab37eSRobert Watson void
221195fab37eSRobert Watson mac_create_ifnet(struct ifnet *ifnet)
221295fab37eSRobert Watson {
221395fab37eSRobert Watson 
221495fab37eSRobert Watson 	MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label);
221595fab37eSRobert Watson }
221695fab37eSRobert Watson 
221795fab37eSRobert Watson void
221895fab37eSRobert Watson mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d)
221995fab37eSRobert Watson {
222095fab37eSRobert Watson 
222195fab37eSRobert Watson 	MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label);
222295fab37eSRobert Watson }
222395fab37eSRobert Watson 
222495fab37eSRobert Watson void
222595fab37eSRobert Watson mac_create_socket(struct ucred *cred, struct socket *socket)
222695fab37eSRobert Watson {
222795fab37eSRobert Watson 
222895fab37eSRobert Watson 	MAC_PERFORM(create_socket, cred, socket, &socket->so_label);
222995fab37eSRobert Watson }
223095fab37eSRobert Watson 
223195fab37eSRobert Watson void
223295fab37eSRobert Watson mac_create_pipe(struct ucred *cred, struct pipe *pipe)
223395fab37eSRobert Watson {
223495fab37eSRobert Watson 
223595fab37eSRobert Watson 	MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label);
223695fab37eSRobert Watson }
223795fab37eSRobert Watson 
223895fab37eSRobert Watson void
223995fab37eSRobert Watson mac_create_socket_from_socket(struct socket *oldsocket,
224095fab37eSRobert Watson     struct socket *newsocket)
224195fab37eSRobert Watson {
224295fab37eSRobert Watson 
224395fab37eSRobert Watson 	MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label,
224495fab37eSRobert Watson 	    newsocket, &newsocket->so_label);
224595fab37eSRobert Watson }
224695fab37eSRobert Watson 
224795fab37eSRobert Watson static void
224895fab37eSRobert Watson mac_relabel_socket(struct ucred *cred, struct socket *socket,
224995fab37eSRobert Watson     struct label *newlabel)
225095fab37eSRobert Watson {
225195fab37eSRobert Watson 
225295fab37eSRobert Watson 	MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel);
225395fab37eSRobert Watson }
225495fab37eSRobert Watson 
225595fab37eSRobert Watson static void
225695fab37eSRobert Watson mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel)
225795fab37eSRobert Watson {
225895fab37eSRobert Watson 
225995fab37eSRobert Watson 	MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel);
226095fab37eSRobert Watson }
226195fab37eSRobert Watson 
226295fab37eSRobert Watson void
226395fab37eSRobert Watson mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket)
226495fab37eSRobert Watson {
226510eeb10cSRobert Watson 	struct label *label;
226695fab37eSRobert Watson 
226710eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
226810eeb10cSRobert Watson 
226910eeb10cSRobert Watson 	MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket,
227010eeb10cSRobert Watson 	    &socket->so_peerlabel);
227195fab37eSRobert Watson }
227295fab37eSRobert Watson 
227395fab37eSRobert Watson void
227495fab37eSRobert Watson mac_set_socket_peer_from_socket(struct socket *oldsocket,
227595fab37eSRobert Watson     struct socket *newsocket)
227695fab37eSRobert Watson {
227795fab37eSRobert Watson 
227895fab37eSRobert Watson 	MAC_PERFORM(set_socket_peer_from_socket, oldsocket,
227995fab37eSRobert Watson 	    &oldsocket->so_label, newsocket, &newsocket->so_peerlabel);
228095fab37eSRobert Watson }
228195fab37eSRobert Watson 
228295fab37eSRobert Watson void
228395fab37eSRobert Watson mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram)
228495fab37eSRobert Watson {
228510eeb10cSRobert Watson 	struct label *label;
228610eeb10cSRobert Watson 
228710eeb10cSRobert Watson 	label = mbuf_to_label(datagram);
228895fab37eSRobert Watson 
228995fab37eSRobert Watson 	MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label,
229010eeb10cSRobert Watson 	    datagram, label);
229195fab37eSRobert Watson }
229295fab37eSRobert Watson 
229395fab37eSRobert Watson void
229495fab37eSRobert Watson mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment)
229595fab37eSRobert Watson {
229610eeb10cSRobert Watson 	struct label *datagramlabel, *fragmentlabel;
229795fab37eSRobert Watson 
229810eeb10cSRobert Watson 	datagramlabel = mbuf_to_label(datagram);
229910eeb10cSRobert Watson 	fragmentlabel = mbuf_to_label(fragment);
230010eeb10cSRobert Watson 
230110eeb10cSRobert Watson 	MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment,
230210eeb10cSRobert Watson 	    fragmentlabel);
230395fab37eSRobert Watson }
230495fab37eSRobert Watson 
230595fab37eSRobert Watson void
230695fab37eSRobert Watson mac_create_ipq(struct mbuf *fragment, struct ipq *ipq)
230795fab37eSRobert Watson {
230810eeb10cSRobert Watson 	struct label *label;
230995fab37eSRobert Watson 
231010eeb10cSRobert Watson 	label = mbuf_to_label(fragment);
231110eeb10cSRobert Watson 
231210eeb10cSRobert Watson 	MAC_PERFORM(create_ipq, fragment, label, ipq, &ipq->ipq_label);
231395fab37eSRobert Watson }
231495fab37eSRobert Watson 
231595fab37eSRobert Watson void
231695fab37eSRobert Watson mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf)
231795fab37eSRobert Watson {
231810eeb10cSRobert Watson 	struct label *oldmbuflabel, *newmbuflabel;
231995fab37eSRobert Watson 
232010eeb10cSRobert Watson 	oldmbuflabel = mbuf_to_label(oldmbuf);
232110eeb10cSRobert Watson 	newmbuflabel = mbuf_to_label(newmbuf);
232210eeb10cSRobert Watson 
232310eeb10cSRobert Watson 	MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf,
232410eeb10cSRobert Watson 	    newmbuflabel);
232595fab37eSRobert Watson }
232695fab37eSRobert Watson 
232795fab37eSRobert Watson void
232895fab37eSRobert Watson mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf)
232995fab37eSRobert Watson {
233010eeb10cSRobert Watson 	struct label *label;
233110eeb10cSRobert Watson 
233210eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
233395fab37eSRobert Watson 
233495fab37eSRobert Watson 	MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf,
233510eeb10cSRobert Watson 	    label);
233695fab37eSRobert Watson }
233795fab37eSRobert Watson 
233895fab37eSRobert Watson void
233995fab37eSRobert Watson mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf)
234095fab37eSRobert Watson {
234110eeb10cSRobert Watson 	struct label *label;
234210eeb10cSRobert Watson 
234310eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
234495fab37eSRobert Watson 
234595fab37eSRobert Watson 	MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf,
234610eeb10cSRobert Watson 	    label);
234795fab37eSRobert Watson }
234895fab37eSRobert Watson 
234995fab37eSRobert Watson void
235095fab37eSRobert Watson mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf)
235195fab37eSRobert Watson {
235210eeb10cSRobert Watson 	struct label *label;
235310eeb10cSRobert Watson 
235410eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
235595fab37eSRobert Watson 
235695fab37eSRobert Watson 	MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf,
235710eeb10cSRobert Watson 	    label);
235895fab37eSRobert Watson }
235995fab37eSRobert Watson 
236095fab37eSRobert Watson void
236195fab37eSRobert Watson mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet,
236295fab37eSRobert Watson     struct mbuf *newmbuf)
236395fab37eSRobert Watson {
236410eeb10cSRobert Watson 	struct label *oldmbuflabel, *newmbuflabel;
236595fab37eSRobert Watson 
236610eeb10cSRobert Watson 	oldmbuflabel = mbuf_to_label(oldmbuf);
236710eeb10cSRobert Watson 	newmbuflabel = mbuf_to_label(newmbuf);
236810eeb10cSRobert Watson 
236910eeb10cSRobert Watson 	MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel,
237010eeb10cSRobert Watson 	    ifnet, &ifnet->if_label, newmbuf, newmbuflabel);
237195fab37eSRobert Watson }
237295fab37eSRobert Watson 
237395fab37eSRobert Watson void
237495fab37eSRobert Watson mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf)
237595fab37eSRobert Watson {
237610eeb10cSRobert Watson 	struct label *oldmbuflabel, *newmbuflabel;
237795fab37eSRobert Watson 
237810eeb10cSRobert Watson 	oldmbuflabel = mbuf_to_label(oldmbuf);
237910eeb10cSRobert Watson 	newmbuflabel = mbuf_to_label(newmbuf);
238010eeb10cSRobert Watson 
238110eeb10cSRobert Watson 	MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf,
238210eeb10cSRobert Watson 	    newmbuflabel);
238395fab37eSRobert Watson }
238495fab37eSRobert Watson 
238595fab37eSRobert Watson int
238695fab37eSRobert Watson mac_fragment_match(struct mbuf *fragment, struct ipq *ipq)
238795fab37eSRobert Watson {
238810eeb10cSRobert Watson 	struct label *label;
238995fab37eSRobert Watson 	int result;
239095fab37eSRobert Watson 
239110eeb10cSRobert Watson 	label = mbuf_to_label(fragment);
239210eeb10cSRobert Watson 
239395fab37eSRobert Watson 	result = 1;
239410eeb10cSRobert Watson 	MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq,
239510eeb10cSRobert Watson 	    &ipq->ipq_label);
239695fab37eSRobert Watson 
239795fab37eSRobert Watson 	return (result);
239895fab37eSRobert Watson }
239995fab37eSRobert Watson 
240095fab37eSRobert Watson void
2401eb8c7f99SRobert Watson mac_reflect_mbuf_icmp(struct mbuf *m)
2402eb8c7f99SRobert Watson {
2403eb8c7f99SRobert Watson 	struct label *label;
2404eb8c7f99SRobert Watson 
2405eb8c7f99SRobert Watson 	label = mbuf_to_label(m);
2406eb8c7f99SRobert Watson 
2407eb8c7f99SRobert Watson 	MAC_PERFORM(reflect_mbuf_icmp, m, label);
2408eb8c7f99SRobert Watson }
2409eb8c7f99SRobert Watson void
2410eb8c7f99SRobert Watson mac_reflect_mbuf_tcp(struct mbuf *m)
2411eb8c7f99SRobert Watson {
2412eb8c7f99SRobert Watson 	struct label *label;
2413eb8c7f99SRobert Watson 
2414eb8c7f99SRobert Watson 	label = mbuf_to_label(m);
2415eb8c7f99SRobert Watson 
2416eb8c7f99SRobert Watson 	MAC_PERFORM(reflect_mbuf_tcp, m, label);
2417eb8c7f99SRobert Watson }
2418eb8c7f99SRobert Watson 
2419eb8c7f99SRobert Watson void
242095fab37eSRobert Watson mac_update_ipq(struct mbuf *fragment, struct ipq *ipq)
242195fab37eSRobert Watson {
242210eeb10cSRobert Watson 	struct label *label;
242395fab37eSRobert Watson 
242410eeb10cSRobert Watson 	label = mbuf_to_label(fragment);
242510eeb10cSRobert Watson 
242610eeb10cSRobert Watson 	MAC_PERFORM(update_ipq, fragment, label, ipq, &ipq->ipq_label);
242795fab37eSRobert Watson }
242895fab37eSRobert Watson 
242995fab37eSRobert Watson void
243095fab37eSRobert Watson mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf)
243195fab37eSRobert Watson {
243210eeb10cSRobert Watson 	struct label *label;
243310eeb10cSRobert Watson 
243410eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
243595fab37eSRobert Watson 
243695fab37eSRobert Watson 	MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf,
243710eeb10cSRobert Watson 	    label);
243895fab37eSRobert Watson }
243995fab37eSRobert Watson 
244095fab37eSRobert Watson void
244195fab37eSRobert Watson mac_create_mount(struct ucred *cred, struct mount *mp)
244295fab37eSRobert Watson {
244395fab37eSRobert Watson 
244495fab37eSRobert Watson 	MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel,
244595fab37eSRobert Watson 	    &mp->mnt_fslabel);
244695fab37eSRobert Watson }
244795fab37eSRobert Watson 
244895fab37eSRobert Watson void
244995fab37eSRobert Watson mac_create_root_mount(struct ucred *cred, struct mount *mp)
245095fab37eSRobert Watson {
245195fab37eSRobert Watson 
245295fab37eSRobert Watson 	MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel,
245395fab37eSRobert Watson 	    &mp->mnt_fslabel);
245495fab37eSRobert Watson }
245595fab37eSRobert Watson 
245695fab37eSRobert Watson int
245795fab37eSRobert Watson mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet)
245895fab37eSRobert Watson {
245995fab37eSRobert Watson 	int error;
246095fab37eSRobert Watson 
246195fab37eSRobert Watson 	if (!mac_enforce_network)
246295fab37eSRobert Watson 		return (0);
246395fab37eSRobert Watson 
246495fab37eSRobert Watson 	MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet,
246595fab37eSRobert Watson 	    &ifnet->if_label);
246695fab37eSRobert Watson 
246795fab37eSRobert Watson 	return (error);
246895fab37eSRobert Watson }
246995fab37eSRobert Watson 
247095fab37eSRobert Watson static int
247195fab37eSRobert Watson mac_check_cred_relabel(struct ucred *cred, struct label *newlabel)
247295fab37eSRobert Watson {
247395fab37eSRobert Watson 	int error;
247495fab37eSRobert Watson 
247595fab37eSRobert Watson 	MAC_CHECK(check_cred_relabel, cred, newlabel);
247695fab37eSRobert Watson 
247795fab37eSRobert Watson 	return (error);
247895fab37eSRobert Watson }
247995fab37eSRobert Watson 
248095fab37eSRobert Watson int
248195fab37eSRobert Watson mac_check_cred_visible(struct ucred *u1, struct ucred *u2)
248295fab37eSRobert Watson {
248395fab37eSRobert Watson 	int error;
248495fab37eSRobert Watson 
248595fab37eSRobert Watson 	if (!mac_enforce_process)
248695fab37eSRobert Watson 		return (0);
248795fab37eSRobert Watson 
248895fab37eSRobert Watson 	MAC_CHECK(check_cred_visible, u1, u2);
248995fab37eSRobert Watson 
249095fab37eSRobert Watson 	return (error);
249195fab37eSRobert Watson }
249295fab37eSRobert Watson 
249395fab37eSRobert Watson int
249495fab37eSRobert Watson mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf)
249595fab37eSRobert Watson {
249610eeb10cSRobert Watson 	struct label *label;
249795fab37eSRobert Watson 	int error;
249895fab37eSRobert Watson 
2499225bff6fSRobert Watson 	M_ASSERTPKTHDR(mbuf);
2500225bff6fSRobert Watson 
250195fab37eSRobert Watson 	if (!mac_enforce_network)
250295fab37eSRobert Watson 		return (0);
250395fab37eSRobert Watson 
250410eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
250595fab37eSRobert Watson 
250695fab37eSRobert Watson 	MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf,
250710eeb10cSRobert Watson 	    label);
250895fab37eSRobert Watson 
250995fab37eSRobert Watson 	return (error);
251095fab37eSRobert Watson }
251195fab37eSRobert Watson 
251295fab37eSRobert Watson int
2513e686e5aeSRobert Watson mac_check_kenv_dump(struct ucred *cred)
2514e686e5aeSRobert Watson {
2515e686e5aeSRobert Watson 	int error;
2516e686e5aeSRobert Watson 
2517e686e5aeSRobert Watson 	if (!mac_enforce_system)
2518e686e5aeSRobert Watson 		return (0);
2519e686e5aeSRobert Watson 
2520e686e5aeSRobert Watson 	MAC_CHECK(check_kenv_dump, cred);
2521e686e5aeSRobert Watson 
2522e686e5aeSRobert Watson 	return (error);
2523e686e5aeSRobert Watson }
2524e686e5aeSRobert Watson 
2525e686e5aeSRobert Watson int
2526e686e5aeSRobert Watson mac_check_kenv_get(struct ucred *cred, char *name)
2527e686e5aeSRobert Watson {
2528e686e5aeSRobert Watson 	int error;
2529e686e5aeSRobert Watson 
2530e686e5aeSRobert Watson 	if (!mac_enforce_system)
2531e686e5aeSRobert Watson 		return (0);
2532e686e5aeSRobert Watson 
2533e686e5aeSRobert Watson 	MAC_CHECK(check_kenv_get, cred, name);
2534e686e5aeSRobert Watson 
2535e686e5aeSRobert Watson 	return (error);
2536e686e5aeSRobert Watson }
2537e686e5aeSRobert Watson 
2538e686e5aeSRobert Watson int
2539e686e5aeSRobert Watson mac_check_kenv_set(struct ucred *cred, char *name, char *value)
2540e686e5aeSRobert Watson {
2541e686e5aeSRobert Watson 	int error;
2542e686e5aeSRobert Watson 
2543e686e5aeSRobert Watson 	if (!mac_enforce_system)
2544e686e5aeSRobert Watson 		return (0);
2545e686e5aeSRobert Watson 
2546e686e5aeSRobert Watson 	MAC_CHECK(check_kenv_set, cred, name, value);
2547e686e5aeSRobert Watson 
2548e686e5aeSRobert Watson 	return (error);
2549e686e5aeSRobert Watson }
2550e686e5aeSRobert Watson 
2551e686e5aeSRobert Watson int
2552e686e5aeSRobert Watson mac_check_kenv_unset(struct ucred *cred, char *name)
2553e686e5aeSRobert Watson {
2554e686e5aeSRobert Watson 	int error;
2555e686e5aeSRobert Watson 
2556e686e5aeSRobert Watson 	if (!mac_enforce_system)
2557e686e5aeSRobert Watson 		return (0);
2558e686e5aeSRobert Watson 
2559e686e5aeSRobert Watson 	MAC_CHECK(check_kenv_unset, cred, name);
2560e686e5aeSRobert Watson 
2561e686e5aeSRobert Watson 	return (error);
2562e686e5aeSRobert Watson }
2563e686e5aeSRobert Watson 
2564e686e5aeSRobert Watson int
2565a3df768bSRobert Watson mac_check_kld_load(struct ucred *cred, struct vnode *vp)
2566a3df768bSRobert Watson {
2567a3df768bSRobert Watson 	int error;
2568a3df768bSRobert Watson 
2569a3df768bSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_kld_load");
2570a3df768bSRobert Watson 
2571a3df768bSRobert Watson 	if (!mac_enforce_kld)
2572a3df768bSRobert Watson 		return (0);
2573a3df768bSRobert Watson 
2574a3df768bSRobert Watson 	MAC_CHECK(check_kld_load, cred, vp, &vp->v_label);
2575a3df768bSRobert Watson 
2576a3df768bSRobert Watson 	return (error);
2577a3df768bSRobert Watson }
2578a3df768bSRobert Watson 
2579a3df768bSRobert Watson int
2580a3df768bSRobert Watson mac_check_kld_stat(struct ucred *cred)
2581a3df768bSRobert Watson {
2582a3df768bSRobert Watson 	int error;
2583a3df768bSRobert Watson 
2584a3df768bSRobert Watson 	if (!mac_enforce_kld)
2585a3df768bSRobert Watson 		return (0);
2586a3df768bSRobert Watson 
2587a3df768bSRobert Watson 	MAC_CHECK(check_kld_stat, cred);
2588a3df768bSRobert Watson 
2589a3df768bSRobert Watson 	return (error);
2590a3df768bSRobert Watson }
2591a3df768bSRobert Watson 
2592a3df768bSRobert Watson int
2593a3df768bSRobert Watson mac_check_kld_unload(struct ucred *cred)
2594a3df768bSRobert Watson {
2595a3df768bSRobert Watson 	int error;
2596a3df768bSRobert Watson 
2597a3df768bSRobert Watson 	if (!mac_enforce_kld)
2598a3df768bSRobert Watson 		return (0);
2599a3df768bSRobert Watson 
2600a3df768bSRobert Watson 	MAC_CHECK(check_kld_unload, cred);
2601a3df768bSRobert Watson 
2602a3df768bSRobert Watson 	return (error);
2603a3df768bSRobert Watson }
2604a3df768bSRobert Watson 
2605a3df768bSRobert Watson int
260695fab37eSRobert Watson mac_check_mount_stat(struct ucred *cred, struct mount *mount)
260795fab37eSRobert Watson {
260895fab37eSRobert Watson 	int error;
260995fab37eSRobert Watson 
261095fab37eSRobert Watson 	if (!mac_enforce_fs)
261195fab37eSRobert Watson 		return (0);
261295fab37eSRobert Watson 
261395fab37eSRobert Watson 	MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel);
261495fab37eSRobert Watson 
261595fab37eSRobert Watson 	return (error);
261695fab37eSRobert Watson }
261795fab37eSRobert Watson 
261895fab37eSRobert Watson int
261995fab37eSRobert Watson mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd,
262095fab37eSRobert Watson     void *data)
262195fab37eSRobert Watson {
262295fab37eSRobert Watson 	int error;
262395fab37eSRobert Watson 
26241aa37f53SRobert Watson 	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
26251aa37f53SRobert Watson 
26261aa37f53SRobert Watson 	if (!mac_enforce_pipe)
26271aa37f53SRobert Watson 		return (0);
26281aa37f53SRobert Watson 
262995fab37eSRobert Watson 	MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data);
263095fab37eSRobert Watson 
263195fab37eSRobert Watson 	return (error);
263295fab37eSRobert Watson }
263395fab37eSRobert Watson 
263495fab37eSRobert Watson int
2635c024c3eeSRobert Watson mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe)
263695fab37eSRobert Watson {
263795fab37eSRobert Watson 	int error;
263895fab37eSRobert Watson 
26391aa37f53SRobert Watson 	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
26401aa37f53SRobert Watson 
26411aa37f53SRobert Watson 	if (!mac_enforce_pipe)
26421aa37f53SRobert Watson 		return (0);
26431aa37f53SRobert Watson 
2644c024c3eeSRobert Watson 	MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label);
2645c024c3eeSRobert Watson 
2646c024c3eeSRobert Watson 	return (error);
2647c024c3eeSRobert Watson }
2648c024c3eeSRobert Watson 
2649c024c3eeSRobert Watson int
2650c024c3eeSRobert Watson mac_check_pipe_read(struct ucred *cred, struct pipe *pipe)
2651c024c3eeSRobert Watson {
2652c024c3eeSRobert Watson 	int error;
2653c024c3eeSRobert Watson 
26541aa37f53SRobert Watson 	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
26551aa37f53SRobert Watson 
26561aa37f53SRobert Watson 	if (!mac_enforce_pipe)
26571aa37f53SRobert Watson 		return (0);
26581aa37f53SRobert Watson 
2659c024c3eeSRobert Watson 	MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label);
266095fab37eSRobert Watson 
266195fab37eSRobert Watson 	return (error);
266295fab37eSRobert Watson }
266395fab37eSRobert Watson 
266495fab37eSRobert Watson static int
266595fab37eSRobert Watson mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
266695fab37eSRobert Watson     struct label *newlabel)
266795fab37eSRobert Watson {
266895fab37eSRobert Watson 	int error;
266995fab37eSRobert Watson 
26701aa37f53SRobert Watson 	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
26711aa37f53SRobert Watson 
26721aa37f53SRobert Watson 	if (!mac_enforce_pipe)
26731aa37f53SRobert Watson 		return (0);
26741aa37f53SRobert Watson 
267595fab37eSRobert Watson 	MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel);
267695fab37eSRobert Watson 
267795fab37eSRobert Watson 	return (error);
267895fab37eSRobert Watson }
267995fab37eSRobert Watson 
268095fab37eSRobert Watson int
2681c024c3eeSRobert Watson mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe)
2682c024c3eeSRobert Watson {
2683c024c3eeSRobert Watson 	int error;
2684c024c3eeSRobert Watson 
26851aa37f53SRobert Watson 	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
26861aa37f53SRobert Watson 
26871aa37f53SRobert Watson 	if (!mac_enforce_pipe)
26881aa37f53SRobert Watson 		return (0);
26891aa37f53SRobert Watson 
2690c024c3eeSRobert Watson 	MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label);
2691c024c3eeSRobert Watson 
2692c024c3eeSRobert Watson 	return (error);
2693c024c3eeSRobert Watson }
2694c024c3eeSRobert Watson 
2695c024c3eeSRobert Watson int
2696c024c3eeSRobert Watson mac_check_pipe_write(struct ucred *cred, struct pipe *pipe)
2697c024c3eeSRobert Watson {
2698c024c3eeSRobert Watson 	int error;
2699c024c3eeSRobert Watson 
27001aa37f53SRobert Watson 	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
27011aa37f53SRobert Watson 
27021aa37f53SRobert Watson 	if (!mac_enforce_pipe)
27031aa37f53SRobert Watson 		return (0);
27041aa37f53SRobert Watson 
2705c024c3eeSRobert Watson 	MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label);
2706c024c3eeSRobert Watson 
2707c024c3eeSRobert Watson 	return (error);
2708c024c3eeSRobert Watson }
2709c024c3eeSRobert Watson 
2710c024c3eeSRobert Watson int
271195fab37eSRobert Watson mac_check_proc_debug(struct ucred *cred, struct proc *proc)
271295fab37eSRobert Watson {
271395fab37eSRobert Watson 	int error;
271495fab37eSRobert Watson 
2715b12baf55SRobert Watson 	PROC_LOCK_ASSERT(proc, MA_OWNED);
2716b12baf55SRobert Watson 
271795fab37eSRobert Watson 	if (!mac_enforce_process)
271895fab37eSRobert Watson 		return (0);
271995fab37eSRobert Watson 
272095fab37eSRobert Watson 	MAC_CHECK(check_proc_debug, cred, proc);
272195fab37eSRobert Watson 
272295fab37eSRobert Watson 	return (error);
272395fab37eSRobert Watson }
272495fab37eSRobert Watson 
272595fab37eSRobert Watson int
272695fab37eSRobert Watson mac_check_proc_sched(struct ucred *cred, struct proc *proc)
272795fab37eSRobert Watson {
272895fab37eSRobert Watson 	int error;
272995fab37eSRobert Watson 
2730b12baf55SRobert Watson 	PROC_LOCK_ASSERT(proc, MA_OWNED);
2731b12baf55SRobert Watson 
273295fab37eSRobert Watson 	if (!mac_enforce_process)
273395fab37eSRobert Watson 		return (0);
273495fab37eSRobert Watson 
273595fab37eSRobert Watson 	MAC_CHECK(check_proc_sched, cred, proc);
273695fab37eSRobert Watson 
273795fab37eSRobert Watson 	return (error);
273895fab37eSRobert Watson }
273995fab37eSRobert Watson 
274095fab37eSRobert Watson int
274195fab37eSRobert Watson mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
274295fab37eSRobert Watson {
274395fab37eSRobert Watson 	int error;
274495fab37eSRobert Watson 
2745b12baf55SRobert Watson 	PROC_LOCK_ASSERT(proc, MA_OWNED);
2746b12baf55SRobert Watson 
274795fab37eSRobert Watson 	if (!mac_enforce_process)
274895fab37eSRobert Watson 		return (0);
274995fab37eSRobert Watson 
275095fab37eSRobert Watson 	MAC_CHECK(check_proc_signal, cred, proc, signum);
275195fab37eSRobert Watson 
275295fab37eSRobert Watson 	return (error);
275395fab37eSRobert Watson }
275495fab37eSRobert Watson 
275595fab37eSRobert Watson int
275695fab37eSRobert Watson mac_check_socket_bind(struct ucred *ucred, struct socket *socket,
275795fab37eSRobert Watson     struct sockaddr *sockaddr)
275895fab37eSRobert Watson {
275995fab37eSRobert Watson 	int error;
276095fab37eSRobert Watson 
276195fab37eSRobert Watson 	if (!mac_enforce_socket)
276295fab37eSRobert Watson 		return (0);
276395fab37eSRobert Watson 
276495fab37eSRobert Watson 	MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label,
276595fab37eSRobert Watson 	    sockaddr);
276695fab37eSRobert Watson 
276795fab37eSRobert Watson 	return (error);
276895fab37eSRobert Watson }
276995fab37eSRobert Watson 
277095fab37eSRobert Watson int
277195fab37eSRobert Watson mac_check_socket_connect(struct ucred *cred, struct socket *socket,
277295fab37eSRobert Watson     struct sockaddr *sockaddr)
277395fab37eSRobert Watson {
277495fab37eSRobert Watson 	int error;
277595fab37eSRobert Watson 
277695fab37eSRobert Watson 	if (!mac_enforce_socket)
277795fab37eSRobert Watson 		return (0);
277895fab37eSRobert Watson 
277995fab37eSRobert Watson 	MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label,
278095fab37eSRobert Watson 	    sockaddr);
278195fab37eSRobert Watson 
278295fab37eSRobert Watson 	return (error);
278395fab37eSRobert Watson }
278495fab37eSRobert Watson 
278595fab37eSRobert Watson int
2786d61198e4SRobert Watson mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf)
2787d61198e4SRobert Watson {
278810eeb10cSRobert Watson 	struct label *label;
2789d61198e4SRobert Watson 	int error;
2790d61198e4SRobert Watson 
2791d61198e4SRobert Watson 	if (!mac_enforce_socket)
2792d61198e4SRobert Watson 		return (0);
2793d61198e4SRobert Watson 
279410eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
279510eeb10cSRobert Watson 
2796d61198e4SRobert Watson 	MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf,
279710eeb10cSRobert Watson 	    label);
2798d61198e4SRobert Watson 
2799d61198e4SRobert Watson 	return (error);
2800d61198e4SRobert Watson }
2801d61198e4SRobert Watson 
2802d61198e4SRobert Watson int
280395fab37eSRobert Watson mac_check_socket_listen(struct ucred *cred, struct socket *socket)
280495fab37eSRobert Watson {
280595fab37eSRobert Watson 	int error;
280695fab37eSRobert Watson 
280795fab37eSRobert Watson 	if (!mac_enforce_socket)
280895fab37eSRobert Watson 		return (0);
280995fab37eSRobert Watson 
281095fab37eSRobert Watson 	MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label);
281195fab37eSRobert Watson 	return (error);
281295fab37eSRobert Watson }
281395fab37eSRobert Watson 
2814b371c939SRobert Watson int
2815b371c939SRobert Watson mac_check_socket_receive(struct ucred *cred, struct socket *so)
2816b371c939SRobert Watson {
2817b371c939SRobert Watson 	int error;
2818b371c939SRobert Watson 
2819b371c939SRobert Watson 	if (!mac_enforce_socket)
2820b371c939SRobert Watson 		return (0);
2821b371c939SRobert Watson 
2822b371c939SRobert Watson 	MAC_CHECK(check_socket_receive, cred, so, &so->so_label);
2823b371c939SRobert Watson 
2824b371c939SRobert Watson 	return (error);
2825b371c939SRobert Watson }
2826b371c939SRobert Watson 
282795fab37eSRobert Watson static int
282895fab37eSRobert Watson mac_check_socket_relabel(struct ucred *cred, struct socket *socket,
282995fab37eSRobert Watson     struct label *newlabel)
283095fab37eSRobert Watson {
283195fab37eSRobert Watson 	int error;
283295fab37eSRobert Watson 
283395fab37eSRobert Watson 	MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label,
283495fab37eSRobert Watson 	    newlabel);
283595fab37eSRobert Watson 
283695fab37eSRobert Watson 	return (error);
283795fab37eSRobert Watson }
283895fab37eSRobert Watson 
283995fab37eSRobert Watson int
2840b371c939SRobert Watson mac_check_socket_send(struct ucred *cred, struct socket *so)
2841b371c939SRobert Watson {
2842b371c939SRobert Watson 	int error;
2843b371c939SRobert Watson 
2844b371c939SRobert Watson 	if (!mac_enforce_socket)
2845b371c939SRobert Watson 		return (0);
2846b371c939SRobert Watson 
2847b371c939SRobert Watson 	MAC_CHECK(check_socket_send, cred, so, &so->so_label);
2848b371c939SRobert Watson 
2849b371c939SRobert Watson 	return (error);
2850b371c939SRobert Watson }
2851b371c939SRobert Watson 
2852b371c939SRobert Watson int
285395fab37eSRobert Watson mac_check_socket_visible(struct ucred *cred, struct socket *socket)
285495fab37eSRobert Watson {
285595fab37eSRobert Watson 	int error;
285695fab37eSRobert Watson 
285795fab37eSRobert Watson 	if (!mac_enforce_socket)
285895fab37eSRobert Watson 		return (0);
285995fab37eSRobert Watson 
286095fab37eSRobert Watson 	MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label);
286195fab37eSRobert Watson 
286295fab37eSRobert Watson 	return (error);
286395fab37eSRobert Watson }
286495fab37eSRobert Watson 
286595fab37eSRobert Watson int
286692835789SRobert Watson mac_check_sysarch_ioperm(struct ucred *cred)
286792835789SRobert Watson {
286892835789SRobert Watson 	int error;
286992835789SRobert Watson 
287092835789SRobert Watson 	if (!mac_enforce_system)
287192835789SRobert Watson 		return (0);
287292835789SRobert Watson 
287392835789SRobert Watson 	MAC_CHECK(check_sysarch_ioperm, cred);
287492835789SRobert Watson 	return (error);
287592835789SRobert Watson }
287692835789SRobert Watson 
287792835789SRobert Watson int
2878e5e820fdSRobert Watson mac_check_system_acct(struct ucred *cred, struct vnode *vp)
2879e5e820fdSRobert Watson {
2880e5e820fdSRobert Watson 	int error;
2881e5e820fdSRobert Watson 
2882e5e820fdSRobert Watson 	if (vp != NULL) {
2883e5e820fdSRobert Watson 		ASSERT_VOP_LOCKED(vp, "mac_check_system_acct");
2884e5e820fdSRobert Watson 	}
2885e5e820fdSRobert Watson 
2886e5e820fdSRobert Watson 	if (!mac_enforce_system)
2887e5e820fdSRobert Watson 		return (0);
2888e5e820fdSRobert Watson 
2889e5e820fdSRobert Watson 	MAC_CHECK(check_system_acct, cred, vp,
2890e5e820fdSRobert Watson 	    vp != NULL ? &vp->v_label : NULL);
2891e5e820fdSRobert Watson 
2892e5e820fdSRobert Watson 	return (error);
2893e5e820fdSRobert Watson }
2894e5e820fdSRobert Watson 
2895e5e820fdSRobert Watson int
2896e5e820fdSRobert Watson mac_check_system_nfsd(struct ucred *cred)
2897e5e820fdSRobert Watson {
2898e5e820fdSRobert Watson 	int error;
2899e5e820fdSRobert Watson 
2900e5e820fdSRobert Watson 	if (!mac_enforce_system)
2901e5e820fdSRobert Watson 		return (0);
2902e5e820fdSRobert Watson 
2903e5e820fdSRobert Watson 	MAC_CHECK(check_system_nfsd, cred);
2904e5e820fdSRobert Watson 
2905e5e820fdSRobert Watson 	return (error);
2906e5e820fdSRobert Watson }
2907e5e820fdSRobert Watson 
2908e5e820fdSRobert Watson int
2909a2ecb9b7SRobert Watson mac_check_system_reboot(struct ucred *cred, int howto)
2910a2ecb9b7SRobert Watson {
2911a2ecb9b7SRobert Watson 	int error;
2912a2ecb9b7SRobert Watson 
29139e913ebdSRobert Watson 	if (!mac_enforce_system)
2914a2ecb9b7SRobert Watson 		return (0);
2915a2ecb9b7SRobert Watson 
2916a2ecb9b7SRobert Watson 	MAC_CHECK(check_system_reboot, cred, howto);
29179e913ebdSRobert Watson 
2918a2ecb9b7SRobert Watson 	return (error);
2919a2ecb9b7SRobert Watson }
2920a2ecb9b7SRobert Watson 
2921a2ecb9b7SRobert Watson int
29224b8d5f2dSRobert Watson mac_check_system_settime(struct ucred *cred)
29234b8d5f2dSRobert Watson {
29244b8d5f2dSRobert Watson 	int error;
29254b8d5f2dSRobert Watson 
29264b8d5f2dSRobert Watson 	if (!mac_enforce_system)
29274b8d5f2dSRobert Watson 		return (0);
29284b8d5f2dSRobert Watson 
29294b8d5f2dSRobert Watson 	MAC_CHECK(check_system_settime, cred);
29304b8d5f2dSRobert Watson 
29314b8d5f2dSRobert Watson 	return (error);
29324b8d5f2dSRobert Watson }
29334b8d5f2dSRobert Watson 
29344b8d5f2dSRobert Watson int
293503ce2c0cSRobert Watson mac_check_system_swapon(struct ucred *cred, struct vnode *vp)
293603ce2c0cSRobert Watson {
293703ce2c0cSRobert Watson 	int error;
293803ce2c0cSRobert Watson 
293903ce2c0cSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon");
294003ce2c0cSRobert Watson 
29419e913ebdSRobert Watson 	if (!mac_enforce_system)
294203ce2c0cSRobert Watson 		return (0);
294303ce2c0cSRobert Watson 
294403ce2c0cSRobert Watson 	MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label);
294503ce2c0cSRobert Watson 	return (error);
294603ce2c0cSRobert Watson }
294703ce2c0cSRobert Watson 
294803ce2c0cSRobert Watson int
29491b2c2ab2SRobert Watson mac_check_system_swapoff(struct ucred *cred, struct vnode *vp)
29501b2c2ab2SRobert Watson {
29511b2c2ab2SRobert Watson 	int error;
29521b2c2ab2SRobert Watson 
29531b2c2ab2SRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_system_swapoff");
29541b2c2ab2SRobert Watson 
29551b2c2ab2SRobert Watson 	if (!mac_enforce_system)
29561b2c2ab2SRobert Watson 		return (0);
29571b2c2ab2SRobert Watson 
29581b2c2ab2SRobert Watson 	MAC_CHECK(check_system_swapoff, cred, vp, &vp->v_label);
29591b2c2ab2SRobert Watson 	return (error);
29601b2c2ab2SRobert Watson }
29611b2c2ab2SRobert Watson 
29621b2c2ab2SRobert Watson int
2963d3fc69eeSRobert Watson mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
2964d3fc69eeSRobert Watson     void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
2965d3fc69eeSRobert Watson {
2966d3fc69eeSRobert Watson 	int error;
2967d3fc69eeSRobert Watson 
2968d3fc69eeSRobert Watson 	/*
2969d3fc69eeSRobert Watson 	 * XXXMAC: We're very much like to assert the SYSCTL_LOCK here,
2970d3fc69eeSRobert Watson 	 * but since it's not exported from kern_sysctl.c, we can't.
2971d3fc69eeSRobert Watson 	 */
29729e913ebdSRobert Watson 	if (!mac_enforce_system)
2973d3fc69eeSRobert Watson 		return (0);
2974d3fc69eeSRobert Watson 
2975d3fc69eeSRobert Watson 	MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp,
2976d3fc69eeSRobert Watson 	    inkernel, new, newlen);
2977d3fc69eeSRobert Watson 
2978d3fc69eeSRobert Watson 	return (error);
2979d3fc69eeSRobert Watson }
2980d3fc69eeSRobert Watson 
2981d3fc69eeSRobert Watson int
298295fab37eSRobert Watson mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
298395fab37eSRobert Watson     struct ifnet *ifnet)
298495fab37eSRobert Watson {
2985f7b951a8SRobert Watson 	char *elements, *buffer;
2986f7b951a8SRobert Watson 	struct mac mac;
298795fab37eSRobert Watson 	int error;
298895fab37eSRobert Watson 
2989f7b951a8SRobert Watson 	error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
299095fab37eSRobert Watson 	if (error)
299195fab37eSRobert Watson 		return (error);
299295fab37eSRobert Watson 
2993f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
2994f7b951a8SRobert Watson 	if (error)
2995f7b951a8SRobert Watson 		return (error);
2996f7b951a8SRobert Watson 
2997a163d034SWarner Losh 	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
2998f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
2999f7b951a8SRobert Watson 	if (error) {
3000f7b951a8SRobert Watson 		free(elements, M_MACTEMP);
3001f7b951a8SRobert Watson 		return (error);
3002f7b951a8SRobert Watson 	}
3003f7b951a8SRobert Watson 
3004a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3005f7b951a8SRobert Watson 	error = mac_externalize_ifnet_label(&ifnet->if_label, elements,
3006a163d034SWarner Losh 	    buffer, mac.m_buflen, M_WAITOK);
3007f7b951a8SRobert Watson 	if (error == 0)
3008f7b951a8SRobert Watson 		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
3009f7b951a8SRobert Watson 
3010f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3011f7b951a8SRobert Watson 	free(elements, M_MACTEMP);
3012f7b951a8SRobert Watson 
3013f7b951a8SRobert Watson 	return (error);
301495fab37eSRobert Watson }
301595fab37eSRobert Watson 
301695fab37eSRobert Watson int
301795fab37eSRobert Watson mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
301895fab37eSRobert Watson     struct ifnet *ifnet)
301995fab37eSRobert Watson {
302095fab37eSRobert Watson 	struct label intlabel;
3021f7b951a8SRobert Watson 	struct mac mac;
3022f7b951a8SRobert Watson 	char *buffer;
302395fab37eSRobert Watson 	int error;
302495fab37eSRobert Watson 
3025f7b951a8SRobert Watson 	error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
302695fab37eSRobert Watson 	if (error)
302795fab37eSRobert Watson 		return (error);
302895fab37eSRobert Watson 
3029f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
303095fab37eSRobert Watson 	if (error)
303195fab37eSRobert Watson 		return (error);
303295fab37eSRobert Watson 
3033a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3034f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
3035f7b951a8SRobert Watson 	if (error) {
3036f7b951a8SRobert Watson 		free(buffer, M_MACTEMP);
3037f7b951a8SRobert Watson 		return (error);
3038f7b951a8SRobert Watson 	}
3039f7b951a8SRobert Watson 
3040f7b951a8SRobert Watson 	mac_init_ifnet_label(&intlabel);
3041f7b951a8SRobert Watson 	error = mac_internalize_ifnet_label(&intlabel, buffer);
3042f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3043f7b951a8SRobert Watson 	if (error) {
3044f7b951a8SRobert Watson 		mac_destroy_ifnet_label(&intlabel);
3045f7b951a8SRobert Watson 		return (error);
3046f7b951a8SRobert Watson 	}
3047f7b951a8SRobert Watson 
304895fab37eSRobert Watson 	/*
304995fab37eSRobert Watson 	 * XXX: Note that this is a redundant privilege check, since
305095fab37eSRobert Watson 	 * policies impose this check themselves if required by the
305195fab37eSRobert Watson 	 * policy.  Eventually, this should go away.
305295fab37eSRobert Watson 	 */
305395fab37eSRobert Watson 	error = suser_cred(cred, 0);
3054f7b951a8SRobert Watson 	if (error) {
3055f7b951a8SRobert Watson 		mac_destroy_ifnet_label(&intlabel);
3056f7b951a8SRobert Watson 		return (error);
3057f7b951a8SRobert Watson 	}
305895fab37eSRobert Watson 
305995fab37eSRobert Watson 	MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label,
306095fab37eSRobert Watson 	    &intlabel);
3061f7b951a8SRobert Watson 	if (error) {
3062f7b951a8SRobert Watson 		mac_destroy_ifnet_label(&intlabel);
3063f7b951a8SRobert Watson 		return (error);
3064f7b951a8SRobert Watson 	}
306595fab37eSRobert Watson 
306695fab37eSRobert Watson 	MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel);
306795fab37eSRobert Watson 
3068f7b951a8SRobert Watson 	mac_destroy_ifnet_label(&intlabel);
3069f7b951a8SRobert Watson 	return (0);
307095fab37eSRobert Watson }
307195fab37eSRobert Watson 
307295fab37eSRobert Watson void
3073990b4b2dSRobert Watson mac_create_devfs_device(struct mount *mp, dev_t dev, struct devfs_dirent *de)
307495fab37eSRobert Watson {
307595fab37eSRobert Watson 
3076990b4b2dSRobert Watson 	MAC_PERFORM(create_devfs_device, mp, dev, de, &de->de_label);
307795fab37eSRobert Watson }
307895fab37eSRobert Watson 
307974e62b1bSRobert Watson void
3080990b4b2dSRobert Watson mac_create_devfs_symlink(struct ucred *cred, struct mount *mp,
3081990b4b2dSRobert Watson     struct devfs_dirent *dd, struct devfs_dirent *de)
308274e62b1bSRobert Watson {
308374e62b1bSRobert Watson 
3084990b4b2dSRobert Watson 	MAC_PERFORM(create_devfs_symlink, cred, mp, dd, &dd->de_label, de,
308574e62b1bSRobert Watson 	    &de->de_label);
308674e62b1bSRobert Watson }
308774e62b1bSRobert Watson 
308895fab37eSRobert Watson void
3089990b4b2dSRobert Watson mac_create_devfs_directory(struct mount *mp, char *dirname, int dirnamelen,
309095fab37eSRobert Watson     struct devfs_dirent *de)
309195fab37eSRobert Watson {
309295fab37eSRobert Watson 
3093990b4b2dSRobert Watson 	MAC_PERFORM(create_devfs_directory, mp, dirname, dirnamelen, de,
309495fab37eSRobert Watson 	    &de->de_label);
309595fab37eSRobert Watson }
309695fab37eSRobert Watson 
309795fab37eSRobert Watson int
309895fab37eSRobert Watson mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
3099f7b951a8SRobert Watson     struct mac *mac)
310095fab37eSRobert Watson {
310195fab37eSRobert Watson 	struct label intlabel;
3102f7b951a8SRobert Watson 	char *buffer;
310395fab37eSRobert Watson 	int error;
310495fab37eSRobert Watson 
3105f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(mac);
310695fab37eSRobert Watson 	if (error)
310795fab37eSRobert Watson 		return (error);
310895fab37eSRobert Watson 
3109a163d034SWarner Losh 	buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
3110f7b951a8SRobert Watson 	error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL);
3111f7b951a8SRobert Watson 	if (error) {
3112f7b951a8SRobert Watson 		free(buffer, M_MACTEMP);
3113f7b951a8SRobert Watson 		return (error);
3114f7b951a8SRobert Watson 	}
3115f7b951a8SRobert Watson 
3116a163d034SWarner Losh 	mac_init_socket_label(&intlabel, M_WAITOK);
3117f7b951a8SRobert Watson 	error = mac_internalize_socket_label(&intlabel, buffer);
3118f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3119f7b951a8SRobert Watson 	if (error) {
3120f7b951a8SRobert Watson 		mac_destroy_socket_label(&intlabel);
3121f7b951a8SRobert Watson 		return (error);
3122f7b951a8SRobert Watson 	}
3123f7b951a8SRobert Watson 
312495fab37eSRobert Watson 	mac_check_socket_relabel(cred, so, &intlabel);
312595fab37eSRobert Watson 	if (error) {
3126f7b951a8SRobert Watson 		mac_destroy_socket_label(&intlabel);
312795fab37eSRobert Watson 		return (error);
312895fab37eSRobert Watson 	}
312995fab37eSRobert Watson 
313095fab37eSRobert Watson 	mac_relabel_socket(cred, so, &intlabel);
313195fab37eSRobert Watson 
3132f7b951a8SRobert Watson 	mac_destroy_socket_label(&intlabel);
313395fab37eSRobert Watson 	return (0);
313495fab37eSRobert Watson }
313595fab37eSRobert Watson 
313695fab37eSRobert Watson int
313795fab37eSRobert Watson mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label)
313895fab37eSRobert Watson {
313995fab37eSRobert Watson 	int error;
314095fab37eSRobert Watson 
31411aa37f53SRobert Watson 	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
31421aa37f53SRobert Watson 
314395fab37eSRobert Watson 	error = mac_check_pipe_relabel(cred, pipe, label);
314495fab37eSRobert Watson 	if (error)
314595fab37eSRobert Watson 		return (error);
314695fab37eSRobert Watson 
314795fab37eSRobert Watson 	mac_relabel_pipe(cred, pipe, label);
314895fab37eSRobert Watson 
314995fab37eSRobert Watson 	return (0);
315095fab37eSRobert Watson }
315195fab37eSRobert Watson 
315295fab37eSRobert Watson int
315395fab37eSRobert Watson mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
3154f7b951a8SRobert Watson     struct mac *mac)
315595fab37eSRobert Watson {
3156f7b951a8SRobert Watson 	char *buffer, *elements;
3157f7b951a8SRobert Watson 	int error;
315895fab37eSRobert Watson 
3159f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(mac);
3160f7b951a8SRobert Watson 	if (error)
3161f7b951a8SRobert Watson 		return (error);
3162f7b951a8SRobert Watson 
3163a163d034SWarner Losh 	elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
3164f7b951a8SRobert Watson 	error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
3165f7b951a8SRobert Watson 	if (error) {
3166f7b951a8SRobert Watson 		free(elements, M_MACTEMP);
3167f7b951a8SRobert Watson 		return (error);
3168f7b951a8SRobert Watson 	}
3169f7b951a8SRobert Watson 
3170a163d034SWarner Losh 	buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3171f7b951a8SRobert Watson 	error = mac_externalize_socket_label(&so->so_label, elements,
3172a163d034SWarner Losh 	    buffer, mac->m_buflen, M_WAITOK);
3173f7b951a8SRobert Watson 	if (error == 0)
3174f7b951a8SRobert Watson 		error = copyout(buffer, mac->m_string, strlen(buffer)+1);
3175f7b951a8SRobert Watson 
3176f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3177f7b951a8SRobert Watson 	free(elements, M_MACTEMP);
3178f7b951a8SRobert Watson 
3179f7b951a8SRobert Watson 	return (error);
318095fab37eSRobert Watson }
318195fab37eSRobert Watson 
318295fab37eSRobert Watson int
318395fab37eSRobert Watson mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
3184f7b951a8SRobert Watson     struct mac *mac)
318595fab37eSRobert Watson {
3186f7b951a8SRobert Watson 	char *elements, *buffer;
3187f7b951a8SRobert Watson 	int error;
318895fab37eSRobert Watson 
3189f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(mac);
3190f7b951a8SRobert Watson 	if (error)
3191f7b951a8SRobert Watson 		return (error);
3192f7b951a8SRobert Watson 
3193a163d034SWarner Losh 	elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
3194f7b951a8SRobert Watson 	error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
3195f7b951a8SRobert Watson 	if (error) {
3196f7b951a8SRobert Watson 		free(elements, M_MACTEMP);
3197f7b951a8SRobert Watson 		return (error);
3198f7b951a8SRobert Watson 	}
3199f7b951a8SRobert Watson 
3200a163d034SWarner Losh 	buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3201f7b951a8SRobert Watson 	error = mac_externalize_socket_peer_label(&so->so_peerlabel,
3202a163d034SWarner Losh 	    elements, buffer, mac->m_buflen, M_WAITOK);
3203f7b951a8SRobert Watson 	if (error == 0)
3204f7b951a8SRobert Watson 		error = copyout(buffer, mac->m_string, strlen(buffer)+1);
3205f7b951a8SRobert Watson 
3206f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3207f7b951a8SRobert Watson 	free(elements, M_MACTEMP);
3208f7b951a8SRobert Watson 
3209f7b951a8SRobert Watson 	return (error);
321095fab37eSRobert Watson }
321195fab37eSRobert Watson 
321295fab37eSRobert Watson /*
321395fab37eSRobert Watson  * Implementation of VOP_SETLABEL() that relies on extended attributes
321495fab37eSRobert Watson  * to store label data.  Can be referenced by filesystems supporting
321595fab37eSRobert Watson  * extended attributes.
321695fab37eSRobert Watson  */
321795fab37eSRobert Watson int
321895fab37eSRobert Watson vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
321995fab37eSRobert Watson {
322095fab37eSRobert Watson 	struct vnode *vp = ap->a_vp;
322195fab37eSRobert Watson 	struct label *intlabel = ap->a_label;
322295fab37eSRobert Watson 	int error;
322395fab37eSRobert Watson 
322495fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
322595fab37eSRobert Watson 
3226763bbd2fSRobert Watson 	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
3227763bbd2fSRobert Watson 		return (EOPNOTSUPP);
322895fab37eSRobert Watson 
3229763bbd2fSRobert Watson 	error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel);
323095fab37eSRobert Watson 	if (error)
323195fab37eSRobert Watson 		return (error);
323295fab37eSRobert Watson 
323395fab37eSRobert Watson 	mac_relabel_vnode(ap->a_cred, vp, intlabel);
323495fab37eSRobert Watson 
323595fab37eSRobert Watson 	return (0);
323695fab37eSRobert Watson }
323795fab37eSRobert Watson 
323895fab37eSRobert Watson static int
323995fab37eSRobert Watson vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred)
324095fab37eSRobert Watson {
324195fab37eSRobert Watson 	int error;
324295fab37eSRobert Watson 
324395fab37eSRobert Watson 	if (vp->v_mount == NULL) {
324495fab37eSRobert Watson 		/* printf("vn_setlabel: null v_mount\n"); */
324506be2aaaSNate Lawson 		if (vp->v_type != VNON)
324606be2aaaSNate Lawson 			printf("vn_setlabel: null v_mount with non-VNON\n");
324795fab37eSRobert Watson 		return (EBADF);
324895fab37eSRobert Watson 	}
324995fab37eSRobert Watson 
325095fab37eSRobert Watson 	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
325195fab37eSRobert Watson 		return (EOPNOTSUPP);
325295fab37eSRobert Watson 
325395fab37eSRobert Watson 	/*
325495fab37eSRobert Watson 	 * Multi-phase commit.  First check the policies to confirm the
325595fab37eSRobert Watson 	 * change is OK.  Then commit via the filesystem.  Finally,
325695fab37eSRobert Watson 	 * update the actual vnode label.  Question: maybe the filesystem
325795fab37eSRobert Watson 	 * should update the vnode at the end as part of VOP_SETLABEL()?
325895fab37eSRobert Watson 	 */
325995fab37eSRobert Watson 	error = mac_check_vnode_relabel(cred, vp, intlabel);
326095fab37eSRobert Watson 	if (error)
326195fab37eSRobert Watson 		return (error);
326295fab37eSRobert Watson 
326395fab37eSRobert Watson 	/*
326495fab37eSRobert Watson 	 * VADMIN provides the opportunity for the filesystem to make
326595fab37eSRobert Watson 	 * decisions about who is and is not able to modify labels
326695fab37eSRobert Watson 	 * and protections on files.  This might not be right.  We can't
326795fab37eSRobert Watson 	 * assume VOP_SETLABEL() will do it, because we might implement
326895fab37eSRobert Watson 	 * that as part of vop_stdsetlabel_ea().
326995fab37eSRobert Watson 	 */
327095fab37eSRobert Watson 	error = VOP_ACCESS(vp, VADMIN, cred, curthread);
327195fab37eSRobert Watson 	if (error)
327295fab37eSRobert Watson 		return (error);
327395fab37eSRobert Watson 
327495fab37eSRobert Watson 	error = VOP_SETLABEL(vp, intlabel, cred, curthread);
327595fab37eSRobert Watson 	if (error)
327695fab37eSRobert Watson 		return (error);
327795fab37eSRobert Watson 
327895fab37eSRobert Watson 	return (0);
327995fab37eSRobert Watson }
328095fab37eSRobert Watson 
3281f7b951a8SRobert Watson int
3282f7b951a8SRobert Watson __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
3283f7b951a8SRobert Watson {
3284f7b951a8SRobert Watson 	char *elements, *buffer;
3285f7b951a8SRobert Watson 	struct mac mac;
3286f7b951a8SRobert Watson 	struct proc *tproc;
3287f7b951a8SRobert Watson 	struct ucred *tcred;
3288f7b951a8SRobert Watson 	int error;
3289f7b951a8SRobert Watson 
3290d1e405c5SAlfred Perlstein 	error = copyin(uap->mac_p, &mac, sizeof(mac));
3291f7b951a8SRobert Watson 	if (error)
3292f7b951a8SRobert Watson 		return (error);
3293f7b951a8SRobert Watson 
3294f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
3295f7b951a8SRobert Watson 	if (error)
3296f7b951a8SRobert Watson 		return (error);
3297f7b951a8SRobert Watson 
3298f7b951a8SRobert Watson 	tproc = pfind(uap->pid);
3299f7b951a8SRobert Watson 	if (tproc == NULL)
3300f7b951a8SRobert Watson 		return (ESRCH);
3301f7b951a8SRobert Watson 
3302f7b951a8SRobert Watson 	tcred = NULL;				/* Satisfy gcc. */
3303f7b951a8SRobert Watson 	error = p_cansee(td, tproc);
3304f7b951a8SRobert Watson 	if (error == 0)
3305f7b951a8SRobert Watson 		tcred = crhold(tproc->p_ucred);
3306f7b951a8SRobert Watson 	PROC_UNLOCK(tproc);
3307f7b951a8SRobert Watson 	if (error)
3308f7b951a8SRobert Watson 		return (error);
3309f7b951a8SRobert Watson 
3310a163d034SWarner Losh 	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3311f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
3312f7b951a8SRobert Watson 	if (error) {
3313f7b951a8SRobert Watson 		free(elements, M_MACTEMP);
3314f7b951a8SRobert Watson 		crfree(tcred);
3315f7b951a8SRobert Watson 		return (error);
3316f7b951a8SRobert Watson 	}
3317f7b951a8SRobert Watson 
3318a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3319f7b951a8SRobert Watson 	error = mac_externalize_cred_label(&tcred->cr_label, elements,
3320a163d034SWarner Losh 	    buffer, mac.m_buflen, M_WAITOK);
3321f7b951a8SRobert Watson 	if (error == 0)
3322f7b951a8SRobert Watson 		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
3323f7b951a8SRobert Watson 
3324f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3325f7b951a8SRobert Watson 	free(elements, M_MACTEMP);
3326f7b951a8SRobert Watson 	crfree(tcred);
3327f7b951a8SRobert Watson 	return (error);
3328f7b951a8SRobert Watson }
3329f7b951a8SRobert Watson 
333095fab37eSRobert Watson /*
333195fab37eSRobert Watson  * MPSAFE
333295fab37eSRobert Watson  */
333395fab37eSRobert Watson int
333495fab37eSRobert Watson __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
333595fab37eSRobert Watson {
3336f7b951a8SRobert Watson 	char *elements, *buffer;
3337f7b951a8SRobert Watson 	struct mac mac;
333895fab37eSRobert Watson 	int error;
333995fab37eSRobert Watson 
3340f7b951a8SRobert Watson 	error = copyin(uap->mac_p, &mac, sizeof(mac));
3341f7b951a8SRobert Watson 	if (error)
3342f7b951a8SRobert Watson 		return (error);
334395fab37eSRobert Watson 
3344f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
3345f7b951a8SRobert Watson 	if (error)
3346f7b951a8SRobert Watson 		return (error);
3347f7b951a8SRobert Watson 
3348a163d034SWarner Losh 	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3349f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
3350f7b951a8SRobert Watson 	if (error) {
3351f7b951a8SRobert Watson 		free(elements, M_MACTEMP);
3352f7b951a8SRobert Watson 		return (error);
3353f7b951a8SRobert Watson 	}
3354f7b951a8SRobert Watson 
3355a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3356f7b951a8SRobert Watson 	error = mac_externalize_cred_label(&td->td_ucred->cr_label,
3357a163d034SWarner Losh 	    elements, buffer, mac.m_buflen, M_WAITOK);
3358f7b951a8SRobert Watson 	if (error == 0)
3359f7b951a8SRobert Watson 		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
3360f7b951a8SRobert Watson 
3361f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3362f7b951a8SRobert Watson 	free(elements, M_MACTEMP);
336395fab37eSRobert Watson 	return (error);
336495fab37eSRobert Watson }
336595fab37eSRobert Watson 
336695fab37eSRobert Watson /*
336795fab37eSRobert Watson  * MPSAFE
336895fab37eSRobert Watson  */
336995fab37eSRobert Watson int
337095fab37eSRobert Watson __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
337195fab37eSRobert Watson {
337295fab37eSRobert Watson 	struct ucred *newcred, *oldcred;
337395fab37eSRobert Watson 	struct label intlabel;
3374f7b951a8SRobert Watson 	struct proc *p;
3375f7b951a8SRobert Watson 	struct mac mac;
3376f7b951a8SRobert Watson 	char *buffer;
337795fab37eSRobert Watson 	int error;
337895fab37eSRobert Watson 
3379f7b951a8SRobert Watson 	error = copyin(uap->mac_p, &mac, sizeof(mac));
338095fab37eSRobert Watson 	if (error)
338195fab37eSRobert Watson 		return (error);
338295fab37eSRobert Watson 
3383f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
338495fab37eSRobert Watson 	if (error)
338595fab37eSRobert Watson 		return (error);
338695fab37eSRobert Watson 
3387a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3388f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
3389f7b951a8SRobert Watson 	if (error) {
3390f7b951a8SRobert Watson 		free(buffer, M_MACTEMP);
3391f7b951a8SRobert Watson 		return (error);
3392f7b951a8SRobert Watson 	}
3393f7b951a8SRobert Watson 
3394f7b951a8SRobert Watson 	mac_init_cred_label(&intlabel);
3395f7b951a8SRobert Watson 	error = mac_internalize_cred_label(&intlabel, buffer);
3396f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3397f7b951a8SRobert Watson 	if (error) {
3398f7b951a8SRobert Watson 		mac_destroy_cred_label(&intlabel);
3399f7b951a8SRobert Watson 		return (error);
3400f7b951a8SRobert Watson 	}
3401f7b951a8SRobert Watson 
340295fab37eSRobert Watson 	newcred = crget();
340395fab37eSRobert Watson 
340495fab37eSRobert Watson 	p = td->td_proc;
340595fab37eSRobert Watson 	PROC_LOCK(p);
340695fab37eSRobert Watson 	oldcred = p->p_ucred;
340795fab37eSRobert Watson 
340895fab37eSRobert Watson 	error = mac_check_cred_relabel(oldcred, &intlabel);
340995fab37eSRobert Watson 	if (error) {
341095fab37eSRobert Watson 		PROC_UNLOCK(p);
341195fab37eSRobert Watson 		crfree(newcred);
3412f7b951a8SRobert Watson 		goto out;
341395fab37eSRobert Watson 	}
341495fab37eSRobert Watson 
341595fab37eSRobert Watson 	setsugid(p);
341695fab37eSRobert Watson 	crcopy(newcred, oldcred);
341795fab37eSRobert Watson 	mac_relabel_cred(newcred, &intlabel);
341895fab37eSRobert Watson 	p->p_ucred = newcred;
3419e5cb5e37SRobert Watson 
3420e5cb5e37SRobert Watson 	/*
3421e5cb5e37SRobert Watson 	 * Grab additional reference for use while revoking mmaps, prior
3422e5cb5e37SRobert Watson 	 * to releasing the proc lock and sharing the cred.
3423e5cb5e37SRobert Watson 	 */
3424e5cb5e37SRobert Watson 	crhold(newcred);
342595fab37eSRobert Watson 	PROC_UNLOCK(p);
3426e5cb5e37SRobert Watson 
3427f7b951a8SRobert Watson 	if (mac_enforce_vm) {
342816140035SRobert Watson 		mtx_lock(&Giant);
3429e5cb5e37SRobert Watson 		mac_cred_mmapped_drop_perms(td, newcred);
343016140035SRobert Watson 		mtx_unlock(&Giant);
3431f7b951a8SRobert Watson 	}
3432e5cb5e37SRobert Watson 
3433e5cb5e37SRobert Watson 	crfree(newcred);	/* Free revocation reference. */
343495fab37eSRobert Watson 	crfree(oldcred);
3435f7b951a8SRobert Watson 
3436f7b951a8SRobert Watson out:
3437f7b951a8SRobert Watson 	mac_destroy_cred_label(&intlabel);
3438f7b951a8SRobert Watson 	return (error);
343995fab37eSRobert Watson }
344095fab37eSRobert Watson 
344195fab37eSRobert Watson /*
344295fab37eSRobert Watson  * MPSAFE
344395fab37eSRobert Watson  */
344495fab37eSRobert Watson int
344595fab37eSRobert Watson __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
344695fab37eSRobert Watson {
3447f7b951a8SRobert Watson 	char *elements, *buffer;
3448f7b951a8SRobert Watson 	struct label intlabel;
344995fab37eSRobert Watson 	struct file *fp;
3450f7b951a8SRobert Watson 	struct mac mac;
345195fab37eSRobert Watson 	struct vnode *vp;
345295fab37eSRobert Watson 	struct pipe *pipe;
3453f7b951a8SRobert Watson 	short label_type;
345495fab37eSRobert Watson 	int error;
345595fab37eSRobert Watson 
3456f7b951a8SRobert Watson 	error = copyin(uap->mac_p, &mac, sizeof(mac));
3457f7b951a8SRobert Watson 	if (error)
3458f7b951a8SRobert Watson 		return (error);
345995fab37eSRobert Watson 
3460f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
3461f7b951a8SRobert Watson 	if (error)
3462f7b951a8SRobert Watson 		return (error);
3463f7b951a8SRobert Watson 
3464a163d034SWarner Losh 	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3465f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
3466f7b951a8SRobert Watson 	if (error) {
3467f7b951a8SRobert Watson 		free(elements, M_MACTEMP);
3468f7b951a8SRobert Watson 		return (error);
3469f7b951a8SRobert Watson 	}
3470f7b951a8SRobert Watson 
3471a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3472f7b951a8SRobert Watson 	mtx_lock(&Giant);				/* VFS */
3473d1e405c5SAlfred Perlstein 	error = fget(td, uap->fd, &fp);
347495fab37eSRobert Watson 	if (error)
347595fab37eSRobert Watson 		goto out;
347695fab37eSRobert Watson 
3477f7b951a8SRobert Watson 	label_type = fp->f_type;
347895fab37eSRobert Watson 	switch (fp->f_type) {
347995fab37eSRobert Watson 	case DTYPE_FIFO:
348095fab37eSRobert Watson 	case DTYPE_VNODE:
34813b6d9652SPoul-Henning Kamp 		vp = fp->f_vnode;
348295fab37eSRobert Watson 
3483f7b951a8SRobert Watson 		mac_init_vnode_label(&intlabel);
3484f7b951a8SRobert Watson 
348595fab37eSRobert Watson 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3486f7b951a8SRobert Watson 		mac_copy_vnode_label(&vp->v_label, &intlabel);
348795fab37eSRobert Watson 		VOP_UNLOCK(vp, 0, td);
3488f7b951a8SRobert Watson 
348995fab37eSRobert Watson 		break;
349095fab37eSRobert Watson 	case DTYPE_PIPE:
349148e3128bSMatthew Dillon 		pipe = fp->f_data;
3492f7b951a8SRobert Watson 
3493f7b951a8SRobert Watson 		mac_init_pipe_label(&intlabel);
3494f7b951a8SRobert Watson 
3495f7b951a8SRobert Watson 		PIPE_LOCK(pipe);
3496f7b951a8SRobert Watson 		mac_copy_pipe_label(pipe->pipe_label, &intlabel);
3497f7b951a8SRobert Watson 		PIPE_UNLOCK(pipe);
349895fab37eSRobert Watson 		break;
349995fab37eSRobert Watson 	default:
350095fab37eSRobert Watson 		error = EINVAL;
3501f7b951a8SRobert Watson 		fdrop(fp, td);
3502f7b951a8SRobert Watson 		goto out;
3503f7b951a8SRobert Watson 	}
3504f7b951a8SRobert Watson 	fdrop(fp, td);
3505f7b951a8SRobert Watson 
3506f7b951a8SRobert Watson 	switch (label_type) {
3507f7b951a8SRobert Watson 	case DTYPE_FIFO:
3508f7b951a8SRobert Watson 	case DTYPE_VNODE:
3509f7b951a8SRobert Watson 		if (error == 0)
3510f7b951a8SRobert Watson 			error = mac_externalize_vnode_label(&intlabel,
3511a163d034SWarner Losh 			    elements, buffer, mac.m_buflen, M_WAITOK);
3512f7b951a8SRobert Watson 		mac_destroy_vnode_label(&intlabel);
3513f7b951a8SRobert Watson 		break;
3514f7b951a8SRobert Watson 	case DTYPE_PIPE:
3515f7b951a8SRobert Watson 		error = mac_externalize_pipe_label(&intlabel, elements,
3516a163d034SWarner Losh 		    buffer, mac.m_buflen, M_WAITOK);
3517f7b951a8SRobert Watson 		mac_destroy_pipe_label(&intlabel);
3518f7b951a8SRobert Watson 		break;
3519f7b951a8SRobert Watson 	default:
3520f7b951a8SRobert Watson 		panic("__mac_get_fd: corrupted label_type");
352195fab37eSRobert Watson 	}
352295fab37eSRobert Watson 
352395fab37eSRobert Watson 	if (error == 0)
3524f7b951a8SRobert Watson 		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
352595fab37eSRobert Watson 
352695fab37eSRobert Watson out:
3527f7b951a8SRobert Watson 	mtx_unlock(&Giant);				/* VFS */
3528f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3529f7b951a8SRobert Watson 	free(elements, M_MACTEMP);
3530f7b951a8SRobert Watson 
353195fab37eSRobert Watson 	return (error);
353295fab37eSRobert Watson }
353395fab37eSRobert Watson 
353495fab37eSRobert Watson /*
353595fab37eSRobert Watson  * MPSAFE
353695fab37eSRobert Watson  */
353795fab37eSRobert Watson int
353895fab37eSRobert Watson __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
353995fab37eSRobert Watson {
3540f7b951a8SRobert Watson 	char *elements, *buffer;
354195fab37eSRobert Watson 	struct nameidata nd;
3542f7b951a8SRobert Watson 	struct label intlabel;
3543f7b951a8SRobert Watson 	struct mac mac;
354495fab37eSRobert Watson 	int error;
354595fab37eSRobert Watson 
3546f7b951a8SRobert Watson 	error = copyin(uap->mac_p, &mac, sizeof(mac));
3547f7b951a8SRobert Watson 	if (error)
3548f7b951a8SRobert Watson 		return (error);
3549f7b951a8SRobert Watson 
3550f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
3551f7b951a8SRobert Watson 	if (error)
3552f7b951a8SRobert Watson 		return (error);
3553f7b951a8SRobert Watson 
3554a163d034SWarner Losh 	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3555f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
3556f7b951a8SRobert Watson 	if (error) {
3557f7b951a8SRobert Watson 		free(elements, M_MACTEMP);
3558f7b951a8SRobert Watson 		return (error);
3559f7b951a8SRobert Watson 	}
3560f7b951a8SRobert Watson 
3561a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3562f7b951a8SRobert Watson 	mtx_lock(&Giant);				/* VFS */
3563f7b951a8SRobert Watson 	NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p,
3564f7b951a8SRobert Watson 	    td);
356595fab37eSRobert Watson 	error = namei(&nd);
356695fab37eSRobert Watson 	if (error)
356795fab37eSRobert Watson 		goto out;
356895fab37eSRobert Watson 
3569f7b951a8SRobert Watson 	mac_init_vnode_label(&intlabel);
3570f7b951a8SRobert Watson 	mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
3571763bbd2fSRobert Watson 	error = mac_externalize_vnode_label(&intlabel, elements, buffer,
3572a163d034SWarner Losh 	    mac.m_buflen, M_WAITOK);
3573f7b951a8SRobert Watson 
357495fab37eSRobert Watson 	NDFREE(&nd, 0);
3575f7b951a8SRobert Watson 	mac_destroy_vnode_label(&intlabel);
3576f7b951a8SRobert Watson 
3577f7b951a8SRobert Watson 	if (error == 0)
3578f7b951a8SRobert Watson 		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
3579f7b951a8SRobert Watson 
3580f7b951a8SRobert Watson out:
3581f7b951a8SRobert Watson 	mtx_unlock(&Giant);				/* VFS */
3582f7b951a8SRobert Watson 
3583f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3584f7b951a8SRobert Watson 	free(elements, M_MACTEMP);
3585f7b951a8SRobert Watson 
3586f7b951a8SRobert Watson 	return (error);
3587f7b951a8SRobert Watson }
3588f7b951a8SRobert Watson 
3589f7b951a8SRobert Watson /*
3590f7b951a8SRobert Watson  * MPSAFE
3591f7b951a8SRobert Watson  */
3592f7b951a8SRobert Watson int
3593f7b951a8SRobert Watson __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
3594f7b951a8SRobert Watson {
3595f7b951a8SRobert Watson 	char *elements, *buffer;
3596f7b951a8SRobert Watson 	struct nameidata nd;
3597f7b951a8SRobert Watson 	struct label intlabel;
3598f7b951a8SRobert Watson 	struct mac mac;
3599f7b951a8SRobert Watson 	int error;
3600f7b951a8SRobert Watson 
3601f7b951a8SRobert Watson 	error = copyin(uap->mac_p, &mac, sizeof(mac));
3602f7b951a8SRobert Watson 	if (error)
3603f7b951a8SRobert Watson 		return (error);
3604f7b951a8SRobert Watson 
3605f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
3606f7b951a8SRobert Watson 	if (error)
3607f7b951a8SRobert Watson 		return (error);
3608f7b951a8SRobert Watson 
3609a163d034SWarner Losh 	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3610f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
3611f7b951a8SRobert Watson 	if (error) {
3612f7b951a8SRobert Watson 		free(elements, M_MACTEMP);
3613f7b951a8SRobert Watson 		return (error);
3614f7b951a8SRobert Watson 	}
3615f7b951a8SRobert Watson 
3616a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3617f7b951a8SRobert Watson 	mtx_lock(&Giant);				/* VFS */
3618f7b951a8SRobert Watson 	NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p,
3619f7b951a8SRobert Watson 	    td);
3620f7b951a8SRobert Watson 	error = namei(&nd);
362195fab37eSRobert Watson 	if (error)
362295fab37eSRobert Watson 		goto out;
362395fab37eSRobert Watson 
3624f7b951a8SRobert Watson 	mac_init_vnode_label(&intlabel);
3625f7b951a8SRobert Watson 	mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
3626763bbd2fSRobert Watson 	error = mac_externalize_vnode_label(&intlabel, elements, buffer,
3627a163d034SWarner Losh 	    mac.m_buflen, M_WAITOK);
3628f7b951a8SRobert Watson 	NDFREE(&nd, 0);
3629f7b951a8SRobert Watson 	mac_destroy_vnode_label(&intlabel);
3630f7b951a8SRobert Watson 
3631f7b951a8SRobert Watson 	if (error == 0)
3632f7b951a8SRobert Watson 		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
363395fab37eSRobert Watson 
363495fab37eSRobert Watson out:
3635f7b951a8SRobert Watson 	mtx_unlock(&Giant);				/* VFS */
3636f7b951a8SRobert Watson 
3637f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3638f7b951a8SRobert Watson 	free(elements, M_MACTEMP);
3639f7b951a8SRobert Watson 
364095fab37eSRobert Watson 	return (error);
364195fab37eSRobert Watson }
364295fab37eSRobert Watson 
364395fab37eSRobert Watson /*
364495fab37eSRobert Watson  * MPSAFE
364595fab37eSRobert Watson  */
364695fab37eSRobert Watson int
364795fab37eSRobert Watson __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
364895fab37eSRobert Watson {
364995fab37eSRobert Watson 	struct label intlabel;
3650f7b951a8SRobert Watson 	struct pipe *pipe;
3651f7b951a8SRobert Watson 	struct file *fp;
365295fab37eSRobert Watson 	struct mount *mp;
365395fab37eSRobert Watson 	struct vnode *vp;
3654f7b951a8SRobert Watson 	struct mac mac;
3655f7b951a8SRobert Watson 	char *buffer;
365695fab37eSRobert Watson 	int error;
365795fab37eSRobert Watson 
3658f7b951a8SRobert Watson 	error = copyin(uap->mac_p, &mac, sizeof(mac));
3659f7b951a8SRobert Watson 	if (error)
3660f7b951a8SRobert Watson 		return (error);
3661f7b951a8SRobert Watson 
3662f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
3663f7b951a8SRobert Watson 	if (error)
3664f7b951a8SRobert Watson 		return (error);
3665f7b951a8SRobert Watson 
3666a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3667f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
3668f7b951a8SRobert Watson 	if (error) {
3669f7b951a8SRobert Watson 		free(buffer, M_MACTEMP);
3670f7b951a8SRobert Watson 		return (error);
3671f7b951a8SRobert Watson 	}
3672f7b951a8SRobert Watson 
3673f7b951a8SRobert Watson 	mtx_lock(&Giant);				/* VFS */
3674f7b951a8SRobert Watson 
3675d1e405c5SAlfred Perlstein 	error = fget(td, uap->fd, &fp);
367695fab37eSRobert Watson 	if (error)
3677f7b951a8SRobert Watson 		goto out;
367895fab37eSRobert Watson 
367995fab37eSRobert Watson 	switch (fp->f_type) {
368095fab37eSRobert Watson 	case DTYPE_FIFO:
368195fab37eSRobert Watson 	case DTYPE_VNODE:
3682f7b951a8SRobert Watson 		mac_init_vnode_label(&intlabel);
3683f7b951a8SRobert Watson 		error = mac_internalize_vnode_label(&intlabel, buffer);
3684f7b951a8SRobert Watson 		if (error) {
3685f7b951a8SRobert Watson 			mac_destroy_vnode_label(&intlabel);
3686f7b951a8SRobert Watson 			break;
3687f7b951a8SRobert Watson 		}
3688f7b951a8SRobert Watson 
36893b6d9652SPoul-Henning Kamp 		vp = fp->f_vnode;
369095fab37eSRobert Watson 		error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
3691f7b951a8SRobert Watson 		if (error != 0) {
3692f7b951a8SRobert Watson 			mac_destroy_vnode_label(&intlabel);
369395fab37eSRobert Watson 			break;
3694f7b951a8SRobert Watson 		}
369595fab37eSRobert Watson 
369695fab37eSRobert Watson 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
369795fab37eSRobert Watson 		error = vn_setlabel(vp, &intlabel, td->td_ucred);
369895fab37eSRobert Watson 		VOP_UNLOCK(vp, 0, td);
369995fab37eSRobert Watson 		vn_finished_write(mp);
3700f7b951a8SRobert Watson 
3701f7b951a8SRobert Watson 		mac_destroy_vnode_label(&intlabel);
370295fab37eSRobert Watson 		break;
3703f7b951a8SRobert Watson 
370495fab37eSRobert Watson 	case DTYPE_PIPE:
3705f7b951a8SRobert Watson 		mac_init_pipe_label(&intlabel);
3706f7b951a8SRobert Watson 		error = mac_internalize_pipe_label(&intlabel, buffer);
3707f7b951a8SRobert Watson 		if (error == 0) {
370848e3128bSMatthew Dillon 			pipe = fp->f_data;
37091aa37f53SRobert Watson 			PIPE_LOCK(pipe);
3710f7b951a8SRobert Watson 			error = mac_pipe_label_set(td->td_ucred, pipe,
3711f7b951a8SRobert Watson 			    &intlabel);
37121aa37f53SRobert Watson 			PIPE_UNLOCK(pipe);
3713f7b951a8SRobert Watson 		}
3714f7b951a8SRobert Watson 
3715f7b951a8SRobert Watson 		mac_destroy_pipe_label(&intlabel);
371695fab37eSRobert Watson 		break;
3717f7b951a8SRobert Watson 
371895fab37eSRobert Watson 	default:
371995fab37eSRobert Watson 		error = EINVAL;
372095fab37eSRobert Watson 	}
372195fab37eSRobert Watson 
372295fab37eSRobert Watson 	fdrop(fp, td);
3723f7b951a8SRobert Watson out:
3724f7b951a8SRobert Watson 	mtx_unlock(&Giant);				/* VFS */
3725f7b951a8SRobert Watson 
3726f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3727f7b951a8SRobert Watson 
372895fab37eSRobert Watson 	return (error);
372995fab37eSRobert Watson }
373095fab37eSRobert Watson 
373195fab37eSRobert Watson /*
373295fab37eSRobert Watson  * MPSAFE
373395fab37eSRobert Watson  */
373495fab37eSRobert Watson int
373595fab37eSRobert Watson __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
373695fab37eSRobert Watson {
373795fab37eSRobert Watson 	struct label intlabel;
3738f7b951a8SRobert Watson 	struct nameidata nd;
373995fab37eSRobert Watson 	struct mount *mp;
3740f7b951a8SRobert Watson 	struct mac mac;
3741f7b951a8SRobert Watson 	char *buffer;
374295fab37eSRobert Watson 	int error;
374395fab37eSRobert Watson 
3744f7b951a8SRobert Watson 	error = copyin(uap->mac_p, &mac, sizeof(mac));
374595fab37eSRobert Watson 	if (error)
3746f7b951a8SRobert Watson 		return (error);
374795fab37eSRobert Watson 
3748f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
374995fab37eSRobert Watson 	if (error)
3750f7b951a8SRobert Watson 		return (error);
375195fab37eSRobert Watson 
3752a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3753f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
3754f7b951a8SRobert Watson 	if (error) {
3755f7b951a8SRobert Watson 		free(buffer, M_MACTEMP);
375695fab37eSRobert Watson 		return (error);
375795fab37eSRobert Watson 	}
375895fab37eSRobert Watson 
3759f7b951a8SRobert Watson 	mac_init_vnode_label(&intlabel);
3760f7b951a8SRobert Watson 	error = mac_internalize_vnode_label(&intlabel, buffer);
3761f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3762f7b951a8SRobert Watson 	if (error) {
3763f7b951a8SRobert Watson 		mac_destroy_vnode_label(&intlabel);
3764f7b951a8SRobert Watson 		return (error);
3765f7b951a8SRobert Watson 	}
3766f7b951a8SRobert Watson 
3767f7b951a8SRobert Watson 	mtx_lock(&Giant);				/* VFS */
3768f7b951a8SRobert Watson 
3769f7b951a8SRobert Watson 	NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p,
3770f7b951a8SRobert Watson 	    td);
3771f7b951a8SRobert Watson 	error = namei(&nd);
3772f7b951a8SRobert Watson 	if (error == 0) {
3773f7b951a8SRobert Watson 		error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
3774f7b951a8SRobert Watson 		if (error == 0)
3775f7b951a8SRobert Watson 			error = vn_setlabel(nd.ni_vp, &intlabel,
3776f7b951a8SRobert Watson 			    td->td_ucred);
3777f7b951a8SRobert Watson 		vn_finished_write(mp);
3778f7b951a8SRobert Watson 	}
3779f7b951a8SRobert Watson 
3780f7b951a8SRobert Watson 	NDFREE(&nd, 0);
3781f7b951a8SRobert Watson 	mtx_unlock(&Giant);				/* VFS */
3782f7b951a8SRobert Watson 	mac_destroy_vnode_label(&intlabel);
3783f7b951a8SRobert Watson 
3784f7b951a8SRobert Watson 	return (error);
3785f7b951a8SRobert Watson }
3786f7b951a8SRobert Watson 
3787f7b951a8SRobert Watson /*
3788f7b951a8SRobert Watson  * MPSAFE
3789f7b951a8SRobert Watson  */
3790f7b951a8SRobert Watson int
3791f7b951a8SRobert Watson __mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
3792f7b951a8SRobert Watson {
3793f7b951a8SRobert Watson 	struct label intlabel;
3794f7b951a8SRobert Watson 	struct nameidata nd;
3795f7b951a8SRobert Watson 	struct mount *mp;
3796f7b951a8SRobert Watson 	struct mac mac;
3797f7b951a8SRobert Watson 	char *buffer;
3798f7b951a8SRobert Watson 	int error;
3799f7b951a8SRobert Watson 
3800f7b951a8SRobert Watson 	error = copyin(uap->mac_p, &mac, sizeof(mac));
3801f7b951a8SRobert Watson 	if (error)
3802f7b951a8SRobert Watson 		return (error);
3803f7b951a8SRobert Watson 
3804f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
3805f7b951a8SRobert Watson 	if (error)
3806f7b951a8SRobert Watson 		return (error);
3807f7b951a8SRobert Watson 
3808a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3809f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
3810f7b951a8SRobert Watson 	if (error) {
3811f7b951a8SRobert Watson 		free(buffer, M_MACTEMP);
3812f7b951a8SRobert Watson 		return (error);
3813f7b951a8SRobert Watson 	}
3814f7b951a8SRobert Watson 
3815f7b951a8SRobert Watson 	mac_init_vnode_label(&intlabel);
3816f7b951a8SRobert Watson 	error = mac_internalize_vnode_label(&intlabel, buffer);
3817f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3818f7b951a8SRobert Watson 	if (error) {
3819f7b951a8SRobert Watson 		mac_destroy_vnode_label(&intlabel);
3820f7b951a8SRobert Watson 		return (error);
3821f7b951a8SRobert Watson 	}
3822f7b951a8SRobert Watson 
3823f7b951a8SRobert Watson 	mtx_lock(&Giant);				/* VFS */
3824f7b951a8SRobert Watson 
3825f7b951a8SRobert Watson 	NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p,
3826f7b951a8SRobert Watson 	    td);
3827f7b951a8SRobert Watson 	error = namei(&nd);
3828f7b951a8SRobert Watson 	if (error == 0) {
3829f7b951a8SRobert Watson 		error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
3830f7b951a8SRobert Watson 		if (error == 0)
3831f7b951a8SRobert Watson 			error = vn_setlabel(nd.ni_vp, &intlabel,
3832f7b951a8SRobert Watson 			    td->td_ucred);
3833f7b951a8SRobert Watson 		vn_finished_write(mp);
3834f7b951a8SRobert Watson 	}
3835f7b951a8SRobert Watson 
3836f7b951a8SRobert Watson 	NDFREE(&nd, 0);
3837f7b951a8SRobert Watson 	mtx_unlock(&Giant);				/* VFS */
3838f7b951a8SRobert Watson 	mac_destroy_vnode_label(&intlabel);
3839f7b951a8SRobert Watson 
3840f7b951a8SRobert Watson 	return (error);
3841f7b951a8SRobert Watson }
3842f7b951a8SRobert Watson 
3843f7b951a8SRobert Watson /*
3844f7b951a8SRobert Watson  * MPSAFE
3845f7b951a8SRobert Watson  */
384627f2eac7SRobert Watson int
384727f2eac7SRobert Watson mac_syscall(struct thread *td, struct mac_syscall_args *uap)
384827f2eac7SRobert Watson {
384927f2eac7SRobert Watson 	struct mac_policy_conf *mpc;
385027f2eac7SRobert Watson 	char target[MAC_MAX_POLICY_NAME];
385141a17fe3SRobert Watson 	int entrycount, error;
385227f2eac7SRobert Watson 
3853d1e405c5SAlfred Perlstein 	error = copyinstr(uap->policy, target, sizeof(target), NULL);
385427f2eac7SRobert Watson 	if (error)
385527f2eac7SRobert Watson 		return (error);
385627f2eac7SRobert Watson 
385727f2eac7SRobert Watson 	error = ENOSYS;
3858a6a65b05SRobert Watson 	LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {
385927f2eac7SRobert Watson 		if (strcmp(mpc->mpc_name, target) == 0 &&
386027f2eac7SRobert Watson 		    mpc->mpc_ops->mpo_syscall != NULL) {
386127f2eac7SRobert Watson 			error = mpc->mpc_ops->mpo_syscall(td,
3862d1e405c5SAlfred Perlstein 			    uap->call, uap->arg);
386327f2eac7SRobert Watson 			goto out;
386427f2eac7SRobert Watson 		}
386527f2eac7SRobert Watson 	}
386627f2eac7SRobert Watson 
386741a17fe3SRobert Watson 	if ((entrycount = mac_policy_list_conditional_busy()) != 0) {
386841a17fe3SRobert Watson 		LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {
386941a17fe3SRobert Watson 			if (strcmp(mpc->mpc_name, target) == 0 &&
387041a17fe3SRobert Watson 			    mpc->mpc_ops->mpo_syscall != NULL) {
387141a17fe3SRobert Watson 				error = mpc->mpc_ops->mpo_syscall(td,
387241a17fe3SRobert Watson 				    uap->call, uap->arg);
387341a17fe3SRobert Watson 				break;
387441a17fe3SRobert Watson 			}
387541a17fe3SRobert Watson 		}
387641a17fe3SRobert Watson 		mac_policy_list_unbusy();
387741a17fe3SRobert Watson 	}
387827f2eac7SRobert Watson out:
387927f2eac7SRobert Watson 	return (error);
388027f2eac7SRobert Watson }
388127f2eac7SRobert Watson 
388295fab37eSRobert Watson SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL);
388395fab37eSRobert Watson SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL);
388495fab37eSRobert Watson 
388595fab37eSRobert Watson #else /* !MAC */
38867bc82500SRobert Watson 
38877bc82500SRobert Watson int
3888f7b951a8SRobert Watson __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
3889f7b951a8SRobert Watson {
3890f7b951a8SRobert Watson 
3891f7b951a8SRobert Watson 	return (ENOSYS);
3892f7b951a8SRobert Watson }
3893f7b951a8SRobert Watson 
3894f7b951a8SRobert Watson int
38957bc82500SRobert Watson __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
38967bc82500SRobert Watson {
38977bc82500SRobert Watson 
38987bc82500SRobert Watson 	return (ENOSYS);
38997bc82500SRobert Watson }
39007bc82500SRobert Watson 
39017bc82500SRobert Watson int
39027bc82500SRobert Watson __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
39037bc82500SRobert Watson {
39047bc82500SRobert Watson 
39057bc82500SRobert Watson 	return (ENOSYS);
39067bc82500SRobert Watson }
39077bc82500SRobert Watson 
39087bc82500SRobert Watson int
39097bc82500SRobert Watson __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
39107bc82500SRobert Watson {
39117bc82500SRobert Watson 
39127bc82500SRobert Watson 	return (ENOSYS);
39137bc82500SRobert Watson }
39147bc82500SRobert Watson 
39157bc82500SRobert Watson int
39167bc82500SRobert Watson __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
39177bc82500SRobert Watson {
39187bc82500SRobert Watson 
39197bc82500SRobert Watson 	return (ENOSYS);
39207bc82500SRobert Watson }
39217bc82500SRobert Watson 
39227bc82500SRobert Watson int
3923f7b951a8SRobert Watson __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
3924f7b951a8SRobert Watson {
3925f7b951a8SRobert Watson 
3926f7b951a8SRobert Watson 	return (ENOSYS);
3927f7b951a8SRobert Watson }
3928f7b951a8SRobert Watson 
3929f7b951a8SRobert Watson int
39307bc82500SRobert Watson __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
39317bc82500SRobert Watson {
39327bc82500SRobert Watson 
39337bc82500SRobert Watson 	return (ENOSYS);
39347bc82500SRobert Watson }
39357bc82500SRobert Watson 
39367bc82500SRobert Watson int
39377bc82500SRobert Watson __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
39387bc82500SRobert Watson {
39397bc82500SRobert Watson 
39407bc82500SRobert Watson 	return (ENOSYS);
39417bc82500SRobert Watson }
394295fab37eSRobert Watson 
394327f2eac7SRobert Watson int
3944f7b951a8SRobert Watson __mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
3945f7b951a8SRobert Watson {
3946f7b951a8SRobert Watson 
3947f7b951a8SRobert Watson 	return (ENOSYS);
3948f7b951a8SRobert Watson }
3949f7b951a8SRobert Watson 
3950f7b951a8SRobert Watson int
395127f2eac7SRobert Watson mac_syscall(struct thread *td, struct mac_syscall_args *uap)
395227f2eac7SRobert Watson {
395327f2eac7SRobert Watson 
395427f2eac7SRobert Watson 	return (ENOSYS);
395527f2eac7SRobert Watson }
395627f2eac7SRobert Watson 
3957f7b951a8SRobert Watson #endif
3958