xref: /freebsd/sys/security/mac/mac_framework.c (revision 089c1bdac97e551f3ade68c30c444cae6353dc38)
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  */
116089c1bdaSRobert Watson int	mac_late = 0;
117763bbd2fSRobert Watson 
118225bff6fSRobert Watson /*
119225bff6fSRobert Watson  * Flag to indicate whether or not we should allocate label storage for
120225bff6fSRobert Watson  * new mbufs.  Since most dynamic policies we currently work with don't
121225bff6fSRobert Watson  * rely on mbuf labeling, try to avoid paying the cost of mtag allocation
122225bff6fSRobert Watson  * unless specifically notified of interest.  One result of this is
123225bff6fSRobert Watson  * that if a dynamically loaded policy requests mbuf labels, it must
124225bff6fSRobert Watson  * be able to deal with a NULL label being returned on any mbufs that
125225bff6fSRobert Watson  * were already in flight when the policy was loaded.  Since the policy
126225bff6fSRobert Watson  * already has to deal with uninitialized labels, this probably won't
127225bff6fSRobert Watson  * be a problem.  Note: currently no locking.  Will this be a problem?
128225bff6fSRobert Watson  */
12919c3e120SRobert Watson #ifndef MAC_ALWAYS_LABEL_MBUF
130089c1bdaSRobert Watson int	mac_labelmbufs = 0;
131225bff6fSRobert Watson #endif
132225bff6fSRobert Watson 
13395fab37eSRobert Watson static int	mac_enforce_fs = 1;
13495fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
13595fab37eSRobert Watson     &mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
13695fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
13795fab37eSRobert Watson 
138a3df768bSRobert Watson static int	mac_enforce_kld = 1;
139a3df768bSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW,
140a3df768bSRobert Watson     &mac_enforce_kld, 0, "Enforce MAC policy on kld operations");
141a3df768bSRobert Watson TUNABLE_INT("security.mac.enforce_kld", &mac_enforce_kld);
142a3df768bSRobert Watson 
14395fab37eSRobert Watson static int	mac_enforce_network = 1;
14495fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
14595fab37eSRobert Watson     &mac_enforce_network, 0, "Enforce MAC policy on network packets");
14695fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_network", &mac_enforce_network);
14795fab37eSRobert Watson 
148b88c98f6SRobert Watson static int	mac_enforce_pipe = 1;
149b88c98f6SRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW,
150b88c98f6SRobert Watson     &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations");
151c031391bSRobert Watson TUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe);
152b88c98f6SRobert Watson 
15395fab37eSRobert Watson static int	mac_enforce_process = 1;
15495fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW,
15595fab37eSRobert Watson     &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations");
15695fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_process", &mac_enforce_process);
15795fab37eSRobert Watson 
15895fab37eSRobert Watson static int	mac_enforce_socket = 1;
15995fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
16095fab37eSRobert Watson     &mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
16195fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
16295fab37eSRobert Watson 
1639e913ebdSRobert Watson static int	mac_enforce_system = 1;
1649e913ebdSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_system, CTLFLAG_RW,
1659e913ebdSRobert Watson     &mac_enforce_system, 0, "Enforce MAC policy on system operations");
1669e913ebdSRobert Watson TUNABLE_INT("security.mac.enforce_system", &mac_enforce_system);
167d3fc69eeSRobert Watson 
168ca7850c3SRobert Watson static int	mac_enforce_vm = 1;
169ca7850c3SRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
170ca7850c3SRobert Watson     &mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
171c031391bSRobert Watson TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm);
172ca7850c3SRobert Watson 
173c0f39905SRobert Watson static int	mac_mmap_revocation = 1;
174c0f39905SRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW,
175c0f39905SRobert Watson     &mac_mmap_revocation, 0, "Revoke mmap access to files on subject "
176c0f39905SRobert Watson     "relabel");
17799fa64f8SRobert Watson static int	mac_mmap_revocation_via_cow = 0;
17895fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW,
17995fab37eSRobert Watson     &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via "
18095fab37eSRobert Watson     "copy-on-write semantics, or by removing all write access");
18195fab37eSRobert Watson 
182f050add5SRobert Watson #ifdef MAC_DEBUG
1836be0c25eSRobert Watson SYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0,
1846be0c25eSRobert Watson     "TrustedBSD MAC debug info");
1856be0c25eSRobert Watson 
1866be0c25eSRobert Watson static int	mac_debug_label_fallback = 0;
1876be0c25eSRobert Watson SYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW,
1886be0c25eSRobert Watson     &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label"
1896be0c25eSRobert Watson     "when label is corrupted.");
1906be0c25eSRobert Watson TUNABLE_INT("security.mac.debug_label_fallback",
1916be0c25eSRobert Watson     &mac_debug_label_fallback);
1926be0c25eSRobert Watson 
193b2f0927aSRobert Watson SYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0,
194b2f0927aSRobert Watson     "TrustedBSD MAC object counters");
195b2f0927aSRobert Watson 
19695fab37eSRobert Watson static unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs,
19795fab37eSRobert Watson     nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents,
1982555374cSRobert Watson     nmacipqs, nmacpipes, nmacprocs;
199b2f0927aSRobert Watson 
2008d8d5ea8SRobert Watson #define	MAC_DEBUG_COUNTER_INC(x)	atomic_add_int(x, 1);
2018d8d5ea8SRobert Watson #define	MAC_DEBUG_COUNTER_DEC(x)	atomic_subtract_int(x, 1);
2028d8d5ea8SRobert Watson 
203b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD,
20495fab37eSRobert Watson     &nmacmbufs, 0, "number of mbufs in use");
205b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD,
20695fab37eSRobert Watson     &nmaccreds, 0, "number of ucreds in use");
207b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD,
20895fab37eSRobert Watson     &nmacifnets, 0, "number of ifnets in use");
209b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD,
21095fab37eSRobert Watson     &nmacipqs, 0, "number of ipqs in use");
211b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD,
21295fab37eSRobert Watson     &nmacbpfdescs, 0, "number of bpfdescs in use");
213b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD,
21495fab37eSRobert Watson     &nmacsockets, 0, "number of sockets in use");
215b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, pipes, CTLFLAG_RD,
21695fab37eSRobert Watson     &nmacpipes, 0, "number of pipes in use");
2172555374cSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, procs, CTLFLAG_RD,
2182555374cSRobert Watson     &nmacprocs, 0, "number of procs in use");
219b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD,
22095fab37eSRobert Watson     &nmacmounts, 0, "number of mounts in use");
221b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD,
22295fab37eSRobert Watson     &nmactemp, 0, "number of temporary labels in use");
223b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD,
22495fab37eSRobert Watson     &nmacvnodes, 0, "number of vnodes in use");
225b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD,
22695fab37eSRobert Watson     &nmacdevfsdirents, 0, "number of devfs dirents inuse");
2278d8d5ea8SRobert Watson #else
2288d8d5ea8SRobert Watson #define	MAC_DEBUG_COUNTER_INC(x)
2298d8d5ea8SRobert Watson #define	MAC_DEBUG_COUNTER_DEC(x)
230f050add5SRobert Watson #endif
23195fab37eSRobert Watson 
23295fab37eSRobert Watson static int	mac_policy_register(struct mac_policy_conf *mpc);
23395fab37eSRobert Watson static int	mac_policy_unregister(struct mac_policy_conf *mpc);
23495fab37eSRobert Watson 
235e183f80eSRobert Watson static void	mac_check_vnode_mmap_downgrade(struct ucred *cred,
236e183f80eSRobert Watson 		    struct vnode *vp, int *prot);
23795fab37eSRobert Watson static void	mac_cred_mmapped_drop_perms_recurse(struct thread *td,
23895fab37eSRobert Watson 		    struct ucred *cred, struct vm_map *map);
23995fab37eSRobert Watson 
24083985c26SRobert Watson static void	mac_destroy_socket_label(struct label *label);
24183985c26SRobert Watson 
242763bbd2fSRobert Watson static int	mac_setlabel_vnode_extattr(struct ucred *cred,
243763bbd2fSRobert Watson 		    struct vnode *vp, struct label *intlabel);
244763bbd2fSRobert Watson 
24595fab37eSRobert Watson MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes");
246f7b951a8SRobert Watson MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
24795fab37eSRobert Watson 
24895fab37eSRobert Watson /*
24941a17fe3SRobert Watson  * mac_static_policy_list holds a list of policy modules that are not
25041a17fe3SRobert Watson  * loaded while the system is "live", and cannot be unloaded.  These
25141a17fe3SRobert Watson  * policies can be invoked without holding the busy count.
25241a17fe3SRobert Watson  *
25341a17fe3SRobert Watson  * mac_policy_list stores the list of dynamic policies.  A busy count is
254a96acd1aSRobert Watson  * maintained for the list, stored in mac_policy_busy.  The busy count
25541a17fe3SRobert Watson  * is protected by mac_policy_mtx; the list may be modified only
256a96acd1aSRobert Watson  * while the busy count is 0, requiring that the lock be held to
257a96acd1aSRobert Watson  * prevent new references to the list from being acquired.  For almost
258a96acd1aSRobert Watson  * all operations, incrementing the busy count is sufficient to
259a96acd1aSRobert Watson  * guarantee consistency, as the list cannot be modified while the
260a96acd1aSRobert Watson  * busy count is elevated.  For a few special operations involving a
26141a17fe3SRobert Watson  * change to the list of active policies, the mtx itself must be held.
26241a17fe3SRobert Watson  * A condition variable, mac_policy_cv, is used to signal potential
26341a17fe3SRobert Watson  * exclusive consumers that they should try to acquire the lock if a
26441a17fe3SRobert Watson  * first attempt at exclusive access fails.
26595fab37eSRobert Watson  */
26641a17fe3SRobert Watson static struct mtx mac_policy_mtx;
26741a17fe3SRobert Watson static struct cv mac_policy_cv;
26841a17fe3SRobert Watson static int mac_policy_count;
269089c1bdaSRobert Watson struct mac_policy_list_head mac_policy_list;
270089c1bdaSRobert Watson struct mac_policy_list_head mac_static_policy_list;
271a96acd1aSRobert Watson 
272a96acd1aSRobert Watson /*
27326306795SJohn Baldwin  * We manually invoke WITNESS_WARN() to allow Witness to generate
274a96acd1aSRobert Watson  * warnings even if we don't end up ever triggering the wait at
275a96acd1aSRobert Watson  * run-time.  The consumer of the exclusive interface must not hold
276a96acd1aSRobert Watson  * any locks (other than potentially Giant) since we may sleep for
277a96acd1aSRobert Watson  * long (potentially indefinite) periods of time waiting for the
278a96acd1aSRobert Watson  * framework to become quiescent so that a policy list change may
279a96acd1aSRobert Watson  * be made.
280a96acd1aSRobert Watson  */
281089c1bdaSRobert Watson void
28241a17fe3SRobert Watson mac_policy_grab_exclusive(void)
28341a17fe3SRobert Watson {
28441a17fe3SRobert Watson 	WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
28541a17fe3SRobert Watson  	    "mac_policy_grab_exclusive() at %s:%d", __FILE__, __LINE__);
28641a17fe3SRobert Watson 	mtx_lock(&mac_policy_mtx);
28741a17fe3SRobert Watson 	while (mac_policy_count != 0)
28841a17fe3SRobert Watson 		cv_wait(&mac_policy_cv, &mac_policy_mtx);
28941a17fe3SRobert Watson }
29095fab37eSRobert Watson 
291089c1bdaSRobert Watson void
29241a17fe3SRobert Watson mac_policy_assert_exclusive(void)
29341a17fe3SRobert Watson {
29441a17fe3SRobert Watson 	mtx_assert(&mac_policy_mtx, MA_OWNED);
29541a17fe3SRobert Watson 	KASSERT(mac_policy_count == 0,
29641a17fe3SRobert Watson 	    ("mac_policy_assert_exclusive(): not exclusive"));
29741a17fe3SRobert Watson }
298225bff6fSRobert Watson 
299089c1bdaSRobert Watson void
30041a17fe3SRobert Watson mac_policy_release_exclusive(void)
30141a17fe3SRobert Watson {
30295fab37eSRobert Watson 
30341a17fe3SRobert Watson 	KASSERT(mac_policy_count == 0,
30441a17fe3SRobert Watson 	    ("mac_policy_release_exclusive(): not exclusive"));
30541a17fe3SRobert Watson 	mtx_unlock(&mac_policy_mtx);
30641a17fe3SRobert Watson 	cv_signal(&mac_policy_cv);
30741a17fe3SRobert Watson }
30841a17fe3SRobert Watson 
309089c1bdaSRobert Watson void
31041a17fe3SRobert Watson mac_policy_list_busy(void)
31141a17fe3SRobert Watson {
31241a17fe3SRobert Watson 	mtx_lock(&mac_policy_mtx);
31341a17fe3SRobert Watson 	mac_policy_count++;
31441a17fe3SRobert Watson 	mtx_unlock(&mac_policy_mtx);
31541a17fe3SRobert Watson }
31641a17fe3SRobert Watson 
317089c1bdaSRobert Watson int
31841a17fe3SRobert Watson mac_policy_list_conditional_busy(void)
31941a17fe3SRobert Watson {
32041a17fe3SRobert Watson 	int ret;
32141a17fe3SRobert Watson 
32241a17fe3SRobert Watson 	mtx_lock(&mac_policy_mtx);
32341a17fe3SRobert Watson 	if (!LIST_EMPTY(&mac_policy_list)) {
32441a17fe3SRobert Watson 		mac_policy_count++;
32541a17fe3SRobert Watson 		ret = 1;
32641a17fe3SRobert Watson 	} else
32741a17fe3SRobert Watson 		ret = 0;
32841a17fe3SRobert Watson 	mtx_unlock(&mac_policy_mtx);
32941a17fe3SRobert Watson 	return (ret);
33041a17fe3SRobert Watson }
33141a17fe3SRobert Watson 
332089c1bdaSRobert Watson void
33341a17fe3SRobert Watson mac_policy_list_unbusy(void)
33441a17fe3SRobert Watson {
33541a17fe3SRobert Watson 	mtx_lock(&mac_policy_mtx);
33641a17fe3SRobert Watson 	mac_policy_count--;
33741a17fe3SRobert Watson 	KASSERT(mac_policy_count >= 0, ("MAC_POLICY_LIST_LOCK"));
33841a17fe3SRobert Watson 	if (mac_policy_count == 0)
33941a17fe3SRobert Watson 		cv_signal(&mac_policy_cv);
34041a17fe3SRobert Watson 	mtx_unlock(&mac_policy_mtx);
34141a17fe3SRobert Watson }
34295fab37eSRobert Watson 
34395fab37eSRobert Watson /*
34495fab37eSRobert Watson  * MAC_CHECK performs the designated check by walking the policy
34595fab37eSRobert Watson  * module list and checking with each as to how it feels about the
34695fab37eSRobert Watson  * request.  Note that it returns its value via 'error' in the scope
34795fab37eSRobert Watson  * of the caller.
34895fab37eSRobert Watson  */
34995fab37eSRobert Watson #define	MAC_CHECK(check, args...) do {					\
35095fab37eSRobert Watson 	struct mac_policy_conf *mpc;					\
35141a17fe3SRobert Watson 	int entrycount;							\
35295fab37eSRobert Watson 									\
35395fab37eSRobert Watson 	error = 0;							\
35441a17fe3SRobert Watson 	LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {		\
35541a17fe3SRobert Watson 		if (mpc->mpc_ops->mpo_ ## check != NULL)		\
3569e7bf51cSRobert Watson 			error = mac_error_select(			\
35741a17fe3SRobert Watson 			    mpc->mpc_ops->mpo_ ## check (args),		\
35841a17fe3SRobert Watson 			    error);					\
35941a17fe3SRobert Watson 	}								\
36041a17fe3SRobert Watson 	if ((entrycount = mac_policy_list_conditional_busy()) != 0) {	\
36195fab37eSRobert Watson 		LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {		\
36295fab37eSRobert Watson 			if (mpc->mpc_ops->mpo_ ## check != NULL)	\
3639e7bf51cSRobert Watson 				error = mac_error_select(		\
36495fab37eSRobert Watson 				    mpc->mpc_ops->mpo_ ## check (args),	\
36595fab37eSRobert Watson 				    error);				\
36695fab37eSRobert Watson 		}							\
36741a17fe3SRobert Watson 		mac_policy_list_unbusy();				\
36841a17fe3SRobert Watson 	}								\
36995fab37eSRobert Watson } while (0)
37095fab37eSRobert Watson 
37195fab37eSRobert Watson /*
37295fab37eSRobert Watson  * MAC_BOOLEAN performs the designated boolean composition by walking
37395fab37eSRobert Watson  * the module list, invoking each instance of the operation, and
37495fab37eSRobert Watson  * combining the results using the passed C operator.  Note that it
37595fab37eSRobert Watson  * returns its value via 'result' in the scope of the caller, which
37695fab37eSRobert Watson  * should be initialized by the caller in a meaningful way to get
37795fab37eSRobert Watson  * a meaningful result.
37895fab37eSRobert Watson  */
37995fab37eSRobert Watson #define	MAC_BOOLEAN(operation, composition, args...) do {		\
38095fab37eSRobert Watson 	struct mac_policy_conf *mpc;					\
38141a17fe3SRobert Watson 	int entrycount;							\
38295fab37eSRobert Watson 									\
38341a17fe3SRobert Watson 	LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {		\
38495fab37eSRobert Watson 		if (mpc->mpc_ops->mpo_ ## operation != NULL)		\
38595fab37eSRobert Watson 			result = result composition			\
38695fab37eSRobert Watson 			    mpc->mpc_ops->mpo_ ## operation (args);	\
38795fab37eSRobert Watson 	}								\
38841a17fe3SRobert Watson 	if ((entrycount = mac_policy_list_conditional_busy()) != 0) {	\
38941a17fe3SRobert Watson 		LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {		\
39041a17fe3SRobert Watson 			if (mpc->mpc_ops->mpo_ ## operation != NULL)	\
39141a17fe3SRobert Watson 				result = result composition		\
39241a17fe3SRobert Watson 				    mpc->mpc_ops->mpo_ ## operation	\
39341a17fe3SRobert Watson 				    (args);				\
39441a17fe3SRobert Watson 		}							\
39541a17fe3SRobert Watson 		mac_policy_list_unbusy();				\
39641a17fe3SRobert Watson 	}								\
39795fab37eSRobert Watson } while (0)
39895fab37eSRobert Watson 
399f7b951a8SRobert Watson #define	MAC_EXTERNALIZE(type, label, elementlist, outbuf, 		\
400f7b951a8SRobert Watson     outbuflen) do {							\
401f51e5803SRobert Watson 	int claimed, first, ignorenotfound, savedlen;			\
402f51e5803SRobert Watson 	char *element_name, *element_temp;				\
403f51e5803SRobert Watson 	struct sbuf sb;							\
404f7b951a8SRobert Watson 									\
405f7b951a8SRobert Watson 	error = 0;							\
406f7b951a8SRobert Watson 	first = 1;							\
407f51e5803SRobert Watson 	sbuf_new(&sb, outbuf, outbuflen, SBUF_FIXEDLEN);		\
408f51e5803SRobert Watson 	element_temp = elementlist;					\
409f7b951a8SRobert Watson 	while ((element_name = strsep(&element_temp, ",")) != NULL) {	\
410f7b951a8SRobert Watson 		if (element_name[0] == '?') {				\
411f7b951a8SRobert Watson 			element_name++;					\
412f7b951a8SRobert Watson 			ignorenotfound = 1;				\
413f7b951a8SRobert Watson 		 } else							\
414f7b951a8SRobert Watson 			ignorenotfound = 0;				\
415f51e5803SRobert Watson 		savedlen = sbuf_len(&sb);				\
416f7b951a8SRobert Watson 		if (first) {						\
417f51e5803SRobert Watson 			error = sbuf_printf(&sb, "%s/", element_name);	\
418f7b951a8SRobert Watson 			first = 0;					\
419f7b951a8SRobert Watson 		} else							\
420f51e5803SRobert Watson 			error = sbuf_printf(&sb, ",%s/", element_name);	\
421f51e5803SRobert Watson 		if (error == -1) {					\
422f51e5803SRobert Watson 			error = EINVAL;	/* XXX: E2BIG? */		\
423f7b951a8SRobert Watson 			break;						\
424f7b951a8SRobert Watson 		}							\
425f51e5803SRobert Watson 		claimed = 0;						\
426f7b951a8SRobert Watson 		MAC_CHECK(externalize_ ## type, label, element_name,	\
427f51e5803SRobert Watson 		    &sb, &claimed);					\
428f7b951a8SRobert Watson 		if (error)						\
429f7b951a8SRobert Watson 			break;						\
430f51e5803SRobert Watson 		if (claimed == 0 && ignorenotfound) {			\
431f51e5803SRobert Watson 			/* Revert last label name. */			\
432f51e5803SRobert Watson 			sbuf_setpos(&sb, savedlen);			\
433f51e5803SRobert Watson 		} else if (claimed != 1) {				\
434f51e5803SRobert Watson 			error = EINVAL;	/* XXX: ENOLABEL? */		\
435f7b951a8SRobert Watson 			break;						\
436f7b951a8SRobert Watson 		}							\
437f7b951a8SRobert Watson 	}								\
438f51e5803SRobert Watson 	sbuf_finish(&sb);						\
439f7b951a8SRobert Watson } while (0)
440f7b951a8SRobert Watson 
441f7b951a8SRobert Watson #define	MAC_INTERNALIZE(type, label, instring) do {			\
442f7b951a8SRobert Watson 	char *element, *element_name, *element_data;			\
443f7b951a8SRobert Watson 	int claimed;							\
444f7b951a8SRobert Watson 									\
445f7b951a8SRobert Watson 	error = 0;							\
446f7b951a8SRobert Watson 	element = instring;						\
447f7b951a8SRobert Watson 	while ((element_name = strsep(&element, ",")) != NULL) {	\
448f7b951a8SRobert Watson 		element_data = element_name;				\
449f7b951a8SRobert Watson 		element_name = strsep(&element_data, "/");		\
450f7b951a8SRobert Watson 		if (element_data == NULL) {				\
451f7b951a8SRobert Watson 			error = EINVAL;					\
452f7b951a8SRobert Watson 			break;						\
453f7b951a8SRobert Watson 		}							\
454f7b951a8SRobert Watson 		claimed = 0;						\
455f7b951a8SRobert Watson 		MAC_CHECK(internalize_ ## type, label, element_name,	\
456f7b951a8SRobert Watson 		    element_data, &claimed);				\
457f7b951a8SRobert Watson 		if (error)						\
458f7b951a8SRobert Watson 			break;						\
459f7b951a8SRobert Watson 		if (claimed != 1) {					\
460f7b951a8SRobert Watson 			/* XXXMAC: Another error here? */		\
461f7b951a8SRobert Watson 			error = EINVAL;					\
462f7b951a8SRobert Watson 			break;						\
463f7b951a8SRobert Watson 		}							\
464f7b951a8SRobert Watson 	}								\
465f7b951a8SRobert Watson } while (0)
466f7b951a8SRobert Watson 
46795fab37eSRobert Watson /*
46895fab37eSRobert Watson  * MAC_PERFORM performs the designated operation by walking the policy
46995fab37eSRobert Watson  * module list and invoking that operation for each policy.
47095fab37eSRobert Watson  */
47195fab37eSRobert Watson #define	MAC_PERFORM(operation, args...) do {				\
47295fab37eSRobert Watson 	struct mac_policy_conf *mpc;					\
47341a17fe3SRobert Watson 	int entrycount;							\
47495fab37eSRobert Watson 									\
47541a17fe3SRobert Watson 	LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {		\
47641a17fe3SRobert Watson 		if (mpc->mpc_ops->mpo_ ## operation != NULL)		\
47741a17fe3SRobert Watson 			mpc->mpc_ops->mpo_ ## operation (args);		\
47841a17fe3SRobert Watson 	}								\
47941a17fe3SRobert Watson 	if ((entrycount = mac_policy_list_conditional_busy()) != 0) {	\
48095fab37eSRobert Watson 		LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {		\
48195fab37eSRobert Watson 			if (mpc->mpc_ops->mpo_ ## operation != NULL)	\
48295fab37eSRobert Watson 				mpc->mpc_ops->mpo_ ## operation (args);	\
48395fab37eSRobert Watson 		}							\
48441a17fe3SRobert Watson 		mac_policy_list_unbusy();				\
48541a17fe3SRobert Watson 	}								\
48695fab37eSRobert Watson } while (0)
48795fab37eSRobert Watson 
48895fab37eSRobert Watson /*
48995fab37eSRobert Watson  * Initialize the MAC subsystem, including appropriate SMP locks.
49095fab37eSRobert Watson  */
49195fab37eSRobert Watson static void
49295fab37eSRobert Watson mac_init(void)
49395fab37eSRobert Watson {
49495fab37eSRobert Watson 
49541a17fe3SRobert Watson 	LIST_INIT(&mac_static_policy_list);
49695fab37eSRobert Watson 	LIST_INIT(&mac_policy_list);
49741a17fe3SRobert Watson 
49841a17fe3SRobert Watson 	mtx_init(&mac_policy_mtx, "mac_policy_mtx", NULL, MTX_DEF);
49941a17fe3SRobert Watson 	cv_init(&mac_policy_cv, "mac_policy_cv");
50095fab37eSRobert Watson }
50195fab37eSRobert Watson 
50295fab37eSRobert Watson /*
50395fab37eSRobert Watson  * For the purposes of modules that want to know if they were loaded
50495fab37eSRobert Watson  * "early", set the mac_late flag once we've processed modules either
50595fab37eSRobert Watson  * linked into the kernel, or loaded before the kernel startup.
50695fab37eSRobert Watson  */
50795fab37eSRobert Watson static void
50895fab37eSRobert Watson mac_late_init(void)
50995fab37eSRobert Watson {
51095fab37eSRobert Watson 
51195fab37eSRobert Watson 	mac_late = 1;
51295fab37eSRobert Watson }
51395fab37eSRobert Watson 
51495fab37eSRobert Watson /*
515225bff6fSRobert Watson  * After the policy list has changed, walk the list to update any global
51619c3e120SRobert Watson  * flags.  Currently, we support only one flag, and it's conditionally
51719c3e120SRobert Watson  * defined; as a result, the entire function is conditional.  Eventually,
51819c3e120SRobert Watson  * the #else case might also iterate across the policies.
519225bff6fSRobert Watson  */
520225bff6fSRobert Watson static void
521225bff6fSRobert Watson mac_policy_updateflags(void)
522225bff6fSRobert Watson {
523225bff6fSRobert Watson #ifndef MAC_ALWAYS_LABEL_MBUF
52419c3e120SRobert Watson 	struct mac_policy_conf *tmpc;
525225bff6fSRobert Watson 	int labelmbufs;
526225bff6fSRobert Watson 
52741a17fe3SRobert Watson 	mac_policy_assert_exclusive();
528225bff6fSRobert Watson 
529225bff6fSRobert Watson 	labelmbufs = 0;
53041a17fe3SRobert Watson 	LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) {
53141a17fe3SRobert Watson 		if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS)
53241a17fe3SRobert Watson 			labelmbufs++;
53341a17fe3SRobert Watson 	}
534225bff6fSRobert Watson 	LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) {
535225bff6fSRobert Watson 		if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS)
536225bff6fSRobert Watson 			labelmbufs++;
537225bff6fSRobert Watson 	}
538225bff6fSRobert Watson 	mac_labelmbufs = (labelmbufs != 0);
539225bff6fSRobert Watson #endif
540225bff6fSRobert Watson }
541225bff6fSRobert Watson 
542225bff6fSRobert Watson /*
54395fab37eSRobert Watson  * Allow MAC policy modules to register during boot, etc.
54495fab37eSRobert Watson  */
54595fab37eSRobert Watson int
54695fab37eSRobert Watson mac_policy_modevent(module_t mod, int type, void *data)
54795fab37eSRobert Watson {
54895fab37eSRobert Watson 	struct mac_policy_conf *mpc;
54995fab37eSRobert Watson 	int error;
55095fab37eSRobert Watson 
55195fab37eSRobert Watson 	error = 0;
55295fab37eSRobert Watson 	mpc = (struct mac_policy_conf *) data;
55395fab37eSRobert Watson 
55495fab37eSRobert Watson 	switch (type) {
55595fab37eSRobert Watson 	case MOD_LOAD:
55695fab37eSRobert Watson 		if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE &&
55795fab37eSRobert Watson 		    mac_late) {
55895fab37eSRobert Watson 			printf("mac_policy_modevent: can't load %s policy "
55995fab37eSRobert Watson 			    "after booting\n", mpc->mpc_name);
56095fab37eSRobert Watson 			error = EBUSY;
56195fab37eSRobert Watson 			break;
56295fab37eSRobert Watson 		}
56395fab37eSRobert Watson 		error = mac_policy_register(mpc);
56495fab37eSRobert Watson 		break;
56595fab37eSRobert Watson 	case MOD_UNLOAD:
56695fab37eSRobert Watson 		/* Don't unregister the module if it was never registered. */
56795fab37eSRobert Watson 		if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED)
56895fab37eSRobert Watson 		    != 0)
56995fab37eSRobert Watson 			error = mac_policy_unregister(mpc);
57095fab37eSRobert Watson 		else
57195fab37eSRobert Watson 			error = 0;
57295fab37eSRobert Watson 		break;
57395fab37eSRobert Watson 	default:
57495fab37eSRobert Watson 		break;
57595fab37eSRobert Watson 	}
57695fab37eSRobert Watson 
57795fab37eSRobert Watson 	return (error);
57895fab37eSRobert Watson }
57995fab37eSRobert Watson 
58095fab37eSRobert Watson static int
58195fab37eSRobert Watson mac_policy_register(struct mac_policy_conf *mpc)
58295fab37eSRobert Watson {
58395fab37eSRobert Watson 	struct mac_policy_conf *tmpc;
58441a17fe3SRobert Watson 	int error, slot, static_entry;
58595fab37eSRobert Watson 
58641a17fe3SRobert Watson 	error = 0;
58741a17fe3SRobert Watson 
58841a17fe3SRobert Watson 	/*
58941a17fe3SRobert Watson 	 * We don't technically need exclusive access while !mac_late,
59041a17fe3SRobert Watson 	 * but hold it for assertion consistency.
59141a17fe3SRobert Watson 	 */
59241a17fe3SRobert Watson 	mac_policy_grab_exclusive();
59341a17fe3SRobert Watson 
59441a17fe3SRobert Watson 	/*
59541a17fe3SRobert Watson 	 * If the module can potentially be unloaded, or we're loading
59641a17fe3SRobert Watson 	 * late, we have to stick it in the non-static list and pay
59741a17fe3SRobert Watson 	 * an extra performance overhead.  Otherwise, we can pay a
59841a17fe3SRobert Watson 	 * light locking cost and stick it in the static list.
59941a17fe3SRobert Watson 	 */
60041a17fe3SRobert Watson 	static_entry = (!mac_late &&
60141a17fe3SRobert Watson 	    !(mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK));
60241a17fe3SRobert Watson 
60341a17fe3SRobert Watson 	if (static_entry) {
60441a17fe3SRobert Watson 		LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) {
60541a17fe3SRobert Watson 			if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) {
60641a17fe3SRobert Watson 				error = EEXIST;
60741a17fe3SRobert Watson 				goto out;
60841a17fe3SRobert Watson 			}
60941a17fe3SRobert Watson 		}
61041a17fe3SRobert Watson 	} else {
61195fab37eSRobert Watson 		LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) {
61295fab37eSRobert Watson 			if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) {
61341a17fe3SRobert Watson 				error = EEXIST;
61441a17fe3SRobert Watson 				goto out;
61541a17fe3SRobert Watson 			}
61695fab37eSRobert Watson 		}
61795fab37eSRobert Watson 	}
61895fab37eSRobert Watson 	if (mpc->mpc_field_off != NULL) {
619b2aef571SRobert Watson 		slot = ffs(mac_slot_offsets_free);
62095fab37eSRobert Watson 		if (slot == 0) {
62141a17fe3SRobert Watson 			error = ENOMEM;
62241a17fe3SRobert Watson 			goto out;
62395fab37eSRobert Watson 		}
62495fab37eSRobert Watson 		slot--;
625b2aef571SRobert Watson 		mac_slot_offsets_free &= ~(1 << slot);
62695fab37eSRobert Watson 		*mpc->mpc_field_off = slot;
62795fab37eSRobert Watson 	}
62895fab37eSRobert Watson 	mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED;
62941a17fe3SRobert Watson 
63041a17fe3SRobert Watson 	/*
63141a17fe3SRobert Watson 	 * If we're loading a MAC module after the framework has
63241a17fe3SRobert Watson 	 * initialized, it has to go into the dynamic list.  If
63341a17fe3SRobert Watson 	 * we're loading it before we've finished initializing,
63441a17fe3SRobert Watson 	 * it can go into the static list with weaker locker
63541a17fe3SRobert Watson 	 * requirements.
63641a17fe3SRobert Watson 	 */
63741a17fe3SRobert Watson 	if (static_entry)
63841a17fe3SRobert Watson 		LIST_INSERT_HEAD(&mac_static_policy_list, mpc, mpc_list);
63941a17fe3SRobert Watson 	else
64095fab37eSRobert Watson 		LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list);
64195fab37eSRobert Watson 
64295fab37eSRobert Watson 	/* Per-policy initialization. */
64395fab37eSRobert Watson 	if (mpc->mpc_ops->mpo_init != NULL)
64495fab37eSRobert Watson 		(*(mpc->mpc_ops->mpo_init))(mpc);
645225bff6fSRobert Watson 	mac_policy_updateflags();
64695fab37eSRobert Watson 
64795fab37eSRobert Watson 	printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname,
64895fab37eSRobert Watson 	    mpc->mpc_name);
64995fab37eSRobert Watson 
65041a17fe3SRobert Watson out:
65141a17fe3SRobert Watson 	mac_policy_release_exclusive();
65241a17fe3SRobert Watson 	return (error);
65395fab37eSRobert Watson }
65495fab37eSRobert Watson 
65595fab37eSRobert Watson static int
65695fab37eSRobert Watson mac_policy_unregister(struct mac_policy_conf *mpc)
65795fab37eSRobert Watson {
65895fab37eSRobert Watson 
659ea599aa0SRobert Watson 	/*
660ea599aa0SRobert Watson 	 * If we fail the load, we may get a request to unload.  Check
661ea599aa0SRobert Watson 	 * to see if we did the run-time registration, and if not,
662ea599aa0SRobert Watson 	 * silently succeed.
663ea599aa0SRobert Watson 	 */
66441a17fe3SRobert Watson 	mac_policy_grab_exclusive();
665ea599aa0SRobert Watson 	if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) {
66641a17fe3SRobert Watson 		mac_policy_release_exclusive();
667ea599aa0SRobert Watson 		return (0);
668ea599aa0SRobert Watson 	}
66995fab37eSRobert Watson #if 0
67095fab37eSRobert Watson 	/*
67195fab37eSRobert Watson 	 * Don't allow unloading modules with private data.
67295fab37eSRobert Watson 	 */
673ea599aa0SRobert Watson 	if (mpc->mpc_field_off != NULL) {
674ea599aa0SRobert Watson 		MAC_POLICY_LIST_UNLOCK();
67595fab37eSRobert Watson 		return (EBUSY);
676ea599aa0SRobert Watson 	}
67795fab37eSRobert Watson #endif
678ea599aa0SRobert Watson 	/*
679ea599aa0SRobert Watson 	 * Only allow the unload to proceed if the module is unloadable
680ea599aa0SRobert Watson 	 * by its own definition.
681ea599aa0SRobert Watson 	 */
682ea599aa0SRobert Watson 	if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) {
68341a17fe3SRobert Watson 		mac_policy_release_exclusive();
68495fab37eSRobert Watson 		return (EBUSY);
685ea599aa0SRobert Watson 	}
68695fab37eSRobert Watson 	if (mpc->mpc_ops->mpo_destroy != NULL)
68795fab37eSRobert Watson 		(*(mpc->mpc_ops->mpo_destroy))(mpc);
68895fab37eSRobert Watson 
68995fab37eSRobert Watson 	LIST_REMOVE(mpc, mpc_list);
6909aeffb2bSRobert Watson 	mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED;
691225bff6fSRobert Watson 	mac_policy_updateflags();
69241a17fe3SRobert Watson 
69341a17fe3SRobert Watson 	mac_policy_release_exclusive();
694a96acd1aSRobert Watson 
69595fab37eSRobert Watson 	printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname,
69695fab37eSRobert Watson 	    mpc->mpc_name);
69795fab37eSRobert Watson 
69895fab37eSRobert Watson 	return (0);
69995fab37eSRobert Watson }
70095fab37eSRobert Watson 
70195fab37eSRobert Watson /*
70295fab37eSRobert Watson  * Define an error value precedence, and given two arguments, selects the
70395fab37eSRobert Watson  * value with the higher precedence.
70495fab37eSRobert Watson  */
7059e7bf51cSRobert Watson int
7069e7bf51cSRobert Watson mac_error_select(int error1, int error2)
70795fab37eSRobert Watson {
70895fab37eSRobert Watson 
70995fab37eSRobert Watson 	/* Certain decision-making errors take top priority. */
71095fab37eSRobert Watson 	if (error1 == EDEADLK || error2 == EDEADLK)
71195fab37eSRobert Watson 		return (EDEADLK);
71295fab37eSRobert Watson 
71395fab37eSRobert Watson 	/* Invalid arguments should be reported where possible. */
71495fab37eSRobert Watson 	if (error1 == EINVAL || error2 == EINVAL)
71595fab37eSRobert Watson 		return (EINVAL);
71695fab37eSRobert Watson 
71795fab37eSRobert Watson 	/* Precedence goes to "visibility", with both process and file. */
71895fab37eSRobert Watson 	if (error1 == ESRCH || error2 == ESRCH)
71995fab37eSRobert Watson 		return (ESRCH);
72095fab37eSRobert Watson 
72195fab37eSRobert Watson 	if (error1 == ENOENT || error2 == ENOENT)
72295fab37eSRobert Watson 		return (ENOENT);
72395fab37eSRobert Watson 
72495fab37eSRobert Watson 	/* Precedence goes to DAC/MAC protections. */
72595fab37eSRobert Watson 	if (error1 == EACCES || error2 == EACCES)
72695fab37eSRobert Watson 		return (EACCES);
72795fab37eSRobert Watson 
72895fab37eSRobert Watson 	/* Precedence goes to privilege. */
72995fab37eSRobert Watson 	if (error1 == EPERM || error2 == EPERM)
73095fab37eSRobert Watson 		return (EPERM);
73195fab37eSRobert Watson 
73295fab37eSRobert Watson 	/* Precedence goes to error over success; otherwise, arbitrary. */
73395fab37eSRobert Watson 	if (error1 != 0)
73495fab37eSRobert Watson 		return (error1);
73595fab37eSRobert Watson 	return (error2);
73695fab37eSRobert Watson }
73795fab37eSRobert Watson 
73810eeb10cSRobert Watson static struct label *
73910eeb10cSRobert Watson mbuf_to_label(struct mbuf *mbuf)
74010eeb10cSRobert Watson {
741225bff6fSRobert Watson 	struct m_tag *tag;
74210eeb10cSRobert Watson 	struct label *label;
74310eeb10cSRobert Watson 
744225bff6fSRobert Watson 	tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL);
745225bff6fSRobert Watson 	label = (struct label *)(tag+1);
74610eeb10cSRobert Watson 
74710eeb10cSRobert Watson 	return (label);
74810eeb10cSRobert Watson }
74910eeb10cSRobert Watson 
75008bcdc58SRobert Watson static void
75108bcdc58SRobert Watson mac_init_label(struct label *label)
75208bcdc58SRobert Watson {
75308bcdc58SRobert Watson 
75408bcdc58SRobert Watson 	bzero(label, sizeof(*label));
75508bcdc58SRobert Watson 	label->l_flags = MAC_FLAG_INITIALIZED;
75608bcdc58SRobert Watson }
75708bcdc58SRobert Watson 
75808bcdc58SRobert Watson static void
75908bcdc58SRobert Watson mac_destroy_label(struct label *label)
76008bcdc58SRobert Watson {
76108bcdc58SRobert Watson 
76208bcdc58SRobert Watson 	KASSERT(label->l_flags & MAC_FLAG_INITIALIZED,
76308bcdc58SRobert Watson 	    ("destroying uninitialized label"));
76408bcdc58SRobert Watson 
76508bcdc58SRobert Watson 	bzero(label, sizeof(*label));
76608bcdc58SRobert Watson 	/* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */
76708bcdc58SRobert Watson }
76808bcdc58SRobert Watson 
76908bcdc58SRobert Watson void
77087807196SRobert Watson mac_init_bpfdesc(struct bpf_d *bpf_d)
77108bcdc58SRobert Watson {
77208bcdc58SRobert Watson 
77387807196SRobert Watson 	mac_init_label(&bpf_d->bd_label);
77487807196SRobert Watson 	MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label);
7758d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_INC(&nmacbpfdescs);
77608bcdc58SRobert Watson }
77708bcdc58SRobert Watson 
778f7b951a8SRobert Watson static void
779f7b951a8SRobert Watson mac_init_cred_label(struct label *label)
78008bcdc58SRobert Watson {
78108bcdc58SRobert Watson 
782f7b951a8SRobert Watson 	mac_init_label(label);
783f7b951a8SRobert Watson 	MAC_PERFORM(init_cred_label, label);
7848d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_INC(&nmaccreds);
78508bcdc58SRobert Watson }
78608bcdc58SRobert Watson 
78708bcdc58SRobert Watson void
788f7b951a8SRobert Watson mac_init_cred(struct ucred *cred)
789f7b951a8SRobert Watson {
790f7b951a8SRobert Watson 
791f7b951a8SRobert Watson 	mac_init_cred_label(&cred->cr_label);
792f7b951a8SRobert Watson }
793f7b951a8SRobert Watson 
794f7b951a8SRobert Watson void
79587807196SRobert Watson mac_init_devfsdirent(struct devfs_dirent *de)
79608bcdc58SRobert Watson {
79708bcdc58SRobert Watson 
79887807196SRobert Watson 	mac_init_label(&de->de_label);
79987807196SRobert Watson 	MAC_PERFORM(init_devfsdirent_label, &de->de_label);
8008d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_INC(&nmacdevfsdirents);
80108bcdc58SRobert Watson }
80208bcdc58SRobert Watson 
803f7b951a8SRobert Watson static void
804f7b951a8SRobert Watson mac_init_ifnet_label(struct label *label)
805f7b951a8SRobert Watson {
806f7b951a8SRobert Watson 
807f7b951a8SRobert Watson 	mac_init_label(label);
808f7b951a8SRobert Watson 	MAC_PERFORM(init_ifnet_label, label);
8098d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_INC(&nmacifnets);
810f7b951a8SRobert Watson }
811f7b951a8SRobert Watson 
81208bcdc58SRobert Watson void
81308bcdc58SRobert Watson mac_init_ifnet(struct ifnet *ifp)
81408bcdc58SRobert Watson {
81508bcdc58SRobert Watson 
816f7b951a8SRobert Watson 	mac_init_ifnet_label(&ifp->if_label);
81708bcdc58SRobert Watson }
81808bcdc58SRobert Watson 
8195e7ce478SRobert Watson int
8205e7ce478SRobert Watson mac_init_ipq(struct ipq *ipq, int flag)
82108bcdc58SRobert Watson {
8225e7ce478SRobert Watson 	int error;
82308bcdc58SRobert Watson 
82408bcdc58SRobert Watson 	mac_init_label(&ipq->ipq_label);
8255e7ce478SRobert Watson 
8265e7ce478SRobert Watson 	MAC_CHECK(init_ipq_label, &ipq->ipq_label, flag);
8275e7ce478SRobert Watson 	if (error) {
8285e7ce478SRobert Watson 		MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label);
8295e7ce478SRobert Watson 		mac_destroy_label(&ipq->ipq_label);
8308d8d5ea8SRobert Watson 	} else {
8318d8d5ea8SRobert Watson 		MAC_DEBUG_COUNTER_INC(&nmacipqs);
8325e7ce478SRobert Watson 	}
8335e7ce478SRobert Watson 	return (error);
83408bcdc58SRobert Watson }
83508bcdc58SRobert Watson 
83687807196SRobert Watson int
837225bff6fSRobert Watson mac_init_mbuf_tag(struct m_tag *tag, int flag)
83808bcdc58SRobert Watson {
839225bff6fSRobert Watson 	struct label *label;
8406d1a6a9aSRobert Watson 	int error;
84156c15412SRobert Watson 
842225bff6fSRobert Watson 	label = (struct label *) (tag + 1);
843225bff6fSRobert Watson 	mac_init_label(label);
84408bcdc58SRobert Watson 
8456d1a6a9aSRobert Watson 	MAC_CHECK(init_mbuf_label, label, flag);
84656c15412SRobert Watson 	if (error) {
847225bff6fSRobert Watson 		MAC_PERFORM(destroy_mbuf_label, label);
848225bff6fSRobert Watson 		mac_destroy_label(label);
8498d8d5ea8SRobert Watson 	} else {
8508d8d5ea8SRobert Watson 		MAC_DEBUG_COUNTER_INC(&nmacmbufs);
85156c15412SRobert Watson 	}
85256c15412SRobert Watson 	return (error);
85308bcdc58SRobert Watson }
85408bcdc58SRobert Watson 
855225bff6fSRobert Watson int
856225bff6fSRobert Watson mac_init_mbuf(struct mbuf *m, int flag)
857225bff6fSRobert Watson {
858225bff6fSRobert Watson 	struct m_tag *tag;
859225bff6fSRobert Watson 	int error;
860225bff6fSRobert Watson 
861225bff6fSRobert Watson 	M_ASSERTPKTHDR(m);
862225bff6fSRobert Watson 
863225bff6fSRobert Watson #ifndef MAC_ALWAYS_LABEL_MBUF
864225bff6fSRobert Watson 	/*
86519c3e120SRobert Watson 	 * If conditionally allocating mbuf labels, don't allocate unless
86619c3e120SRobert Watson 	 * they are required.
867225bff6fSRobert Watson 	 */
86819c3e120SRobert Watson 	if (!mac_labelmbufs)
86919c3e120SRobert Watson 		return (0);
870225bff6fSRobert Watson #endif
871225bff6fSRobert Watson 	tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label),
872225bff6fSRobert Watson 	    flag);
873225bff6fSRobert Watson 	if (tag == NULL)
874225bff6fSRobert Watson 		return (ENOMEM);
875225bff6fSRobert Watson 	error = mac_init_mbuf_tag(tag, flag);
876225bff6fSRobert Watson 	if (error) {
877225bff6fSRobert Watson 		m_tag_free(tag);
878225bff6fSRobert Watson 		return (error);
879225bff6fSRobert Watson 	}
880225bff6fSRobert Watson 	m_tag_prepend(m, tag);
881225bff6fSRobert Watson 	return (0);
882225bff6fSRobert Watson }
883225bff6fSRobert Watson 
88408bcdc58SRobert Watson void
88587807196SRobert Watson mac_init_mount(struct mount *mp)
88608bcdc58SRobert Watson {
88708bcdc58SRobert Watson 
88887807196SRobert Watson 	mac_init_label(&mp->mnt_mntlabel);
88987807196SRobert Watson 	mac_init_label(&mp->mnt_fslabel);
89087807196SRobert Watson 	MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel);
89187807196SRobert Watson 	MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel);
8928d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_INC(&nmacmounts);
89308bcdc58SRobert Watson }
89408bcdc58SRobert Watson 
895f7b951a8SRobert Watson static void
896f7b951a8SRobert Watson mac_init_pipe_label(struct label *label)
897f7b951a8SRobert Watson {
898f7b951a8SRobert Watson 
899f7b951a8SRobert Watson 	mac_init_label(label);
900f7b951a8SRobert Watson 	MAC_PERFORM(init_pipe_label, label);
9018d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_INC(&nmacpipes);
902f7b951a8SRobert Watson }
903f7b951a8SRobert Watson 
90408bcdc58SRobert Watson void
90508bcdc58SRobert Watson mac_init_pipe(struct pipe *pipe)
90608bcdc58SRobert Watson {
90708bcdc58SRobert Watson 	struct label *label;
90808bcdc58SRobert Watson 
909a163d034SWarner Losh 	label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK);
91008bcdc58SRobert Watson 	pipe->pipe_label = label;
91108bcdc58SRobert Watson 	pipe->pipe_peer->pipe_label = label;
912f7b951a8SRobert Watson 	mac_init_pipe_label(label);
91308bcdc58SRobert Watson }
91408bcdc58SRobert Watson 
9152555374cSRobert Watson void
9162555374cSRobert Watson mac_init_proc(struct proc *p)
9172555374cSRobert Watson {
9182555374cSRobert Watson 
9192555374cSRobert Watson 	mac_init_label(&p->p_label);
9202555374cSRobert Watson 	MAC_PERFORM(init_proc_label, &p->p_label);
9218d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_INC(&nmacprocs);
9222555374cSRobert Watson }
9232555374cSRobert Watson 
92483985c26SRobert Watson static int
92583985c26SRobert Watson mac_init_socket_label(struct label *label, int flag)
92608bcdc58SRobert Watson {
92783985c26SRobert Watson 	int error;
92808bcdc58SRobert Watson 
92983985c26SRobert Watson 	mac_init_label(label);
93083985c26SRobert Watson 
93183985c26SRobert Watson 	MAC_CHECK(init_socket_label, label, flag);
93283985c26SRobert Watson 	if (error) {
93383985c26SRobert Watson 		MAC_PERFORM(destroy_socket_label, label);
93483985c26SRobert Watson 		mac_destroy_label(label);
9358d8d5ea8SRobert Watson 	} else {
9368d8d5ea8SRobert Watson 		MAC_DEBUG_COUNTER_INC(&nmacsockets);
93783985c26SRobert Watson 	}
93883985c26SRobert Watson 
93983985c26SRobert Watson 	return (error);
94083985c26SRobert Watson }
94183985c26SRobert Watson 
94283985c26SRobert Watson static int
94383985c26SRobert Watson mac_init_socket_peer_label(struct label *label, int flag)
94483985c26SRobert Watson {
94583985c26SRobert Watson 	int error;
94683985c26SRobert Watson 
94783985c26SRobert Watson 	mac_init_label(label);
94883985c26SRobert Watson 
94983985c26SRobert Watson 	MAC_CHECK(init_socket_peer_label, label, flag);
95083985c26SRobert Watson 	if (error) {
95183985c26SRobert Watson 		MAC_PERFORM(destroy_socket_label, label);
95283985c26SRobert Watson 		mac_destroy_label(label);
95383985c26SRobert Watson 	}
95483985c26SRobert Watson 
95583985c26SRobert Watson 	return (error);
95683985c26SRobert Watson }
95783985c26SRobert Watson 
95883985c26SRobert Watson int
95983985c26SRobert Watson mac_init_socket(struct socket *socket, int flag)
96083985c26SRobert Watson {
96183985c26SRobert Watson 	int error;
96283985c26SRobert Watson 
96383985c26SRobert Watson 	error = mac_init_socket_label(&socket->so_label, flag);
96483985c26SRobert Watson 	if (error)
96583985c26SRobert Watson 		return (error);
96683985c26SRobert Watson 
96783985c26SRobert Watson 	error = mac_init_socket_peer_label(&socket->so_peerlabel, flag);
96883985c26SRobert Watson 	if (error)
96983985c26SRobert Watson 		mac_destroy_socket_label(&socket->so_label);
97083985c26SRobert Watson 
97183985c26SRobert Watson 	return (error);
97287807196SRobert Watson }
97387807196SRobert Watson 
974763bbd2fSRobert Watson void
975f7b951a8SRobert Watson mac_init_vnode_label(struct label *label)
97687807196SRobert Watson {
97787807196SRobert Watson 
97887807196SRobert Watson 	mac_init_label(label);
979f7b951a8SRobert Watson 	MAC_PERFORM(init_vnode_label, label);
9808d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_INC(&nmacvnodes);
98108bcdc58SRobert Watson }
98208bcdc58SRobert Watson 
98308bcdc58SRobert Watson void
98487807196SRobert Watson mac_init_vnode(struct vnode *vp)
98508bcdc58SRobert Watson {
98608bcdc58SRobert Watson 
987f7b951a8SRobert Watson 	mac_init_vnode_label(&vp->v_label);
98808bcdc58SRobert Watson }
98908bcdc58SRobert Watson 
99008bcdc58SRobert Watson void
99108bcdc58SRobert Watson mac_destroy_bpfdesc(struct bpf_d *bpf_d)
99208bcdc58SRobert Watson {
99308bcdc58SRobert Watson 
99408bcdc58SRobert Watson 	MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label);
99508bcdc58SRobert Watson 	mac_destroy_label(&bpf_d->bd_label);
9968d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacbpfdescs);
99708bcdc58SRobert Watson }
99808bcdc58SRobert Watson 
999f7b951a8SRobert Watson static void
1000f7b951a8SRobert Watson mac_destroy_cred_label(struct label *label)
100108bcdc58SRobert Watson {
100208bcdc58SRobert Watson 
1003f7b951a8SRobert Watson 	MAC_PERFORM(destroy_cred_label, label);
1004f7b951a8SRobert Watson 	mac_destroy_label(label);
10058d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmaccreds);
100687807196SRobert Watson }
100787807196SRobert Watson 
100887807196SRobert Watson void
1009f7b951a8SRobert Watson mac_destroy_cred(struct ucred *cred)
1010f7b951a8SRobert Watson {
1011f7b951a8SRobert Watson 
1012f7b951a8SRobert Watson 	mac_destroy_cred_label(&cred->cr_label);
1013f7b951a8SRobert Watson }
1014f7b951a8SRobert Watson 
1015f7b951a8SRobert Watson void
101687807196SRobert Watson mac_destroy_devfsdirent(struct devfs_dirent *de)
101787807196SRobert Watson {
101887807196SRobert Watson 
101987807196SRobert Watson 	MAC_PERFORM(destroy_devfsdirent_label, &de->de_label);
102087807196SRobert Watson 	mac_destroy_label(&de->de_label);
10218d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacdevfsdirents);
102287807196SRobert Watson }
102387807196SRobert Watson 
1024f7b951a8SRobert Watson static void
1025f7b951a8SRobert Watson mac_destroy_ifnet_label(struct label *label)
1026f7b951a8SRobert Watson {
1027f7b951a8SRobert Watson 
1028f7b951a8SRobert Watson 	MAC_PERFORM(destroy_ifnet_label, label);
1029f7b951a8SRobert Watson 	mac_destroy_label(label);
10308d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacifnets);
1031f7b951a8SRobert Watson }
1032f7b951a8SRobert Watson 
103387807196SRobert Watson void
103487807196SRobert Watson mac_destroy_ifnet(struct ifnet *ifp)
103587807196SRobert Watson {
103687807196SRobert Watson 
1037f7b951a8SRobert Watson 	mac_destroy_ifnet_label(&ifp->if_label);
103887807196SRobert Watson }
103987807196SRobert Watson 
104087807196SRobert Watson void
104187807196SRobert Watson mac_destroy_ipq(struct ipq *ipq)
104287807196SRobert Watson {
104387807196SRobert Watson 
104487807196SRobert Watson 	MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label);
104587807196SRobert Watson 	mac_destroy_label(&ipq->ipq_label);
10468d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacipqs);
104787807196SRobert Watson }
104887807196SRobert Watson 
104987807196SRobert Watson void
1050225bff6fSRobert Watson mac_destroy_mbuf_tag(struct m_tag *tag)
105187807196SRobert Watson {
1052225bff6fSRobert Watson 	struct label *label;
105387807196SRobert Watson 
1054225bff6fSRobert Watson 	label = (struct label *)(tag+1);
1055225bff6fSRobert Watson 
1056225bff6fSRobert Watson 	MAC_PERFORM(destroy_mbuf_label, label);
1057225bff6fSRobert Watson 	mac_destroy_label(label);
10588d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacmbufs);
105908bcdc58SRobert Watson }
106008bcdc58SRobert Watson 
106108bcdc58SRobert Watson void
106208bcdc58SRobert Watson mac_destroy_mount(struct mount *mp)
106308bcdc58SRobert Watson {
106408bcdc58SRobert Watson 
106508bcdc58SRobert Watson 	MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel);
106608bcdc58SRobert Watson 	MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel);
106708bcdc58SRobert Watson 	mac_destroy_label(&mp->mnt_fslabel);
106808bcdc58SRobert Watson 	mac_destroy_label(&mp->mnt_mntlabel);
10698d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacmounts);
107008bcdc58SRobert Watson }
107108bcdc58SRobert Watson 
1072f7b951a8SRobert Watson static void
1073f7b951a8SRobert Watson mac_destroy_pipe_label(struct label *label)
1074f7b951a8SRobert Watson {
1075f7b951a8SRobert Watson 
1076f7b951a8SRobert Watson 	MAC_PERFORM(destroy_pipe_label, label);
1077f7b951a8SRobert Watson 	mac_destroy_label(label);
10788d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacpipes);
1079f7b951a8SRobert Watson }
1080f7b951a8SRobert Watson 
108187807196SRobert Watson void
108287807196SRobert Watson mac_destroy_pipe(struct pipe *pipe)
108308bcdc58SRobert Watson {
108408bcdc58SRobert Watson 
1085f7b951a8SRobert Watson 	mac_destroy_pipe_label(pipe->pipe_label);
108687807196SRobert Watson 	free(pipe->pipe_label, M_MACPIPELABEL);
108787807196SRobert Watson }
108887807196SRobert Watson 
10892555374cSRobert Watson void
10902555374cSRobert Watson mac_destroy_proc(struct proc *p)
10912555374cSRobert Watson {
10922555374cSRobert Watson 
10932555374cSRobert Watson 	MAC_PERFORM(destroy_proc_label, &p->p_label);
10942555374cSRobert Watson 	mac_destroy_label(&p->p_label);
10958d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacprocs);
10962555374cSRobert Watson }
10972555374cSRobert Watson 
109883985c26SRobert Watson static void
109983985c26SRobert Watson mac_destroy_socket_label(struct label *label)
110083985c26SRobert Watson {
110183985c26SRobert Watson 
110283985c26SRobert Watson 	MAC_PERFORM(destroy_socket_label, label);
110383985c26SRobert Watson 	mac_destroy_label(label);
11048d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacsockets);
110583985c26SRobert Watson }
110683985c26SRobert Watson 
110783985c26SRobert Watson static void
110883985c26SRobert Watson mac_destroy_socket_peer_label(struct label *label)
110983985c26SRobert Watson {
111083985c26SRobert Watson 
111183985c26SRobert Watson 	MAC_PERFORM(destroy_socket_peer_label, label);
111283985c26SRobert Watson 	mac_destroy_label(label);
111383985c26SRobert Watson }
111483985c26SRobert Watson 
111587807196SRobert Watson void
111687807196SRobert Watson mac_destroy_socket(struct socket *socket)
111787807196SRobert Watson {
111887807196SRobert Watson 
111983985c26SRobert Watson 	mac_destroy_socket_label(&socket->so_label);
112083985c26SRobert Watson 	mac_destroy_socket_peer_label(&socket->so_peerlabel);
112108bcdc58SRobert Watson }
112208bcdc58SRobert Watson 
1123763bbd2fSRobert Watson void
1124f7b951a8SRobert Watson mac_destroy_vnode_label(struct label *label)
112508bcdc58SRobert Watson {
112608bcdc58SRobert Watson 
1127f7b951a8SRobert Watson 	MAC_PERFORM(destroy_vnode_label, label);
112808bcdc58SRobert Watson 	mac_destroy_label(label);
11298d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacvnodes);
113008bcdc58SRobert Watson }
113108bcdc58SRobert Watson 
113208bcdc58SRobert Watson void
113308bcdc58SRobert Watson mac_destroy_vnode(struct vnode *vp)
113408bcdc58SRobert Watson {
113508bcdc58SRobert Watson 
1136f7b951a8SRobert Watson 	mac_destroy_vnode_label(&vp->v_label);
1137f7b951a8SRobert Watson }
1138f7b951a8SRobert Watson 
1139225bff6fSRobert Watson void
1140225bff6fSRobert Watson mac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest)
1141225bff6fSRobert Watson {
1142225bff6fSRobert Watson 	struct label *src_label, *dest_label;
1143225bff6fSRobert Watson 
1144225bff6fSRobert Watson 	src_label = (struct label *)(src+1);
1145225bff6fSRobert Watson 	dest_label = (struct label *)(dest+1);
1146225bff6fSRobert Watson 
1147225bff6fSRobert Watson 	/*
1148225bff6fSRobert Watson 	 * mac_init_mbuf_tag() is called on the target tag in
1149225bff6fSRobert Watson 	 * m_tag_copy(), so we don't need to call it here.
1150225bff6fSRobert Watson 	 */
1151225bff6fSRobert Watson 	MAC_PERFORM(copy_mbuf_label, src_label, dest_label);
1152225bff6fSRobert Watson }
1153225bff6fSRobert Watson 
1154f7b951a8SRobert Watson static void
1155f7b951a8SRobert Watson mac_copy_pipe_label(struct label *src, struct label *dest)
1156f7b951a8SRobert Watson {
1157f7b951a8SRobert Watson 
1158f7b951a8SRobert Watson 	MAC_PERFORM(copy_pipe_label, src, dest);
1159f7b951a8SRobert Watson }
1160f7b951a8SRobert Watson 
1161763bbd2fSRobert Watson void
1162f7b951a8SRobert Watson mac_copy_vnode_label(struct label *src, struct label *dest)
1163f7b951a8SRobert Watson {
1164f7b951a8SRobert Watson 
1165f7b951a8SRobert Watson 	MAC_PERFORM(copy_vnode_label, src, dest);
116608bcdc58SRobert Watson }
116708bcdc58SRobert Watson 
116869bbb5b1SRobert Watson static int
1169f7b951a8SRobert Watson mac_check_structmac_consistent(struct mac *mac)
1170f7b951a8SRobert Watson {
1171f7b951a8SRobert Watson 
1172cc7b13bfSRobert Watson 	if (mac->m_buflen < 0 ||
1173cc7b13bfSRobert Watson 	    mac->m_buflen > MAC_MAX_LABEL_BUF_LEN)
1174f7b951a8SRobert Watson 		return (EINVAL);
1175f7b951a8SRobert Watson 
1176f7b951a8SRobert Watson 	return (0);
1177f7b951a8SRobert Watson }
1178f7b951a8SRobert Watson 
1179f7b951a8SRobert Watson static int
1180f7b951a8SRobert Watson mac_externalize_cred_label(struct label *label, char *elements,
1181f7b951a8SRobert Watson     char *outbuf, size_t outbuflen, int flags)
118269bbb5b1SRobert Watson {
118369bbb5b1SRobert Watson 	int error;
118469bbb5b1SRobert Watson 
1185f7b951a8SRobert Watson 	MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen);
118669bbb5b1SRobert Watson 
118769bbb5b1SRobert Watson 	return (error);
118869bbb5b1SRobert Watson }
118969bbb5b1SRobert Watson 
119069bbb5b1SRobert Watson static int
1191f7b951a8SRobert Watson mac_externalize_ifnet_label(struct label *label, char *elements,
1192f7b951a8SRobert Watson     char *outbuf, size_t outbuflen, int flags)
119369bbb5b1SRobert Watson {
119469bbb5b1SRobert Watson 	int error;
119569bbb5b1SRobert Watson 
1196f7b951a8SRobert Watson 	MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen);
1197f7b951a8SRobert Watson 
1198f7b951a8SRobert Watson 	return (error);
1199f7b951a8SRobert Watson }
1200f7b951a8SRobert Watson 
1201f7b951a8SRobert Watson static int
1202f7b951a8SRobert Watson mac_externalize_pipe_label(struct label *label, char *elements,
1203f7b951a8SRobert Watson     char *outbuf, size_t outbuflen, int flags)
1204f7b951a8SRobert Watson {
1205f7b951a8SRobert Watson 	int error;
1206f7b951a8SRobert Watson 
1207f7b951a8SRobert Watson 	MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen);
1208f7b951a8SRobert Watson 
1209f7b951a8SRobert Watson 	return (error);
1210f7b951a8SRobert Watson }
1211f7b951a8SRobert Watson 
1212f7b951a8SRobert Watson static int
1213f7b951a8SRobert Watson mac_externalize_socket_label(struct label *label, char *elements,
1214f7b951a8SRobert Watson     char *outbuf, size_t outbuflen, int flags)
1215f7b951a8SRobert Watson {
1216f7b951a8SRobert Watson 	int error;
1217f7b951a8SRobert Watson 
1218f7b951a8SRobert Watson 	MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen);
1219f7b951a8SRobert Watson 
1220f7b951a8SRobert Watson 	return (error);
1221f7b951a8SRobert Watson }
1222f7b951a8SRobert Watson 
1223f7b951a8SRobert Watson static int
1224f7b951a8SRobert Watson mac_externalize_socket_peer_label(struct label *label, char *elements,
1225f7b951a8SRobert Watson     char *outbuf, size_t outbuflen, int flags)
1226f7b951a8SRobert Watson {
1227f7b951a8SRobert Watson 	int error;
1228f7b951a8SRobert Watson 
1229f7b951a8SRobert Watson 	MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen);
1230f7b951a8SRobert Watson 
1231f7b951a8SRobert Watson 	return (error);
1232f7b951a8SRobert Watson }
1233f7b951a8SRobert Watson 
1234f7b951a8SRobert Watson static int
1235f7b951a8SRobert Watson mac_externalize_vnode_label(struct label *label, char *elements,
1236f7b951a8SRobert Watson     char *outbuf, size_t outbuflen, int flags)
1237f7b951a8SRobert Watson {
1238f7b951a8SRobert Watson 	int error;
1239f7b951a8SRobert Watson 
1240f7b951a8SRobert Watson 	MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen);
1241f7b951a8SRobert Watson 
1242f7b951a8SRobert Watson 	return (error);
1243f7b951a8SRobert Watson }
1244f7b951a8SRobert Watson 
1245f7b951a8SRobert Watson static int
1246f7b951a8SRobert Watson mac_internalize_cred_label(struct label *label, char *string)
1247f7b951a8SRobert Watson {
1248f7b951a8SRobert Watson 	int error;
1249f7b951a8SRobert Watson 
1250f7b951a8SRobert Watson 	MAC_INTERNALIZE(cred_label, label, string);
1251f7b951a8SRobert Watson 
1252f7b951a8SRobert Watson 	return (error);
1253f7b951a8SRobert Watson }
1254f7b951a8SRobert Watson 
1255f7b951a8SRobert Watson static int
1256f7b951a8SRobert Watson mac_internalize_ifnet_label(struct label *label, char *string)
1257f7b951a8SRobert Watson {
1258f7b951a8SRobert Watson 	int error;
1259f7b951a8SRobert Watson 
1260f7b951a8SRobert Watson 	MAC_INTERNALIZE(ifnet_label, label, string);
1261f7b951a8SRobert Watson 
1262f7b951a8SRobert Watson 	return (error);
1263f7b951a8SRobert Watson }
1264f7b951a8SRobert Watson 
1265f7b951a8SRobert Watson static int
1266f7b951a8SRobert Watson mac_internalize_pipe_label(struct label *label, char *string)
1267f7b951a8SRobert Watson {
1268f7b951a8SRobert Watson 	int error;
1269f7b951a8SRobert Watson 
1270f7b951a8SRobert Watson 	MAC_INTERNALIZE(pipe_label, label, string);
1271f7b951a8SRobert Watson 
1272f7b951a8SRobert Watson 	return (error);
1273f7b951a8SRobert Watson }
1274f7b951a8SRobert Watson 
1275f7b951a8SRobert Watson static int
1276f7b951a8SRobert Watson mac_internalize_socket_label(struct label *label, char *string)
1277f7b951a8SRobert Watson {
1278f7b951a8SRobert Watson 	int error;
1279f7b951a8SRobert Watson 
1280f7b951a8SRobert Watson 	MAC_INTERNALIZE(socket_label, label, string);
1281f7b951a8SRobert Watson 
1282f7b951a8SRobert Watson 	return (error);
1283f7b951a8SRobert Watson }
1284f7b951a8SRobert Watson 
1285f7b951a8SRobert Watson static int
1286f7b951a8SRobert Watson mac_internalize_vnode_label(struct label *label, char *string)
1287f7b951a8SRobert Watson {
1288f7b951a8SRobert Watson 	int error;
1289f7b951a8SRobert Watson 
1290f7b951a8SRobert Watson 	MAC_INTERNALIZE(vnode_label, label, string);
129169bbb5b1SRobert Watson 
129269bbb5b1SRobert Watson 	return (error);
129369bbb5b1SRobert Watson }
129469bbb5b1SRobert Watson 
129569bbb5b1SRobert Watson /*
129669bbb5b1SRobert Watson  * Initialize MAC label for the first kernel process, from which other
129769bbb5b1SRobert Watson  * kernel processes and threads are spawned.
129869bbb5b1SRobert Watson  */
129969bbb5b1SRobert Watson void
130069bbb5b1SRobert Watson mac_create_proc0(struct ucred *cred)
130169bbb5b1SRobert Watson {
130269bbb5b1SRobert Watson 
130369bbb5b1SRobert Watson 	MAC_PERFORM(create_proc0, cred);
130469bbb5b1SRobert Watson }
130569bbb5b1SRobert Watson 
130669bbb5b1SRobert Watson /*
130769bbb5b1SRobert Watson  * Initialize MAC label for the first userland process, from which other
130869bbb5b1SRobert Watson  * userland processes and threads are spawned.
130969bbb5b1SRobert Watson  */
131069bbb5b1SRobert Watson void
131169bbb5b1SRobert Watson mac_create_proc1(struct ucred *cred)
131269bbb5b1SRobert Watson {
131369bbb5b1SRobert Watson 
131469bbb5b1SRobert Watson 	MAC_PERFORM(create_proc1, cred);
131569bbb5b1SRobert Watson }
131669bbb5b1SRobert Watson 
131769bbb5b1SRobert Watson void
131869bbb5b1SRobert Watson mac_thread_userret(struct thread *td)
131969bbb5b1SRobert Watson {
132069bbb5b1SRobert Watson 
132169bbb5b1SRobert Watson 	MAC_PERFORM(thread_userret, td);
132269bbb5b1SRobert Watson }
132369bbb5b1SRobert Watson 
132469bbb5b1SRobert Watson /*
132569bbb5b1SRobert Watson  * When a new process is created, its label must be initialized.  Generally,
132669bbb5b1SRobert Watson  * this involves inheritence from the parent process, modulo possible
132769bbb5b1SRobert Watson  * deltas.  This function allows that processing to take place.
132869bbb5b1SRobert Watson  */
132969bbb5b1SRobert Watson void
133069bbb5b1SRobert Watson mac_create_cred(struct ucred *parent_cred, struct ucred *child_cred)
133169bbb5b1SRobert Watson {
133269bbb5b1SRobert Watson 
133369bbb5b1SRobert Watson 	MAC_PERFORM(create_cred, parent_cred, child_cred);
133469bbb5b1SRobert Watson }
133569bbb5b1SRobert Watson 
133695fab37eSRobert Watson void
1337990b4b2dSRobert Watson mac_update_devfsdirent(struct mount *mp, struct devfs_dirent *de,
1338990b4b2dSRobert Watson     struct vnode *vp)
133995fab37eSRobert Watson {
134095fab37eSRobert Watson 
1341990b4b2dSRobert Watson 	MAC_PERFORM(update_devfsdirent, mp, de, &de->de_label, vp,
1342990b4b2dSRobert Watson 	    &vp->v_label);
134395fab37eSRobert Watson }
134495fab37eSRobert Watson 
134595fab37eSRobert Watson void
1346763bbd2fSRobert Watson mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de,
1347763bbd2fSRobert Watson     struct vnode *vp)
134895fab37eSRobert Watson {
134995fab37eSRobert Watson 
1350763bbd2fSRobert Watson 	MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de,
1351763bbd2fSRobert Watson 	    &de->de_label, vp, &vp->v_label);
135295fab37eSRobert Watson }
135395fab37eSRobert Watson 
1354763bbd2fSRobert Watson int
1355763bbd2fSRobert Watson mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp)
135695fab37eSRobert Watson {
135795fab37eSRobert Watson 	int error;
135895fab37eSRobert Watson 
1359763bbd2fSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr");
1360763bbd2fSRobert Watson 
1361763bbd2fSRobert Watson 	MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp,
1362763bbd2fSRobert Watson 	    &vp->v_label);
136395fab37eSRobert Watson 
136495fab37eSRobert Watson 	return (error);
136595fab37eSRobert Watson }
136695fab37eSRobert Watson 
136795fab37eSRobert Watson void
1368763bbd2fSRobert Watson mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp)
136995fab37eSRobert Watson {
137095fab37eSRobert Watson 
1371763bbd2fSRobert Watson 	MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp,
1372763bbd2fSRobert Watson 	    &vp->v_label);
137395fab37eSRobert Watson }
137495fab37eSRobert Watson 
137595fab37eSRobert Watson int
1376763bbd2fSRobert Watson mac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
1377763bbd2fSRobert Watson     struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
137895fab37eSRobert Watson {
1379763bbd2fSRobert Watson 	int error;
138095fab37eSRobert Watson 
1381763bbd2fSRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr");
1382763bbd2fSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr");
138395fab37eSRobert Watson 
1384763bbd2fSRobert Watson 	error = VOP_OPENEXTATTR(vp, cred, curthread);
1385763bbd2fSRobert Watson 	if (error == EOPNOTSUPP) {
1386763bbd2fSRobert Watson 		/* XXX: Optionally abort if transactions not supported. */
1387763bbd2fSRobert Watson 		if (ea_warn_once == 0) {
1388763bbd2fSRobert Watson 			printf("Warning: transactions not supported "
1389763bbd2fSRobert Watson 			    "in EA write.\n");
1390763bbd2fSRobert Watson 			ea_warn_once = 1;
1391763bbd2fSRobert Watson 		}
1392763bbd2fSRobert Watson 	} else if (error)
139395fab37eSRobert Watson 		return (error);
139495fab37eSRobert Watson 
1395763bbd2fSRobert Watson 	MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel,
1396763bbd2fSRobert Watson 	    dvp, &dvp->v_label, vp, &vp->v_label, cnp);
139795fab37eSRobert Watson 
1398763bbd2fSRobert Watson 	if (error) {
1399763bbd2fSRobert Watson 		VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
140095fab37eSRobert Watson 		return (error);
140195fab37eSRobert Watson 	}
140295fab37eSRobert Watson 
1403763bbd2fSRobert Watson 	error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
140495fab37eSRobert Watson 
1405763bbd2fSRobert Watson 	if (error == EOPNOTSUPP)
1406763bbd2fSRobert Watson 		error = 0;				/* XXX */
140795fab37eSRobert Watson 
140895fab37eSRobert Watson 	return (error);
140995fab37eSRobert Watson }
141095fab37eSRobert Watson 
141195fab37eSRobert Watson static int
1412763bbd2fSRobert Watson mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
1413763bbd2fSRobert Watson     struct label *intlabel)
141495fab37eSRobert Watson {
141595fab37eSRobert Watson 	int error;
141695fab37eSRobert Watson 
1417763bbd2fSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr");
141895fab37eSRobert Watson 
1419763bbd2fSRobert Watson 	error = VOP_OPENEXTATTR(vp, cred, curthread);
1420763bbd2fSRobert Watson 	if (error == EOPNOTSUPP) {
1421763bbd2fSRobert Watson 		/* XXX: Optionally abort if transactions not supported. */
1422763bbd2fSRobert Watson 		if (ea_warn_once == 0) {
1423763bbd2fSRobert Watson 			printf("Warning: transactions not supported "
1424763bbd2fSRobert Watson 			    "in EA write.\n");
1425763bbd2fSRobert Watson 			ea_warn_once = 1;
142695fab37eSRobert Watson 		}
1427763bbd2fSRobert Watson 	} else if (error)
142895fab37eSRobert Watson 		return (error);
142995fab37eSRobert Watson 
1430763bbd2fSRobert Watson 	MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel);
143195fab37eSRobert Watson 
1432763bbd2fSRobert Watson 	if (error) {
1433763bbd2fSRobert Watson 		VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
143495fab37eSRobert Watson 		return (error);
143595fab37eSRobert Watson 	}
143695fab37eSRobert Watson 
1437763bbd2fSRobert Watson 	error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
1438763bbd2fSRobert Watson 
1439763bbd2fSRobert Watson 	if (error == EOPNOTSUPP)
1440763bbd2fSRobert Watson 		error = 0;				/* XXX */
1441763bbd2fSRobert Watson 
1442763bbd2fSRobert Watson 	return (error);
144395fab37eSRobert Watson }
144495fab37eSRobert Watson 
1445670cb89bSRobert Watson int
1446670cb89bSRobert Watson mac_execve_enter(struct image_params *imgp, struct mac *mac_p,
1447670cb89bSRobert Watson     struct label *execlabelstorage)
1448670cb89bSRobert Watson {
1449670cb89bSRobert Watson 	struct mac mac;
1450670cb89bSRobert Watson 	char *buffer;
1451670cb89bSRobert Watson 	int error;
1452670cb89bSRobert Watson 
1453670cb89bSRobert Watson 	if (mac_p == NULL)
1454670cb89bSRobert Watson 		return (0);
1455670cb89bSRobert Watson 
1456670cb89bSRobert Watson 	error = copyin(mac_p, &mac, sizeof(mac));
1457670cb89bSRobert Watson 	if (error)
1458670cb89bSRobert Watson 		return (error);
1459670cb89bSRobert Watson 
1460670cb89bSRobert Watson 	error = mac_check_structmac_consistent(&mac);
1461670cb89bSRobert Watson 	if (error)
1462670cb89bSRobert Watson 		return (error);
1463670cb89bSRobert Watson 
1464a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
1465670cb89bSRobert Watson 	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
1466670cb89bSRobert Watson 	if (error) {
1467670cb89bSRobert Watson 		free(buffer, M_MACTEMP);
1468670cb89bSRobert Watson 		return (error);
1469670cb89bSRobert Watson 	}
1470670cb89bSRobert Watson 
1471670cb89bSRobert Watson 	mac_init_cred_label(execlabelstorage);
1472670cb89bSRobert Watson 	error = mac_internalize_cred_label(execlabelstorage, buffer);
1473670cb89bSRobert Watson 	free(buffer, M_MACTEMP);
1474670cb89bSRobert Watson 	if (error) {
1475670cb89bSRobert Watson 		mac_destroy_cred_label(execlabelstorage);
1476670cb89bSRobert Watson 		return (error);
1477670cb89bSRobert Watson 	}
1478670cb89bSRobert Watson 	imgp->execlabel = execlabelstorage;
1479670cb89bSRobert Watson 	return (0);
1480670cb89bSRobert Watson }
1481670cb89bSRobert Watson 
148295fab37eSRobert Watson void
1483670cb89bSRobert Watson mac_execve_exit(struct image_params *imgp)
1484670cb89bSRobert Watson {
1485670cb89bSRobert Watson 	if (imgp->execlabel != NULL)
1486670cb89bSRobert Watson 		mac_destroy_cred_label(imgp->execlabel);
1487670cb89bSRobert Watson }
1488670cb89bSRobert Watson 
1489670cb89bSRobert Watson void
1490670cb89bSRobert Watson mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp,
1491670cb89bSRobert Watson     struct label *interpvnodelabel, struct image_params *imgp)
149295fab37eSRobert Watson {
149395fab37eSRobert Watson 
149495fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_execve_transition");
149595fab37eSRobert Watson 
14964443e9ffSRobert Watson 	if (!mac_enforce_process && !mac_enforce_fs)
14974443e9ffSRobert Watson 		return;
14984443e9ffSRobert Watson 
1499670cb89bSRobert Watson 	MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label,
15009fa3506eSRobert Watson 	    interpvnodelabel, imgp, imgp->execlabel);
150195fab37eSRobert Watson }
150295fab37eSRobert Watson 
150395fab37eSRobert Watson int
1504670cb89bSRobert Watson mac_execve_will_transition(struct ucred *old, struct vnode *vp,
1505670cb89bSRobert Watson     struct label *interpvnodelabel, struct image_params *imgp)
150695fab37eSRobert Watson {
1507763bbd2fSRobert Watson 	int result;
150895fab37eSRobert Watson 
15094443e9ffSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_execve_will_transition");
15104443e9ffSRobert Watson 
15114443e9ffSRobert Watson 	if (!mac_enforce_process && !mac_enforce_fs)
15124443e9ffSRobert Watson 		return (0);
15134443e9ffSRobert Watson 
151495fab37eSRobert Watson 	result = 0;
1515670cb89bSRobert Watson 	MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label,
15169fa3506eSRobert Watson 	    interpvnodelabel, imgp, imgp->execlabel);
151795fab37eSRobert Watson 
151895fab37eSRobert Watson 	return (result);
151995fab37eSRobert Watson }
152095fab37eSRobert Watson 
152195fab37eSRobert Watson int
1522b914de36SRobert Watson mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode)
152395fab37eSRobert Watson {
152495fab37eSRobert Watson 	int error;
152595fab37eSRobert Watson 
152695fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access");
152795fab37eSRobert Watson 
152895fab37eSRobert Watson 	if (!mac_enforce_fs)
152995fab37eSRobert Watson 		return (0);
153095fab37eSRobert Watson 
1531b914de36SRobert Watson 	MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, acc_mode);
153295fab37eSRobert Watson 	return (error);
153395fab37eSRobert Watson }
153495fab37eSRobert Watson 
153595fab37eSRobert Watson int
153695fab37eSRobert Watson mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp)
153795fab37eSRobert Watson {
153895fab37eSRobert Watson 	int error;
153995fab37eSRobert Watson 
154095fab37eSRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir");
154195fab37eSRobert Watson 
154295fab37eSRobert Watson 	if (!mac_enforce_fs)
154395fab37eSRobert Watson 		return (0);
154495fab37eSRobert Watson 
154595fab37eSRobert Watson 	MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label);
154695fab37eSRobert Watson 	return (error);
154795fab37eSRobert Watson }
154895fab37eSRobert Watson 
154995fab37eSRobert Watson int
155095fab37eSRobert Watson mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp)
155195fab37eSRobert Watson {
155295fab37eSRobert Watson 	int error;
155395fab37eSRobert Watson 
155495fab37eSRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot");
155595fab37eSRobert Watson 
155695fab37eSRobert Watson 	if (!mac_enforce_fs)
155795fab37eSRobert Watson 		return (0);
155895fab37eSRobert Watson 
155995fab37eSRobert Watson 	MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label);
156095fab37eSRobert Watson 	return (error);
156195fab37eSRobert Watson }
156295fab37eSRobert Watson 
156395fab37eSRobert Watson int
156495fab37eSRobert Watson mac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
156595fab37eSRobert Watson     struct componentname *cnp, struct vattr *vap)
156695fab37eSRobert Watson {
156795fab37eSRobert Watson 	int error;
156895fab37eSRobert Watson 
156995fab37eSRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create");
157095fab37eSRobert Watson 
157195fab37eSRobert Watson 	if (!mac_enforce_fs)
157295fab37eSRobert Watson 		return (0);
157395fab37eSRobert Watson 
157495fab37eSRobert Watson 	MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap);
157595fab37eSRobert Watson 	return (error);
157695fab37eSRobert Watson }
157795fab37eSRobert Watson 
157895fab37eSRobert Watson int
157995fab37eSRobert Watson mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp,
158095fab37eSRobert Watson     struct componentname *cnp)
158195fab37eSRobert Watson {
158295fab37eSRobert Watson 	int error;
158395fab37eSRobert Watson 
158495fab37eSRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete");
158595fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete");
158695fab37eSRobert Watson 
158795fab37eSRobert Watson 	if (!mac_enforce_fs)
158895fab37eSRobert Watson 		return (0);
158995fab37eSRobert Watson 
159095fab37eSRobert Watson 	MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp,
159195fab37eSRobert Watson 	    &vp->v_label, cnp);
159295fab37eSRobert Watson 	return (error);
159395fab37eSRobert Watson }
159495fab37eSRobert Watson 
159595fab37eSRobert Watson int
159695fab37eSRobert Watson mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
159795fab37eSRobert Watson     acl_type_t type)
159895fab37eSRobert Watson {
159995fab37eSRobert Watson 	int error;
160095fab37eSRobert Watson 
160195fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl");
160295fab37eSRobert Watson 
160395fab37eSRobert Watson 	if (!mac_enforce_fs)
160495fab37eSRobert Watson 		return (0);
160595fab37eSRobert Watson 
160695fab37eSRobert Watson 	MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type);
160795fab37eSRobert Watson 	return (error);
160895fab37eSRobert Watson }
160995fab37eSRobert Watson 
161095fab37eSRobert Watson int
1611c096756cSRobert Watson mac_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
1612c096756cSRobert Watson     int attrnamespace, const char *name)
1613c096756cSRobert Watson {
1614c096756cSRobert Watson 	int error;
1615c096756cSRobert Watson 
1616c096756cSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteextattr");
1617c096756cSRobert Watson 
1618c096756cSRobert Watson 	if (!mac_enforce_fs)
1619c096756cSRobert Watson 		return (0);
1620c096756cSRobert Watson 
1621c096756cSRobert Watson 	MAC_CHECK(check_vnode_deleteextattr, cred, vp, &vp->v_label,
1622c096756cSRobert Watson 	    attrnamespace, name);
1623c096756cSRobert Watson 	return (error);
1624c096756cSRobert Watson }
1625c096756cSRobert Watson 
1626c096756cSRobert Watson int
1627670cb89bSRobert Watson mac_check_vnode_exec(struct ucred *cred, struct vnode *vp,
1628670cb89bSRobert Watson     struct image_params *imgp)
162995fab37eSRobert Watson {
163095fab37eSRobert Watson 	int error;
163195fab37eSRobert Watson 
1632851704bbSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec");
1633851704bbSRobert Watson 
163495fab37eSRobert Watson 	if (!mac_enforce_process && !mac_enforce_fs)
163595fab37eSRobert Watson 		return (0);
163695fab37eSRobert Watson 
16379fa3506eSRobert Watson 	MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label, imgp,
16389fa3506eSRobert Watson 	    imgp->execlabel);
163995fab37eSRobert Watson 
164095fab37eSRobert Watson 	return (error);
164195fab37eSRobert Watson }
164295fab37eSRobert Watson 
164395fab37eSRobert Watson int
164495fab37eSRobert Watson mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
164595fab37eSRobert Watson {
164695fab37eSRobert Watson 	int error;
164795fab37eSRobert Watson 
164895fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl");
164995fab37eSRobert Watson 
165095fab37eSRobert Watson 	if (!mac_enforce_fs)
165195fab37eSRobert Watson 		return (0);
165295fab37eSRobert Watson 
165395fab37eSRobert Watson 	MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type);
165495fab37eSRobert Watson 	return (error);
165595fab37eSRobert Watson }
165695fab37eSRobert Watson 
165795fab37eSRobert Watson int
165895fab37eSRobert Watson mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
165995fab37eSRobert Watson     int attrnamespace, const char *name, struct uio *uio)
166095fab37eSRobert Watson {
166195fab37eSRobert Watson 	int error;
166295fab37eSRobert Watson 
166395fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr");
166495fab37eSRobert Watson 
166595fab37eSRobert Watson 	if (!mac_enforce_fs)
166695fab37eSRobert Watson 		return (0);
166795fab37eSRobert Watson 
166895fab37eSRobert Watson 	MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label,
166995fab37eSRobert Watson 	    attrnamespace, name, uio);
167095fab37eSRobert Watson 	return (error);
167195fab37eSRobert Watson }
167295fab37eSRobert Watson 
167395fab37eSRobert Watson int
16740a694196SRobert Watson mac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
16750a694196SRobert Watson     struct vnode *vp, struct componentname *cnp)
16760a694196SRobert Watson {
16770a694196SRobert Watson 	int error;
16780a694196SRobert Watson 
16790a694196SRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link");
16800a694196SRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link");
16810a694196SRobert Watson 
16820a694196SRobert Watson 	if (!mac_enforce_fs)
16830a694196SRobert Watson 		return (0);
16840a694196SRobert Watson 
16850a694196SRobert Watson 	MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp,
16860a694196SRobert Watson 	    &vp->v_label, cnp);
16870a694196SRobert Watson 	return (error);
16880a694196SRobert Watson }
16890a694196SRobert Watson 
16900a694196SRobert Watson int
1691c096756cSRobert Watson mac_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
1692c096756cSRobert Watson     int attrnamespace)
1693c096756cSRobert Watson {
1694c096756cSRobert Watson 	int error;
1695c096756cSRobert Watson 
1696c096756cSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_listextattr");
1697c096756cSRobert Watson 
1698c096756cSRobert Watson 	if (!mac_enforce_fs)
1699c096756cSRobert Watson 		return (0);
1700c096756cSRobert Watson 
1701c096756cSRobert Watson 	MAC_CHECK(check_vnode_listextattr, cred, vp, &vp->v_label,
1702c096756cSRobert Watson 	    attrnamespace);
1703c096756cSRobert Watson 	return (error);
1704c096756cSRobert Watson }
1705c096756cSRobert Watson 
1706c096756cSRobert Watson int
170795fab37eSRobert Watson mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
170895fab37eSRobert Watson     struct componentname *cnp)
170995fab37eSRobert Watson {
171095fab37eSRobert Watson 	int error;
171195fab37eSRobert Watson 
171295fab37eSRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup");
171395fab37eSRobert Watson 
171495fab37eSRobert Watson 	if (!mac_enforce_fs)
171595fab37eSRobert Watson 		return (0);
171695fab37eSRobert Watson 
171795fab37eSRobert Watson 	MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp);
171895fab37eSRobert Watson 	return (error);
171995fab37eSRobert Watson }
172095fab37eSRobert Watson 
1721e183f80eSRobert Watson int
1722e183f80eSRobert Watson mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot)
172395fab37eSRobert Watson {
1724e183f80eSRobert Watson 	int error;
172595fab37eSRobert Watson 
1726e183f80eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap");
1727ca7850c3SRobert Watson 
1728e183f80eSRobert Watson 	if (!mac_enforce_fs || !mac_enforce_vm)
1729e183f80eSRobert Watson 		return (0);
1730e183f80eSRobert Watson 
1731e183f80eSRobert Watson 	MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot);
1732e183f80eSRobert Watson 	return (error);
1733e183f80eSRobert Watson }
1734e183f80eSRobert Watson 
1735e183f80eSRobert Watson void
1736e183f80eSRobert Watson mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot)
1737e183f80eSRobert Watson {
1738e183f80eSRobert Watson 	int result = *prot;
1739e183f80eSRobert Watson 
1740e183f80eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade");
1741e183f80eSRobert Watson 
1742e183f80eSRobert Watson 	if (!mac_enforce_fs || !mac_enforce_vm)
1743e183f80eSRobert Watson 		return;
1744e183f80eSRobert Watson 
1745e183f80eSRobert Watson 	MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label,
1746e183f80eSRobert Watson 	    &result);
1747e183f80eSRobert Watson 
1748e183f80eSRobert Watson 	*prot = result;
1749e183f80eSRobert Watson }
1750e183f80eSRobert Watson 
1751e183f80eSRobert Watson int
1752e183f80eSRobert Watson mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot)
1753e183f80eSRobert Watson {
1754e183f80eSRobert Watson 	int error;
1755e183f80eSRobert Watson 
1756e183f80eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect");
1757e183f80eSRobert Watson 
1758e183f80eSRobert Watson 	if (!mac_enforce_fs || !mac_enforce_vm)
1759e183f80eSRobert Watson 		return (0);
1760e183f80eSRobert Watson 
1761e183f80eSRobert Watson 	MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot);
1762e183f80eSRobert Watson 	return (error);
176395fab37eSRobert Watson }
176495fab37eSRobert Watson 
176595fab37eSRobert Watson int
1766b914de36SRobert Watson mac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode)
176795fab37eSRobert Watson {
176895fab37eSRobert Watson 	int error;
176995fab37eSRobert Watson 
177095fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open");
177195fab37eSRobert Watson 
177295fab37eSRobert Watson 	if (!mac_enforce_fs)
177395fab37eSRobert Watson 		return (0);
177495fab37eSRobert Watson 
177595fab37eSRobert Watson 	MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode);
177695fab37eSRobert Watson 	return (error);
177795fab37eSRobert Watson }
177895fab37eSRobert Watson 
177995fab37eSRobert Watson int
1780177142e4SRobert Watson mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
1781177142e4SRobert Watson     struct vnode *vp)
17827f724f8bSRobert Watson {
17837f724f8bSRobert Watson 	int error;
17847f724f8bSRobert Watson 
17857f724f8bSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll");
17867f724f8bSRobert Watson 
17877f724f8bSRobert Watson 	if (!mac_enforce_fs)
17887f724f8bSRobert Watson 		return (0);
17897f724f8bSRobert Watson 
1790177142e4SRobert Watson 	MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp,
1791177142e4SRobert Watson 	    &vp->v_label);
17927f724f8bSRobert Watson 
17937f724f8bSRobert Watson 	return (error);
17947f724f8bSRobert Watson }
17957f724f8bSRobert Watson 
17967f724f8bSRobert Watson int
1797177142e4SRobert Watson mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
1798177142e4SRobert Watson     struct vnode *vp)
17997f724f8bSRobert Watson {
18007f724f8bSRobert Watson 	int error;
18017f724f8bSRobert Watson 
18027f724f8bSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read");
18037f724f8bSRobert Watson 
18047f724f8bSRobert Watson 	if (!mac_enforce_fs)
18057f724f8bSRobert Watson 		return (0);
18067f724f8bSRobert Watson 
1807177142e4SRobert Watson 	MAC_CHECK(check_vnode_read, active_cred, file_cred, vp,
1808177142e4SRobert Watson 	    &vp->v_label);
18097f724f8bSRobert Watson 
18107f724f8bSRobert Watson 	return (error);
18117f724f8bSRobert Watson }
18127f724f8bSRobert Watson 
18137f724f8bSRobert Watson int
181495fab37eSRobert Watson mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp)
181595fab37eSRobert Watson {
181695fab37eSRobert Watson 	int error;
181795fab37eSRobert Watson 
181895fab37eSRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir");
181995fab37eSRobert Watson 
182095fab37eSRobert Watson 	if (!mac_enforce_fs)
182195fab37eSRobert Watson 		return (0);
182295fab37eSRobert Watson 
182395fab37eSRobert Watson 	MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label);
182495fab37eSRobert Watson 	return (error);
182595fab37eSRobert Watson }
182695fab37eSRobert Watson 
182795fab37eSRobert Watson int
182895fab37eSRobert Watson mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp)
182995fab37eSRobert Watson {
183095fab37eSRobert Watson 	int error;
183195fab37eSRobert Watson 
183295fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink");
183395fab37eSRobert Watson 
183495fab37eSRobert Watson 	if (!mac_enforce_fs)
183595fab37eSRobert Watson 		return (0);
183695fab37eSRobert Watson 
183795fab37eSRobert Watson 	MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label);
183895fab37eSRobert Watson 	return (error);
183995fab37eSRobert Watson }
184095fab37eSRobert Watson 
184195fab37eSRobert Watson static int
184295fab37eSRobert Watson mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
184395fab37eSRobert Watson     struct label *newlabel)
184495fab37eSRobert Watson {
184595fab37eSRobert Watson 	int error;
184695fab37eSRobert Watson 
184795fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel");
184895fab37eSRobert Watson 
184995fab37eSRobert Watson 	MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel);
185095fab37eSRobert Watson 
185195fab37eSRobert Watson 	return (error);
185295fab37eSRobert Watson }
185395fab37eSRobert Watson 
185495fab37eSRobert Watson int
185595fab37eSRobert Watson mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
185695fab37eSRobert Watson     struct vnode *vp, struct componentname *cnp)
185795fab37eSRobert Watson {
185895fab37eSRobert Watson 	int error;
185995fab37eSRobert Watson 
186095fab37eSRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from");
186195fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from");
186295fab37eSRobert Watson 
186395fab37eSRobert Watson 	if (!mac_enforce_fs)
186495fab37eSRobert Watson 		return (0);
186595fab37eSRobert Watson 
186695fab37eSRobert Watson 	MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp,
186795fab37eSRobert Watson 	    &vp->v_label, cnp);
186895fab37eSRobert Watson 	return (error);
186995fab37eSRobert Watson }
187095fab37eSRobert Watson 
187195fab37eSRobert Watson int
187295fab37eSRobert Watson mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
187395fab37eSRobert Watson     struct vnode *vp, int samedir, struct componentname *cnp)
187495fab37eSRobert Watson {
187595fab37eSRobert Watson 	int error;
187695fab37eSRobert Watson 
187795fab37eSRobert Watson 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to");
187895fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to");
187995fab37eSRobert Watson 
188095fab37eSRobert Watson 	if (!mac_enforce_fs)
188195fab37eSRobert Watson 		return (0);
188295fab37eSRobert Watson 
188395fab37eSRobert Watson 	MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp,
188495fab37eSRobert Watson 	    vp != NULL ? &vp->v_label : NULL, samedir, cnp);
188595fab37eSRobert Watson 	return (error);
188695fab37eSRobert Watson }
188795fab37eSRobert Watson 
188895fab37eSRobert Watson int
188995fab37eSRobert Watson mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp)
189095fab37eSRobert Watson {
189195fab37eSRobert Watson 	int error;
189295fab37eSRobert Watson 
189395fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke");
189495fab37eSRobert Watson 
189595fab37eSRobert Watson 	if (!mac_enforce_fs)
189695fab37eSRobert Watson 		return (0);
189795fab37eSRobert Watson 
189895fab37eSRobert Watson 	MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label);
189995fab37eSRobert Watson 	return (error);
190095fab37eSRobert Watson }
190195fab37eSRobert Watson 
190295fab37eSRobert Watson int
190395fab37eSRobert Watson mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
190495fab37eSRobert Watson     struct acl *acl)
190595fab37eSRobert Watson {
190695fab37eSRobert Watson 	int error;
190795fab37eSRobert Watson 
190895fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl");
190995fab37eSRobert Watson 
191095fab37eSRobert Watson 	if (!mac_enforce_fs)
191195fab37eSRobert Watson 		return (0);
191295fab37eSRobert Watson 
191395fab37eSRobert Watson 	MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl);
191495fab37eSRobert Watson 	return (error);
191595fab37eSRobert Watson }
191695fab37eSRobert Watson 
191795fab37eSRobert Watson int
191895fab37eSRobert Watson mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
191995fab37eSRobert Watson     int attrnamespace, const char *name, struct uio *uio)
192095fab37eSRobert Watson {
192195fab37eSRobert Watson 	int error;
192295fab37eSRobert Watson 
192395fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr");
192495fab37eSRobert Watson 
192595fab37eSRobert Watson 	if (!mac_enforce_fs)
192695fab37eSRobert Watson 		return (0);
192795fab37eSRobert Watson 
192895fab37eSRobert Watson 	MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label,
192995fab37eSRobert Watson 	    attrnamespace, name, uio);
193095fab37eSRobert Watson 	return (error);
193195fab37eSRobert Watson }
193295fab37eSRobert Watson 
193395fab37eSRobert Watson int
193495fab37eSRobert Watson mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
193595fab37eSRobert Watson {
193695fab37eSRobert Watson 	int error;
193795fab37eSRobert Watson 
193895fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags");
193995fab37eSRobert Watson 
194095fab37eSRobert Watson 	if (!mac_enforce_fs)
194195fab37eSRobert Watson 		return (0);
194295fab37eSRobert Watson 
194395fab37eSRobert Watson 	MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags);
194495fab37eSRobert Watson 	return (error);
194595fab37eSRobert Watson }
194695fab37eSRobert Watson 
194795fab37eSRobert Watson int
194895fab37eSRobert Watson mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
194995fab37eSRobert Watson {
195095fab37eSRobert Watson 	int error;
195195fab37eSRobert Watson 
195295fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode");
195395fab37eSRobert Watson 
195495fab37eSRobert Watson 	if (!mac_enforce_fs)
195595fab37eSRobert Watson 		return (0);
195695fab37eSRobert Watson 
195795fab37eSRobert Watson 	MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode);
195895fab37eSRobert Watson 	return (error);
195995fab37eSRobert Watson }
196095fab37eSRobert Watson 
196195fab37eSRobert Watson int
196295fab37eSRobert Watson mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
196395fab37eSRobert Watson     gid_t gid)
196495fab37eSRobert Watson {
196595fab37eSRobert Watson 	int error;
196695fab37eSRobert Watson 
196795fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner");
196895fab37eSRobert Watson 
196995fab37eSRobert Watson 	if (!mac_enforce_fs)
197095fab37eSRobert Watson 		return (0);
197195fab37eSRobert Watson 
197295fab37eSRobert Watson 	MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid);
197395fab37eSRobert Watson 	return (error);
197495fab37eSRobert Watson }
197595fab37eSRobert Watson 
197695fab37eSRobert Watson int
197795fab37eSRobert Watson mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
197895fab37eSRobert Watson     struct timespec atime, struct timespec mtime)
197995fab37eSRobert Watson {
198095fab37eSRobert Watson 	int error;
198195fab37eSRobert Watson 
198295fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes");
198395fab37eSRobert Watson 
198495fab37eSRobert Watson 	if (!mac_enforce_fs)
198595fab37eSRobert Watson 		return (0);
198695fab37eSRobert Watson 
198795fab37eSRobert Watson 	MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime,
198895fab37eSRobert Watson 	    mtime);
198995fab37eSRobert Watson 	return (error);
199095fab37eSRobert Watson }
199195fab37eSRobert Watson 
199295fab37eSRobert Watson int
1993177142e4SRobert Watson mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
1994177142e4SRobert Watson     struct vnode *vp)
199595fab37eSRobert Watson {
199695fab37eSRobert Watson 	int error;
199795fab37eSRobert Watson 
199895fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat");
199995fab37eSRobert Watson 
200095fab37eSRobert Watson 	if (!mac_enforce_fs)
200195fab37eSRobert Watson 		return (0);
200295fab37eSRobert Watson 
2003177142e4SRobert Watson 	MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp,
2004177142e4SRobert Watson 	    &vp->v_label);
200595fab37eSRobert Watson 	return (error);
200695fab37eSRobert Watson }
200795fab37eSRobert Watson 
20087f724f8bSRobert Watson int
2009177142e4SRobert Watson mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
2010177142e4SRobert Watson     struct vnode *vp)
20117f724f8bSRobert Watson {
20127f724f8bSRobert Watson 	int error;
20137f724f8bSRobert Watson 
20147f724f8bSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write");
20157f724f8bSRobert Watson 
20167f724f8bSRobert Watson 	if (!mac_enforce_fs)
20177f724f8bSRobert Watson 		return (0);
20187f724f8bSRobert Watson 
2019177142e4SRobert Watson 	MAC_CHECK(check_vnode_write, active_cred, file_cred, vp,
2020177142e4SRobert Watson 	    &vp->v_label);
20217f724f8bSRobert Watson 
20227f724f8bSRobert Watson 	return (error);
20237f724f8bSRobert Watson }
20247f724f8bSRobert Watson 
202595fab37eSRobert Watson /*
202695fab37eSRobert Watson  * When relabeling a process, call out to the policies for the maximum
202795fab37eSRobert Watson  * permission allowed for each object type we know about in its
202895fab37eSRobert Watson  * memory space, and revoke access (in the least surprising ways we
202995fab37eSRobert Watson  * know) when necessary.  The process lock is not held here.
203095fab37eSRobert Watson  */
20314d10c0ceSRobert Watson void
203295fab37eSRobert Watson mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred)
203395fab37eSRobert Watson {
203495fab37eSRobert Watson 
203595fab37eSRobert Watson 	/* XXX freeze all other threads */
203695fab37eSRobert Watson 	mac_cred_mmapped_drop_perms_recurse(td, cred,
203795fab37eSRobert Watson 	    &td->td_proc->p_vmspace->vm_map);
203895fab37eSRobert Watson 	/* XXX allow other threads to continue */
203995fab37eSRobert Watson }
204095fab37eSRobert Watson 
204195fab37eSRobert Watson static __inline const char *
204295fab37eSRobert Watson prot2str(vm_prot_t prot)
204395fab37eSRobert Watson {
204495fab37eSRobert Watson 
204595fab37eSRobert Watson 	switch (prot & VM_PROT_ALL) {
204695fab37eSRobert Watson 	case VM_PROT_READ:
204795fab37eSRobert Watson 		return ("r--");
204895fab37eSRobert Watson 	case VM_PROT_READ | VM_PROT_WRITE:
204995fab37eSRobert Watson 		return ("rw-");
205095fab37eSRobert Watson 	case VM_PROT_READ | VM_PROT_EXECUTE:
205195fab37eSRobert Watson 		return ("r-x");
205295fab37eSRobert Watson 	case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
205395fab37eSRobert Watson 		return ("rwx");
205495fab37eSRobert Watson 	case VM_PROT_WRITE:
205595fab37eSRobert Watson 		return ("-w-");
205695fab37eSRobert Watson 	case VM_PROT_EXECUTE:
205795fab37eSRobert Watson 		return ("--x");
205895fab37eSRobert Watson 	case VM_PROT_WRITE | VM_PROT_EXECUTE:
205995fab37eSRobert Watson 		return ("-wx");
206095fab37eSRobert Watson 	default:
206195fab37eSRobert Watson 		return ("---");
206295fab37eSRobert Watson 	}
206395fab37eSRobert Watson }
206495fab37eSRobert Watson 
206595fab37eSRobert Watson static void
206695fab37eSRobert Watson mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred,
206795fab37eSRobert Watson     struct vm_map *map)
206895fab37eSRobert Watson {
206995fab37eSRobert Watson 	struct vm_map_entry *vme;
2070e183f80eSRobert Watson 	int result;
2071e183f80eSRobert Watson 	vm_prot_t revokeperms;
207295fab37eSRobert Watson 	vm_object_t object;
207395fab37eSRobert Watson 	vm_ooffset_t offset;
207495fab37eSRobert Watson 	struct vnode *vp;
207595fab37eSRobert Watson 
2076c0f39905SRobert Watson 	if (!mac_mmap_revocation)
2077c0f39905SRobert Watson 		return;
2078c0f39905SRobert Watson 
207995fab37eSRobert Watson 	vm_map_lock_read(map);
208095fab37eSRobert Watson 	for (vme = map->header.next; vme != &map->header; vme = vme->next) {
208195fab37eSRobert Watson 		if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) {
208295fab37eSRobert Watson 			mac_cred_mmapped_drop_perms_recurse(td, cred,
208395fab37eSRobert Watson 			    vme->object.sub_map);
208495fab37eSRobert Watson 			continue;
208595fab37eSRobert Watson 		}
208695fab37eSRobert Watson 		/*
208795fab37eSRobert Watson 		 * Skip over entries that obviously are not shared.
208895fab37eSRobert Watson 		 */
208995fab37eSRobert Watson 		if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) ||
209095fab37eSRobert Watson 		    !vme->max_protection)
209195fab37eSRobert Watson 			continue;
209295fab37eSRobert Watson 		/*
209395fab37eSRobert Watson 		 * Drill down to the deepest backing object.
209495fab37eSRobert Watson 		 */
209595fab37eSRobert Watson 		offset = vme->offset;
209695fab37eSRobert Watson 		object = vme->object.vm_object;
209795fab37eSRobert Watson 		if (object == NULL)
209895fab37eSRobert Watson 			continue;
209995fab37eSRobert Watson 		while (object->backing_object != NULL) {
210095fab37eSRobert Watson 			object = object->backing_object;
210195fab37eSRobert Watson 			offset += object->backing_object_offset;
210295fab37eSRobert Watson 		}
210395fab37eSRobert Watson 		/*
210495fab37eSRobert Watson 		 * At the moment, vm_maps and objects aren't considered
210595fab37eSRobert Watson 		 * by the MAC system, so only things with backing by a
210695fab37eSRobert Watson 		 * normal object (read: vnodes) are checked.
210795fab37eSRobert Watson 		 */
210895fab37eSRobert Watson 		if (object->type != OBJT_VNODE)
210995fab37eSRobert Watson 			continue;
211095fab37eSRobert Watson 		vp = (struct vnode *)object->handle;
211195fab37eSRobert Watson 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2112e183f80eSRobert Watson 		result = vme->max_protection;
2113e183f80eSRobert Watson 		mac_check_vnode_mmap_downgrade(cred, vp, &result);
211495fab37eSRobert Watson 		VOP_UNLOCK(vp, 0, td);
211595fab37eSRobert Watson 		/*
211695fab37eSRobert Watson 		 * Find out what maximum protection we may be allowing
211795fab37eSRobert Watson 		 * now but a policy needs to get removed.
211895fab37eSRobert Watson 		 */
211995fab37eSRobert Watson 		revokeperms = vme->max_protection & ~result;
212095fab37eSRobert Watson 		if (!revokeperms)
212195fab37eSRobert Watson 			continue;
2122b656366bSBruce Evans 		printf("pid %ld: revoking %s perms from %#lx:%ld "
2123b656366bSBruce Evans 		    "(max %s/cur %s)\n", (long)td->td_proc->p_pid,
2124b656366bSBruce Evans 		    prot2str(revokeperms), (u_long)vme->start,
2125b656366bSBruce Evans 		    (long)(vme->end - vme->start),
212695fab37eSRobert Watson 		    prot2str(vme->max_protection), prot2str(vme->protection));
212795fab37eSRobert Watson 		vm_map_lock_upgrade(map);
212895fab37eSRobert Watson 		/*
212995fab37eSRobert Watson 		 * This is the really simple case: if a map has more
213095fab37eSRobert Watson 		 * max_protection than is allowed, but it's not being
213195fab37eSRobert Watson 		 * actually used (that is, the current protection is
213295fab37eSRobert Watson 		 * still allowed), we can just wipe it out and do
213395fab37eSRobert Watson 		 * nothing more.
213495fab37eSRobert Watson 		 */
213595fab37eSRobert Watson 		if ((vme->protection & revokeperms) == 0) {
213695fab37eSRobert Watson 			vme->max_protection -= revokeperms;
213795fab37eSRobert Watson 		} else {
213895fab37eSRobert Watson 			if (revokeperms & VM_PROT_WRITE) {
213995fab37eSRobert Watson 				/*
214095fab37eSRobert Watson 				 * In the more complicated case, flush out all
214195fab37eSRobert Watson 				 * pending changes to the object then turn it
214295fab37eSRobert Watson 				 * copy-on-write.
214395fab37eSRobert Watson 				 */
214495fab37eSRobert Watson 				vm_object_reference(object);
214595fab37eSRobert Watson 				vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2146b6e48e03SAlan Cox 				VM_OBJECT_LOCK(object);
214795fab37eSRobert Watson 				vm_object_page_clean(object,
214895fab37eSRobert Watson 				    OFF_TO_IDX(offset),
214995fab37eSRobert Watson 				    OFF_TO_IDX(offset + vme->end - vme->start +
215095fab37eSRobert Watson 					PAGE_MASK),
215195fab37eSRobert Watson 				    OBJPC_SYNC);
2152b6e48e03SAlan Cox 				VM_OBJECT_UNLOCK(object);
215395fab37eSRobert Watson 				VOP_UNLOCK(vp, 0, td);
215495fab37eSRobert Watson 				vm_object_deallocate(object);
215595fab37eSRobert Watson 				/*
215695fab37eSRobert Watson 				 * Why bother if there's no read permissions
215795fab37eSRobert Watson 				 * anymore?  For the rest, we need to leave
215895fab37eSRobert Watson 				 * the write permissions on for COW, or
215995fab37eSRobert Watson 				 * remove them entirely if configured to.
216095fab37eSRobert Watson 				 */
216195fab37eSRobert Watson 				if (!mac_mmap_revocation_via_cow) {
216295fab37eSRobert Watson 					vme->max_protection &= ~VM_PROT_WRITE;
216395fab37eSRobert Watson 					vme->protection &= ~VM_PROT_WRITE;
216495fab37eSRobert Watson 				} if ((revokeperms & VM_PROT_READ) == 0)
216595fab37eSRobert Watson 					vme->eflags |= MAP_ENTRY_COW |
216695fab37eSRobert Watson 					    MAP_ENTRY_NEEDS_COPY;
216795fab37eSRobert Watson 			}
216895fab37eSRobert Watson 			if (revokeperms & VM_PROT_EXECUTE) {
216995fab37eSRobert Watson 				vme->max_protection &= ~VM_PROT_EXECUTE;
217095fab37eSRobert Watson 				vme->protection &= ~VM_PROT_EXECUTE;
217195fab37eSRobert Watson 			}
217295fab37eSRobert Watson 			if (revokeperms & VM_PROT_READ) {
217395fab37eSRobert Watson 				vme->max_protection = 0;
217495fab37eSRobert Watson 				vme->protection = 0;
217595fab37eSRobert Watson 			}
217695fab37eSRobert Watson 			pmap_protect(map->pmap, vme->start, vme->end,
217795fab37eSRobert Watson 			    vme->protection & ~revokeperms);
217895fab37eSRobert Watson 			vm_map_simplify_entry(map, vme);
217995fab37eSRobert Watson 		}
218095fab37eSRobert Watson 		vm_map_lock_downgrade(map);
218195fab37eSRobert Watson 	}
218295fab37eSRobert Watson 	vm_map_unlock_read(map);
218395fab37eSRobert Watson }
218495fab37eSRobert Watson 
218595fab37eSRobert Watson /*
218695fab37eSRobert Watson  * When the subject's label changes, it may require revocation of privilege
218795fab37eSRobert Watson  * to mapped objects.  This can't be done on-the-fly later with a unified
218895fab37eSRobert Watson  * buffer cache.
218995fab37eSRobert Watson  */
219095fab37eSRobert Watson static void
219195fab37eSRobert Watson mac_relabel_cred(struct ucred *cred, struct label *newlabel)
219295fab37eSRobert Watson {
219395fab37eSRobert Watson 
219495fab37eSRobert Watson 	MAC_PERFORM(relabel_cred, cred, newlabel);
219595fab37eSRobert Watson }
219695fab37eSRobert Watson 
219795fab37eSRobert Watson void
219895fab37eSRobert Watson mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel)
219995fab37eSRobert Watson {
220095fab37eSRobert Watson 
220195fab37eSRobert Watson 	MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel);
220295fab37eSRobert Watson }
220395fab37eSRobert Watson 
220495fab37eSRobert Watson void
220595fab37eSRobert Watson mac_create_ifnet(struct ifnet *ifnet)
220695fab37eSRobert Watson {
220795fab37eSRobert Watson 
220895fab37eSRobert Watson 	MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label);
220995fab37eSRobert Watson }
221095fab37eSRobert Watson 
221195fab37eSRobert Watson void
221295fab37eSRobert Watson mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d)
221395fab37eSRobert Watson {
221495fab37eSRobert Watson 
221595fab37eSRobert Watson 	MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label);
221695fab37eSRobert Watson }
221795fab37eSRobert Watson 
221895fab37eSRobert Watson void
221995fab37eSRobert Watson mac_create_socket(struct ucred *cred, struct socket *socket)
222095fab37eSRobert Watson {
222195fab37eSRobert Watson 
222295fab37eSRobert Watson 	MAC_PERFORM(create_socket, cred, socket, &socket->so_label);
222395fab37eSRobert Watson }
222495fab37eSRobert Watson 
222595fab37eSRobert Watson void
222695fab37eSRobert Watson mac_create_pipe(struct ucred *cred, struct pipe *pipe)
222795fab37eSRobert Watson {
222895fab37eSRobert Watson 
222995fab37eSRobert Watson 	MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label);
223095fab37eSRobert Watson }
223195fab37eSRobert Watson 
223295fab37eSRobert Watson void
223395fab37eSRobert Watson mac_create_socket_from_socket(struct socket *oldsocket,
223495fab37eSRobert Watson     struct socket *newsocket)
223595fab37eSRobert Watson {
223695fab37eSRobert Watson 
223795fab37eSRobert Watson 	MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label,
223895fab37eSRobert Watson 	    newsocket, &newsocket->so_label);
223995fab37eSRobert Watson }
224095fab37eSRobert Watson 
224195fab37eSRobert Watson static void
224295fab37eSRobert Watson mac_relabel_socket(struct ucred *cred, struct socket *socket,
224395fab37eSRobert Watson     struct label *newlabel)
224495fab37eSRobert Watson {
224595fab37eSRobert Watson 
224695fab37eSRobert Watson 	MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel);
224795fab37eSRobert Watson }
224895fab37eSRobert Watson 
224995fab37eSRobert Watson static void
225095fab37eSRobert Watson mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel)
225195fab37eSRobert Watson {
225295fab37eSRobert Watson 
225395fab37eSRobert Watson 	MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel);
225495fab37eSRobert Watson }
225595fab37eSRobert Watson 
225695fab37eSRobert Watson void
225795fab37eSRobert Watson mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket)
225895fab37eSRobert Watson {
225910eeb10cSRobert Watson 	struct label *label;
226095fab37eSRobert Watson 
226110eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
226210eeb10cSRobert Watson 
226310eeb10cSRobert Watson 	MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket,
226410eeb10cSRobert Watson 	    &socket->so_peerlabel);
226595fab37eSRobert Watson }
226695fab37eSRobert Watson 
226795fab37eSRobert Watson void
226895fab37eSRobert Watson mac_set_socket_peer_from_socket(struct socket *oldsocket,
226995fab37eSRobert Watson     struct socket *newsocket)
227095fab37eSRobert Watson {
227195fab37eSRobert Watson 
227295fab37eSRobert Watson 	MAC_PERFORM(set_socket_peer_from_socket, oldsocket,
227395fab37eSRobert Watson 	    &oldsocket->so_label, newsocket, &newsocket->so_peerlabel);
227495fab37eSRobert Watson }
227595fab37eSRobert Watson 
227695fab37eSRobert Watson void
227795fab37eSRobert Watson mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram)
227895fab37eSRobert Watson {
227910eeb10cSRobert Watson 	struct label *label;
228010eeb10cSRobert Watson 
228110eeb10cSRobert Watson 	label = mbuf_to_label(datagram);
228295fab37eSRobert Watson 
228395fab37eSRobert Watson 	MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label,
228410eeb10cSRobert Watson 	    datagram, label);
228595fab37eSRobert Watson }
228695fab37eSRobert Watson 
228795fab37eSRobert Watson void
228895fab37eSRobert Watson mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment)
228995fab37eSRobert Watson {
229010eeb10cSRobert Watson 	struct label *datagramlabel, *fragmentlabel;
229195fab37eSRobert Watson 
229210eeb10cSRobert Watson 	datagramlabel = mbuf_to_label(datagram);
229310eeb10cSRobert Watson 	fragmentlabel = mbuf_to_label(fragment);
229410eeb10cSRobert Watson 
229510eeb10cSRobert Watson 	MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment,
229610eeb10cSRobert Watson 	    fragmentlabel);
229795fab37eSRobert Watson }
229895fab37eSRobert Watson 
229995fab37eSRobert Watson void
230095fab37eSRobert Watson mac_create_ipq(struct mbuf *fragment, struct ipq *ipq)
230195fab37eSRobert Watson {
230210eeb10cSRobert Watson 	struct label *label;
230395fab37eSRobert Watson 
230410eeb10cSRobert Watson 	label = mbuf_to_label(fragment);
230510eeb10cSRobert Watson 
230610eeb10cSRobert Watson 	MAC_PERFORM(create_ipq, fragment, label, ipq, &ipq->ipq_label);
230795fab37eSRobert Watson }
230895fab37eSRobert Watson 
230995fab37eSRobert Watson void
231095fab37eSRobert Watson mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf)
231195fab37eSRobert Watson {
231210eeb10cSRobert Watson 	struct label *oldmbuflabel, *newmbuflabel;
231395fab37eSRobert Watson 
231410eeb10cSRobert Watson 	oldmbuflabel = mbuf_to_label(oldmbuf);
231510eeb10cSRobert Watson 	newmbuflabel = mbuf_to_label(newmbuf);
231610eeb10cSRobert Watson 
231710eeb10cSRobert Watson 	MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf,
231810eeb10cSRobert Watson 	    newmbuflabel);
231995fab37eSRobert Watson }
232095fab37eSRobert Watson 
232195fab37eSRobert Watson void
232295fab37eSRobert Watson mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf)
232395fab37eSRobert Watson {
232410eeb10cSRobert Watson 	struct label *label;
232510eeb10cSRobert Watson 
232610eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
232795fab37eSRobert Watson 
232895fab37eSRobert Watson 	MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf,
232910eeb10cSRobert Watson 	    label);
233095fab37eSRobert Watson }
233195fab37eSRobert Watson 
233295fab37eSRobert Watson void
233395fab37eSRobert Watson mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf)
233495fab37eSRobert Watson {
233510eeb10cSRobert Watson 	struct label *label;
233610eeb10cSRobert Watson 
233710eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
233895fab37eSRobert Watson 
233995fab37eSRobert Watson 	MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf,
234010eeb10cSRobert Watson 	    label);
234195fab37eSRobert Watson }
234295fab37eSRobert Watson 
234395fab37eSRobert Watson void
234495fab37eSRobert Watson mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf)
234595fab37eSRobert Watson {
234610eeb10cSRobert Watson 	struct label *label;
234710eeb10cSRobert Watson 
234810eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
234995fab37eSRobert Watson 
235095fab37eSRobert Watson 	MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf,
235110eeb10cSRobert Watson 	    label);
235295fab37eSRobert Watson }
235395fab37eSRobert Watson 
235495fab37eSRobert Watson void
235595fab37eSRobert Watson mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet,
235695fab37eSRobert Watson     struct mbuf *newmbuf)
235795fab37eSRobert Watson {
235810eeb10cSRobert Watson 	struct label *oldmbuflabel, *newmbuflabel;
235995fab37eSRobert Watson 
236010eeb10cSRobert Watson 	oldmbuflabel = mbuf_to_label(oldmbuf);
236110eeb10cSRobert Watson 	newmbuflabel = mbuf_to_label(newmbuf);
236210eeb10cSRobert Watson 
236310eeb10cSRobert Watson 	MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel,
236410eeb10cSRobert Watson 	    ifnet, &ifnet->if_label, newmbuf, newmbuflabel);
236595fab37eSRobert Watson }
236695fab37eSRobert Watson 
236795fab37eSRobert Watson void
236895fab37eSRobert Watson mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf)
236995fab37eSRobert Watson {
237010eeb10cSRobert Watson 	struct label *oldmbuflabel, *newmbuflabel;
237195fab37eSRobert Watson 
237210eeb10cSRobert Watson 	oldmbuflabel = mbuf_to_label(oldmbuf);
237310eeb10cSRobert Watson 	newmbuflabel = mbuf_to_label(newmbuf);
237410eeb10cSRobert Watson 
237510eeb10cSRobert Watson 	MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf,
237610eeb10cSRobert Watson 	    newmbuflabel);
237795fab37eSRobert Watson }
237895fab37eSRobert Watson 
237995fab37eSRobert Watson int
238095fab37eSRobert Watson mac_fragment_match(struct mbuf *fragment, struct ipq *ipq)
238195fab37eSRobert Watson {
238210eeb10cSRobert Watson 	struct label *label;
238395fab37eSRobert Watson 	int result;
238495fab37eSRobert Watson 
238510eeb10cSRobert Watson 	label = mbuf_to_label(fragment);
238610eeb10cSRobert Watson 
238795fab37eSRobert Watson 	result = 1;
238810eeb10cSRobert Watson 	MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq,
238910eeb10cSRobert Watson 	    &ipq->ipq_label);
239095fab37eSRobert Watson 
239195fab37eSRobert Watson 	return (result);
239295fab37eSRobert Watson }
239395fab37eSRobert Watson 
239495fab37eSRobert Watson void
2395eb8c7f99SRobert Watson mac_reflect_mbuf_icmp(struct mbuf *m)
2396eb8c7f99SRobert Watson {
2397eb8c7f99SRobert Watson 	struct label *label;
2398eb8c7f99SRobert Watson 
2399eb8c7f99SRobert Watson 	label = mbuf_to_label(m);
2400eb8c7f99SRobert Watson 
2401eb8c7f99SRobert Watson 	MAC_PERFORM(reflect_mbuf_icmp, m, label);
2402eb8c7f99SRobert Watson }
2403eb8c7f99SRobert Watson void
2404eb8c7f99SRobert Watson mac_reflect_mbuf_tcp(struct mbuf *m)
2405eb8c7f99SRobert Watson {
2406eb8c7f99SRobert Watson 	struct label *label;
2407eb8c7f99SRobert Watson 
2408eb8c7f99SRobert Watson 	label = mbuf_to_label(m);
2409eb8c7f99SRobert Watson 
2410eb8c7f99SRobert Watson 	MAC_PERFORM(reflect_mbuf_tcp, m, label);
2411eb8c7f99SRobert Watson }
2412eb8c7f99SRobert Watson 
2413eb8c7f99SRobert Watson void
241495fab37eSRobert Watson mac_update_ipq(struct mbuf *fragment, struct ipq *ipq)
241595fab37eSRobert Watson {
241610eeb10cSRobert Watson 	struct label *label;
241795fab37eSRobert Watson 
241810eeb10cSRobert Watson 	label = mbuf_to_label(fragment);
241910eeb10cSRobert Watson 
242010eeb10cSRobert Watson 	MAC_PERFORM(update_ipq, fragment, label, ipq, &ipq->ipq_label);
242195fab37eSRobert Watson }
242295fab37eSRobert Watson 
242395fab37eSRobert Watson void
242495fab37eSRobert Watson mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf)
242595fab37eSRobert Watson {
242610eeb10cSRobert Watson 	struct label *label;
242710eeb10cSRobert Watson 
242810eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
242995fab37eSRobert Watson 
243095fab37eSRobert Watson 	MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf,
243110eeb10cSRobert Watson 	    label);
243295fab37eSRobert Watson }
243395fab37eSRobert Watson 
243495fab37eSRobert Watson void
243595fab37eSRobert Watson mac_create_mount(struct ucred *cred, struct mount *mp)
243695fab37eSRobert Watson {
243795fab37eSRobert Watson 
243895fab37eSRobert Watson 	MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel,
243995fab37eSRobert Watson 	    &mp->mnt_fslabel);
244095fab37eSRobert Watson }
244195fab37eSRobert Watson 
244295fab37eSRobert Watson void
244395fab37eSRobert Watson mac_create_root_mount(struct ucred *cred, struct mount *mp)
244495fab37eSRobert Watson {
244595fab37eSRobert Watson 
244695fab37eSRobert Watson 	MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel,
244795fab37eSRobert Watson 	    &mp->mnt_fslabel);
244895fab37eSRobert Watson }
244995fab37eSRobert Watson 
245095fab37eSRobert Watson int
245195fab37eSRobert Watson mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet)
245295fab37eSRobert Watson {
245395fab37eSRobert Watson 	int error;
245495fab37eSRobert Watson 
245595fab37eSRobert Watson 	if (!mac_enforce_network)
245695fab37eSRobert Watson 		return (0);
245795fab37eSRobert Watson 
245895fab37eSRobert Watson 	MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet,
245995fab37eSRobert Watson 	    &ifnet->if_label);
246095fab37eSRobert Watson 
246195fab37eSRobert Watson 	return (error);
246295fab37eSRobert Watson }
246395fab37eSRobert Watson 
246495fab37eSRobert Watson static int
246595fab37eSRobert Watson mac_check_cred_relabel(struct ucred *cred, struct label *newlabel)
246695fab37eSRobert Watson {
246795fab37eSRobert Watson 	int error;
246895fab37eSRobert Watson 
246995fab37eSRobert Watson 	MAC_CHECK(check_cred_relabel, cred, newlabel);
247095fab37eSRobert Watson 
247195fab37eSRobert Watson 	return (error);
247295fab37eSRobert Watson }
247395fab37eSRobert Watson 
247495fab37eSRobert Watson int
247595fab37eSRobert Watson mac_check_cred_visible(struct ucred *u1, struct ucred *u2)
247695fab37eSRobert Watson {
247795fab37eSRobert Watson 	int error;
247895fab37eSRobert Watson 
247995fab37eSRobert Watson 	if (!mac_enforce_process)
248095fab37eSRobert Watson 		return (0);
248195fab37eSRobert Watson 
248295fab37eSRobert Watson 	MAC_CHECK(check_cred_visible, u1, u2);
248395fab37eSRobert Watson 
248495fab37eSRobert Watson 	return (error);
248595fab37eSRobert Watson }
248695fab37eSRobert Watson 
248795fab37eSRobert Watson int
248895fab37eSRobert Watson mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf)
248995fab37eSRobert Watson {
249010eeb10cSRobert Watson 	struct label *label;
249195fab37eSRobert Watson 	int error;
249295fab37eSRobert Watson 
2493225bff6fSRobert Watson 	M_ASSERTPKTHDR(mbuf);
2494225bff6fSRobert Watson 
249595fab37eSRobert Watson 	if (!mac_enforce_network)
249695fab37eSRobert Watson 		return (0);
249795fab37eSRobert Watson 
249810eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
249995fab37eSRobert Watson 
250095fab37eSRobert Watson 	MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf,
250110eeb10cSRobert Watson 	    label);
250295fab37eSRobert Watson 
250395fab37eSRobert Watson 	return (error);
250495fab37eSRobert Watson }
250595fab37eSRobert Watson 
250695fab37eSRobert Watson int
2507e686e5aeSRobert Watson mac_check_kenv_dump(struct ucred *cred)
2508e686e5aeSRobert Watson {
2509e686e5aeSRobert Watson 	int error;
2510e686e5aeSRobert Watson 
2511e686e5aeSRobert Watson 	if (!mac_enforce_system)
2512e686e5aeSRobert Watson 		return (0);
2513e686e5aeSRobert Watson 
2514e686e5aeSRobert Watson 	MAC_CHECK(check_kenv_dump, cred);
2515e686e5aeSRobert Watson 
2516e686e5aeSRobert Watson 	return (error);
2517e686e5aeSRobert Watson }
2518e686e5aeSRobert Watson 
2519e686e5aeSRobert Watson int
2520e686e5aeSRobert Watson mac_check_kenv_get(struct ucred *cred, char *name)
2521e686e5aeSRobert Watson {
2522e686e5aeSRobert Watson 	int error;
2523e686e5aeSRobert Watson 
2524e686e5aeSRobert Watson 	if (!mac_enforce_system)
2525e686e5aeSRobert Watson 		return (0);
2526e686e5aeSRobert Watson 
2527e686e5aeSRobert Watson 	MAC_CHECK(check_kenv_get, cred, name);
2528e686e5aeSRobert Watson 
2529e686e5aeSRobert Watson 	return (error);
2530e686e5aeSRobert Watson }
2531e686e5aeSRobert Watson 
2532e686e5aeSRobert Watson int
2533e686e5aeSRobert Watson mac_check_kenv_set(struct ucred *cred, char *name, char *value)
2534e686e5aeSRobert Watson {
2535e686e5aeSRobert Watson 	int error;
2536e686e5aeSRobert Watson 
2537e686e5aeSRobert Watson 	if (!mac_enforce_system)
2538e686e5aeSRobert Watson 		return (0);
2539e686e5aeSRobert Watson 
2540e686e5aeSRobert Watson 	MAC_CHECK(check_kenv_set, cred, name, value);
2541e686e5aeSRobert Watson 
2542e686e5aeSRobert Watson 	return (error);
2543e686e5aeSRobert Watson }
2544e686e5aeSRobert Watson 
2545e686e5aeSRobert Watson int
2546e686e5aeSRobert Watson mac_check_kenv_unset(struct ucred *cred, char *name)
2547e686e5aeSRobert Watson {
2548e686e5aeSRobert Watson 	int error;
2549e686e5aeSRobert Watson 
2550e686e5aeSRobert Watson 	if (!mac_enforce_system)
2551e686e5aeSRobert Watson 		return (0);
2552e686e5aeSRobert Watson 
2553e686e5aeSRobert Watson 	MAC_CHECK(check_kenv_unset, cred, name);
2554e686e5aeSRobert Watson 
2555e686e5aeSRobert Watson 	return (error);
2556e686e5aeSRobert Watson }
2557e686e5aeSRobert Watson 
2558e686e5aeSRobert Watson int
2559a3df768bSRobert Watson mac_check_kld_load(struct ucred *cred, struct vnode *vp)
2560a3df768bSRobert Watson {
2561a3df768bSRobert Watson 	int error;
2562a3df768bSRobert Watson 
2563a3df768bSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_kld_load");
2564a3df768bSRobert Watson 
2565a3df768bSRobert Watson 	if (!mac_enforce_kld)
2566a3df768bSRobert Watson 		return (0);
2567a3df768bSRobert Watson 
2568a3df768bSRobert Watson 	MAC_CHECK(check_kld_load, cred, vp, &vp->v_label);
2569a3df768bSRobert Watson 
2570a3df768bSRobert Watson 	return (error);
2571a3df768bSRobert Watson }
2572a3df768bSRobert Watson 
2573a3df768bSRobert Watson int
2574a3df768bSRobert Watson mac_check_kld_stat(struct ucred *cred)
2575a3df768bSRobert Watson {
2576a3df768bSRobert Watson 	int error;
2577a3df768bSRobert Watson 
2578a3df768bSRobert Watson 	if (!mac_enforce_kld)
2579a3df768bSRobert Watson 		return (0);
2580a3df768bSRobert Watson 
2581a3df768bSRobert Watson 	MAC_CHECK(check_kld_stat, cred);
2582a3df768bSRobert Watson 
2583a3df768bSRobert Watson 	return (error);
2584a3df768bSRobert Watson }
2585a3df768bSRobert Watson 
2586a3df768bSRobert Watson int
2587a3df768bSRobert Watson mac_check_kld_unload(struct ucred *cred)
2588a3df768bSRobert Watson {
2589a3df768bSRobert Watson 	int error;
2590a3df768bSRobert Watson 
2591a3df768bSRobert Watson 	if (!mac_enforce_kld)
2592a3df768bSRobert Watson 		return (0);
2593a3df768bSRobert Watson 
2594a3df768bSRobert Watson 	MAC_CHECK(check_kld_unload, cred);
2595a3df768bSRobert Watson 
2596a3df768bSRobert Watson 	return (error);
2597a3df768bSRobert Watson }
2598a3df768bSRobert Watson 
2599a3df768bSRobert Watson int
260095fab37eSRobert Watson mac_check_mount_stat(struct ucred *cred, struct mount *mount)
260195fab37eSRobert Watson {
260295fab37eSRobert Watson 	int error;
260395fab37eSRobert Watson 
260495fab37eSRobert Watson 	if (!mac_enforce_fs)
260595fab37eSRobert Watson 		return (0);
260695fab37eSRobert Watson 
260795fab37eSRobert Watson 	MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel);
260895fab37eSRobert Watson 
260995fab37eSRobert Watson 	return (error);
261095fab37eSRobert Watson }
261195fab37eSRobert Watson 
261295fab37eSRobert Watson int
261395fab37eSRobert Watson mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd,
261495fab37eSRobert Watson     void *data)
261595fab37eSRobert Watson {
261695fab37eSRobert Watson 	int error;
261795fab37eSRobert Watson 
26181aa37f53SRobert Watson 	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
26191aa37f53SRobert Watson 
26201aa37f53SRobert Watson 	if (!mac_enforce_pipe)
26211aa37f53SRobert Watson 		return (0);
26221aa37f53SRobert Watson 
262395fab37eSRobert Watson 	MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data);
262495fab37eSRobert Watson 
262595fab37eSRobert Watson 	return (error);
262695fab37eSRobert Watson }
262795fab37eSRobert Watson 
262895fab37eSRobert Watson int
2629c024c3eeSRobert Watson mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe)
263095fab37eSRobert Watson {
263195fab37eSRobert Watson 	int error;
263295fab37eSRobert Watson 
26331aa37f53SRobert Watson 	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
26341aa37f53SRobert Watson 
26351aa37f53SRobert Watson 	if (!mac_enforce_pipe)
26361aa37f53SRobert Watson 		return (0);
26371aa37f53SRobert Watson 
2638c024c3eeSRobert Watson 	MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label);
2639c024c3eeSRobert Watson 
2640c024c3eeSRobert Watson 	return (error);
2641c024c3eeSRobert Watson }
2642c024c3eeSRobert Watson 
2643c024c3eeSRobert Watson int
2644c024c3eeSRobert Watson mac_check_pipe_read(struct ucred *cred, struct pipe *pipe)
2645c024c3eeSRobert Watson {
2646c024c3eeSRobert Watson 	int error;
2647c024c3eeSRobert Watson 
26481aa37f53SRobert Watson 	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
26491aa37f53SRobert Watson 
26501aa37f53SRobert Watson 	if (!mac_enforce_pipe)
26511aa37f53SRobert Watson 		return (0);
26521aa37f53SRobert Watson 
2653c024c3eeSRobert Watson 	MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label);
265495fab37eSRobert Watson 
265595fab37eSRobert Watson 	return (error);
265695fab37eSRobert Watson }
265795fab37eSRobert Watson 
265895fab37eSRobert Watson static int
265995fab37eSRobert Watson mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
266095fab37eSRobert Watson     struct label *newlabel)
266195fab37eSRobert Watson {
266295fab37eSRobert Watson 	int error;
266395fab37eSRobert Watson 
26641aa37f53SRobert Watson 	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
26651aa37f53SRobert Watson 
26661aa37f53SRobert Watson 	if (!mac_enforce_pipe)
26671aa37f53SRobert Watson 		return (0);
26681aa37f53SRobert Watson 
266995fab37eSRobert Watson 	MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel);
267095fab37eSRobert Watson 
267195fab37eSRobert Watson 	return (error);
267295fab37eSRobert Watson }
267395fab37eSRobert Watson 
267495fab37eSRobert Watson int
2675c024c3eeSRobert Watson mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe)
2676c024c3eeSRobert Watson {
2677c024c3eeSRobert Watson 	int error;
2678c024c3eeSRobert Watson 
26791aa37f53SRobert Watson 	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
26801aa37f53SRobert Watson 
26811aa37f53SRobert Watson 	if (!mac_enforce_pipe)
26821aa37f53SRobert Watson 		return (0);
26831aa37f53SRobert Watson 
2684c024c3eeSRobert Watson 	MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label);
2685c024c3eeSRobert Watson 
2686c024c3eeSRobert Watson 	return (error);
2687c024c3eeSRobert Watson }
2688c024c3eeSRobert Watson 
2689c024c3eeSRobert Watson int
2690c024c3eeSRobert Watson mac_check_pipe_write(struct ucred *cred, struct pipe *pipe)
2691c024c3eeSRobert Watson {
2692c024c3eeSRobert Watson 	int error;
2693c024c3eeSRobert Watson 
26941aa37f53SRobert Watson 	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
26951aa37f53SRobert Watson 
26961aa37f53SRobert Watson 	if (!mac_enforce_pipe)
26971aa37f53SRobert Watson 		return (0);
26981aa37f53SRobert Watson 
2699c024c3eeSRobert Watson 	MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label);
2700c024c3eeSRobert Watson 
2701c024c3eeSRobert Watson 	return (error);
2702c024c3eeSRobert Watson }
2703c024c3eeSRobert Watson 
2704c024c3eeSRobert Watson int
270595fab37eSRobert Watson mac_check_proc_debug(struct ucred *cred, struct proc *proc)
270695fab37eSRobert Watson {
270795fab37eSRobert Watson 	int error;
270895fab37eSRobert Watson 
2709b12baf55SRobert Watson 	PROC_LOCK_ASSERT(proc, MA_OWNED);
2710b12baf55SRobert Watson 
271195fab37eSRobert Watson 	if (!mac_enforce_process)
271295fab37eSRobert Watson 		return (0);
271395fab37eSRobert Watson 
271495fab37eSRobert Watson 	MAC_CHECK(check_proc_debug, cred, proc);
271595fab37eSRobert Watson 
271695fab37eSRobert Watson 	return (error);
271795fab37eSRobert Watson }
271895fab37eSRobert Watson 
271995fab37eSRobert Watson int
272095fab37eSRobert Watson mac_check_proc_sched(struct ucred *cred, struct proc *proc)
272195fab37eSRobert Watson {
272295fab37eSRobert Watson 	int error;
272395fab37eSRobert Watson 
2724b12baf55SRobert Watson 	PROC_LOCK_ASSERT(proc, MA_OWNED);
2725b12baf55SRobert Watson 
272695fab37eSRobert Watson 	if (!mac_enforce_process)
272795fab37eSRobert Watson 		return (0);
272895fab37eSRobert Watson 
272995fab37eSRobert Watson 	MAC_CHECK(check_proc_sched, cred, proc);
273095fab37eSRobert Watson 
273195fab37eSRobert Watson 	return (error);
273295fab37eSRobert Watson }
273395fab37eSRobert Watson 
273495fab37eSRobert Watson int
273595fab37eSRobert Watson mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
273695fab37eSRobert Watson {
273795fab37eSRobert Watson 	int error;
273895fab37eSRobert Watson 
2739b12baf55SRobert Watson 	PROC_LOCK_ASSERT(proc, MA_OWNED);
2740b12baf55SRobert Watson 
274195fab37eSRobert Watson 	if (!mac_enforce_process)
274295fab37eSRobert Watson 		return (0);
274395fab37eSRobert Watson 
274495fab37eSRobert Watson 	MAC_CHECK(check_proc_signal, cred, proc, signum);
274595fab37eSRobert Watson 
274695fab37eSRobert Watson 	return (error);
274795fab37eSRobert Watson }
274895fab37eSRobert Watson 
274995fab37eSRobert Watson int
275095fab37eSRobert Watson mac_check_socket_bind(struct ucred *ucred, struct socket *socket,
275195fab37eSRobert Watson     struct sockaddr *sockaddr)
275295fab37eSRobert Watson {
275395fab37eSRobert Watson 	int error;
275495fab37eSRobert Watson 
275595fab37eSRobert Watson 	if (!mac_enforce_socket)
275695fab37eSRobert Watson 		return (0);
275795fab37eSRobert Watson 
275895fab37eSRobert Watson 	MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label,
275995fab37eSRobert Watson 	    sockaddr);
276095fab37eSRobert Watson 
276195fab37eSRobert Watson 	return (error);
276295fab37eSRobert Watson }
276395fab37eSRobert Watson 
276495fab37eSRobert Watson int
276595fab37eSRobert Watson mac_check_socket_connect(struct ucred *cred, struct socket *socket,
276695fab37eSRobert Watson     struct sockaddr *sockaddr)
276795fab37eSRobert Watson {
276895fab37eSRobert Watson 	int error;
276995fab37eSRobert Watson 
277095fab37eSRobert Watson 	if (!mac_enforce_socket)
277195fab37eSRobert Watson 		return (0);
277295fab37eSRobert Watson 
277395fab37eSRobert Watson 	MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label,
277495fab37eSRobert Watson 	    sockaddr);
277595fab37eSRobert Watson 
277695fab37eSRobert Watson 	return (error);
277795fab37eSRobert Watson }
277895fab37eSRobert Watson 
277995fab37eSRobert Watson int
2780d61198e4SRobert Watson mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf)
2781d61198e4SRobert Watson {
278210eeb10cSRobert Watson 	struct label *label;
2783d61198e4SRobert Watson 	int error;
2784d61198e4SRobert Watson 
2785d61198e4SRobert Watson 	if (!mac_enforce_socket)
2786d61198e4SRobert Watson 		return (0);
2787d61198e4SRobert Watson 
278810eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
278910eeb10cSRobert Watson 
2790d61198e4SRobert Watson 	MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf,
279110eeb10cSRobert Watson 	    label);
2792d61198e4SRobert Watson 
2793d61198e4SRobert Watson 	return (error);
2794d61198e4SRobert Watson }
2795d61198e4SRobert Watson 
2796d61198e4SRobert Watson int
279795fab37eSRobert Watson mac_check_socket_listen(struct ucred *cred, struct socket *socket)
279895fab37eSRobert Watson {
279995fab37eSRobert Watson 	int error;
280095fab37eSRobert Watson 
280195fab37eSRobert Watson 	if (!mac_enforce_socket)
280295fab37eSRobert Watson 		return (0);
280395fab37eSRobert Watson 
280495fab37eSRobert Watson 	MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label);
280595fab37eSRobert Watson 	return (error);
280695fab37eSRobert Watson }
280795fab37eSRobert Watson 
2808b371c939SRobert Watson int
2809b371c939SRobert Watson mac_check_socket_receive(struct ucred *cred, struct socket *so)
2810b371c939SRobert Watson {
2811b371c939SRobert Watson 	int error;
2812b371c939SRobert Watson 
2813b371c939SRobert Watson 	if (!mac_enforce_socket)
2814b371c939SRobert Watson 		return (0);
2815b371c939SRobert Watson 
2816b371c939SRobert Watson 	MAC_CHECK(check_socket_receive, cred, so, &so->so_label);
2817b371c939SRobert Watson 
2818b371c939SRobert Watson 	return (error);
2819b371c939SRobert Watson }
2820b371c939SRobert Watson 
282195fab37eSRobert Watson static int
282295fab37eSRobert Watson mac_check_socket_relabel(struct ucred *cred, struct socket *socket,
282395fab37eSRobert Watson     struct label *newlabel)
282495fab37eSRobert Watson {
282595fab37eSRobert Watson 	int error;
282695fab37eSRobert Watson 
282795fab37eSRobert Watson 	MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label,
282895fab37eSRobert Watson 	    newlabel);
282995fab37eSRobert Watson 
283095fab37eSRobert Watson 	return (error);
283195fab37eSRobert Watson }
283295fab37eSRobert Watson 
283395fab37eSRobert Watson int
2834b371c939SRobert Watson mac_check_socket_send(struct ucred *cred, struct socket *so)
2835b371c939SRobert Watson {
2836b371c939SRobert Watson 	int error;
2837b371c939SRobert Watson 
2838b371c939SRobert Watson 	if (!mac_enforce_socket)
2839b371c939SRobert Watson 		return (0);
2840b371c939SRobert Watson 
2841b371c939SRobert Watson 	MAC_CHECK(check_socket_send, cred, so, &so->so_label);
2842b371c939SRobert Watson 
2843b371c939SRobert Watson 	return (error);
2844b371c939SRobert Watson }
2845b371c939SRobert Watson 
2846b371c939SRobert Watson int
284795fab37eSRobert Watson mac_check_socket_visible(struct ucred *cred, struct socket *socket)
284895fab37eSRobert Watson {
284995fab37eSRobert Watson 	int error;
285095fab37eSRobert Watson 
285195fab37eSRobert Watson 	if (!mac_enforce_socket)
285295fab37eSRobert Watson 		return (0);
285395fab37eSRobert Watson 
285495fab37eSRobert Watson 	MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label);
285595fab37eSRobert Watson 
285695fab37eSRobert Watson 	return (error);
285795fab37eSRobert Watson }
285895fab37eSRobert Watson 
285995fab37eSRobert Watson int
286092835789SRobert Watson mac_check_sysarch_ioperm(struct ucred *cred)
286192835789SRobert Watson {
286292835789SRobert Watson 	int error;
286392835789SRobert Watson 
286492835789SRobert Watson 	if (!mac_enforce_system)
286592835789SRobert Watson 		return (0);
286692835789SRobert Watson 
286792835789SRobert Watson 	MAC_CHECK(check_sysarch_ioperm, cred);
286892835789SRobert Watson 	return (error);
286992835789SRobert Watson }
287092835789SRobert Watson 
287192835789SRobert Watson int
2872e5e820fdSRobert Watson mac_check_system_acct(struct ucred *cred, struct vnode *vp)
2873e5e820fdSRobert Watson {
2874e5e820fdSRobert Watson 	int error;
2875e5e820fdSRobert Watson 
2876e5e820fdSRobert Watson 	if (vp != NULL) {
2877e5e820fdSRobert Watson 		ASSERT_VOP_LOCKED(vp, "mac_check_system_acct");
2878e5e820fdSRobert Watson 	}
2879e5e820fdSRobert Watson 
2880e5e820fdSRobert Watson 	if (!mac_enforce_system)
2881e5e820fdSRobert Watson 		return (0);
2882e5e820fdSRobert Watson 
2883e5e820fdSRobert Watson 	MAC_CHECK(check_system_acct, cred, vp,
2884e5e820fdSRobert Watson 	    vp != NULL ? &vp->v_label : NULL);
2885e5e820fdSRobert Watson 
2886e5e820fdSRobert Watson 	return (error);
2887e5e820fdSRobert Watson }
2888e5e820fdSRobert Watson 
2889e5e820fdSRobert Watson int
2890e5e820fdSRobert Watson mac_check_system_nfsd(struct ucred *cred)
2891e5e820fdSRobert Watson {
2892e5e820fdSRobert Watson 	int error;
2893e5e820fdSRobert Watson 
2894e5e820fdSRobert Watson 	if (!mac_enforce_system)
2895e5e820fdSRobert Watson 		return (0);
2896e5e820fdSRobert Watson 
2897e5e820fdSRobert Watson 	MAC_CHECK(check_system_nfsd, cred);
2898e5e820fdSRobert Watson 
2899e5e820fdSRobert Watson 	return (error);
2900e5e820fdSRobert Watson }
2901e5e820fdSRobert Watson 
2902e5e820fdSRobert Watson int
2903a2ecb9b7SRobert Watson mac_check_system_reboot(struct ucred *cred, int howto)
2904a2ecb9b7SRobert Watson {
2905a2ecb9b7SRobert Watson 	int error;
2906a2ecb9b7SRobert Watson 
29079e913ebdSRobert Watson 	if (!mac_enforce_system)
2908a2ecb9b7SRobert Watson 		return (0);
2909a2ecb9b7SRobert Watson 
2910a2ecb9b7SRobert Watson 	MAC_CHECK(check_system_reboot, cred, howto);
29119e913ebdSRobert Watson 
2912a2ecb9b7SRobert Watson 	return (error);
2913a2ecb9b7SRobert Watson }
2914a2ecb9b7SRobert Watson 
2915a2ecb9b7SRobert Watson int
29164b8d5f2dSRobert Watson mac_check_system_settime(struct ucred *cred)
29174b8d5f2dSRobert Watson {
29184b8d5f2dSRobert Watson 	int error;
29194b8d5f2dSRobert Watson 
29204b8d5f2dSRobert Watson 	if (!mac_enforce_system)
29214b8d5f2dSRobert Watson 		return (0);
29224b8d5f2dSRobert Watson 
29234b8d5f2dSRobert Watson 	MAC_CHECK(check_system_settime, cred);
29244b8d5f2dSRobert Watson 
29254b8d5f2dSRobert Watson 	return (error);
29264b8d5f2dSRobert Watson }
29274b8d5f2dSRobert Watson 
29284b8d5f2dSRobert Watson int
292903ce2c0cSRobert Watson mac_check_system_swapon(struct ucred *cred, struct vnode *vp)
293003ce2c0cSRobert Watson {
293103ce2c0cSRobert Watson 	int error;
293203ce2c0cSRobert Watson 
293303ce2c0cSRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon");
293403ce2c0cSRobert Watson 
29359e913ebdSRobert Watson 	if (!mac_enforce_system)
293603ce2c0cSRobert Watson 		return (0);
293703ce2c0cSRobert Watson 
293803ce2c0cSRobert Watson 	MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label);
293903ce2c0cSRobert Watson 	return (error);
294003ce2c0cSRobert Watson }
294103ce2c0cSRobert Watson 
294203ce2c0cSRobert Watson int
29431b2c2ab2SRobert Watson mac_check_system_swapoff(struct ucred *cred, struct vnode *vp)
29441b2c2ab2SRobert Watson {
29451b2c2ab2SRobert Watson 	int error;
29461b2c2ab2SRobert Watson 
29471b2c2ab2SRobert Watson 	ASSERT_VOP_LOCKED(vp, "mac_check_system_swapoff");
29481b2c2ab2SRobert Watson 
29491b2c2ab2SRobert Watson 	if (!mac_enforce_system)
29501b2c2ab2SRobert Watson 		return (0);
29511b2c2ab2SRobert Watson 
29521b2c2ab2SRobert Watson 	MAC_CHECK(check_system_swapoff, cred, vp, &vp->v_label);
29531b2c2ab2SRobert Watson 	return (error);
29541b2c2ab2SRobert Watson }
29551b2c2ab2SRobert Watson 
29561b2c2ab2SRobert Watson int
2957d3fc69eeSRobert Watson mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
2958d3fc69eeSRobert Watson     void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
2959d3fc69eeSRobert Watson {
2960d3fc69eeSRobert Watson 	int error;
2961d3fc69eeSRobert Watson 
2962d3fc69eeSRobert Watson 	/*
2963d3fc69eeSRobert Watson 	 * XXXMAC: We're very much like to assert the SYSCTL_LOCK here,
2964d3fc69eeSRobert Watson 	 * but since it's not exported from kern_sysctl.c, we can't.
2965d3fc69eeSRobert Watson 	 */
29669e913ebdSRobert Watson 	if (!mac_enforce_system)
2967d3fc69eeSRobert Watson 		return (0);
2968d3fc69eeSRobert Watson 
2969d3fc69eeSRobert Watson 	MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp,
2970d3fc69eeSRobert Watson 	    inkernel, new, newlen);
2971d3fc69eeSRobert Watson 
2972d3fc69eeSRobert Watson 	return (error);
2973d3fc69eeSRobert Watson }
2974d3fc69eeSRobert Watson 
2975d3fc69eeSRobert Watson int
297695fab37eSRobert Watson mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
297795fab37eSRobert Watson     struct ifnet *ifnet)
297895fab37eSRobert Watson {
2979f7b951a8SRobert Watson 	char *elements, *buffer;
2980f7b951a8SRobert Watson 	struct mac mac;
298195fab37eSRobert Watson 	int error;
298295fab37eSRobert Watson 
2983f7b951a8SRobert Watson 	error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
298495fab37eSRobert Watson 	if (error)
298595fab37eSRobert Watson 		return (error);
298695fab37eSRobert Watson 
2987f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
2988f7b951a8SRobert Watson 	if (error)
2989f7b951a8SRobert Watson 		return (error);
2990f7b951a8SRobert Watson 
2991a163d034SWarner Losh 	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
2992f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
2993f7b951a8SRobert Watson 	if (error) {
2994f7b951a8SRobert Watson 		free(elements, M_MACTEMP);
2995f7b951a8SRobert Watson 		return (error);
2996f7b951a8SRobert Watson 	}
2997f7b951a8SRobert Watson 
2998a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
2999f7b951a8SRobert Watson 	error = mac_externalize_ifnet_label(&ifnet->if_label, elements,
3000a163d034SWarner Losh 	    buffer, mac.m_buflen, M_WAITOK);
3001f7b951a8SRobert Watson 	if (error == 0)
3002f7b951a8SRobert Watson 		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
3003f7b951a8SRobert Watson 
3004f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3005f7b951a8SRobert Watson 	free(elements, M_MACTEMP);
3006f7b951a8SRobert Watson 
3007f7b951a8SRobert Watson 	return (error);
300895fab37eSRobert Watson }
300995fab37eSRobert Watson 
301095fab37eSRobert Watson int
301195fab37eSRobert Watson mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
301295fab37eSRobert Watson     struct ifnet *ifnet)
301395fab37eSRobert Watson {
301495fab37eSRobert Watson 	struct label intlabel;
3015f7b951a8SRobert Watson 	struct mac mac;
3016f7b951a8SRobert Watson 	char *buffer;
301795fab37eSRobert Watson 	int error;
301895fab37eSRobert Watson 
3019f7b951a8SRobert Watson 	error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
302095fab37eSRobert Watson 	if (error)
302195fab37eSRobert Watson 		return (error);
302295fab37eSRobert Watson 
3023f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
302495fab37eSRobert Watson 	if (error)
302595fab37eSRobert Watson 		return (error);
302695fab37eSRobert Watson 
3027a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3028f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
3029f7b951a8SRobert Watson 	if (error) {
3030f7b951a8SRobert Watson 		free(buffer, M_MACTEMP);
3031f7b951a8SRobert Watson 		return (error);
3032f7b951a8SRobert Watson 	}
3033f7b951a8SRobert Watson 
3034f7b951a8SRobert Watson 	mac_init_ifnet_label(&intlabel);
3035f7b951a8SRobert Watson 	error = mac_internalize_ifnet_label(&intlabel, buffer);
3036f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3037f7b951a8SRobert Watson 	if (error) {
3038f7b951a8SRobert Watson 		mac_destroy_ifnet_label(&intlabel);
3039f7b951a8SRobert Watson 		return (error);
3040f7b951a8SRobert Watson 	}
3041f7b951a8SRobert Watson 
304295fab37eSRobert Watson 	/*
304395fab37eSRobert Watson 	 * XXX: Note that this is a redundant privilege check, since
304495fab37eSRobert Watson 	 * policies impose this check themselves if required by the
304595fab37eSRobert Watson 	 * policy.  Eventually, this should go away.
304695fab37eSRobert Watson 	 */
304795fab37eSRobert Watson 	error = suser_cred(cred, 0);
3048f7b951a8SRobert Watson 	if (error) {
3049f7b951a8SRobert Watson 		mac_destroy_ifnet_label(&intlabel);
3050f7b951a8SRobert Watson 		return (error);
3051f7b951a8SRobert Watson 	}
305295fab37eSRobert Watson 
305395fab37eSRobert Watson 	MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label,
305495fab37eSRobert Watson 	    &intlabel);
3055f7b951a8SRobert Watson 	if (error) {
3056f7b951a8SRobert Watson 		mac_destroy_ifnet_label(&intlabel);
3057f7b951a8SRobert Watson 		return (error);
3058f7b951a8SRobert Watson 	}
305995fab37eSRobert Watson 
306095fab37eSRobert Watson 	MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel);
306195fab37eSRobert Watson 
3062f7b951a8SRobert Watson 	mac_destroy_ifnet_label(&intlabel);
3063f7b951a8SRobert Watson 	return (0);
306495fab37eSRobert Watson }
306595fab37eSRobert Watson 
306695fab37eSRobert Watson void
3067990b4b2dSRobert Watson mac_create_devfs_device(struct mount *mp, dev_t dev, struct devfs_dirent *de)
306895fab37eSRobert Watson {
306995fab37eSRobert Watson 
3070990b4b2dSRobert Watson 	MAC_PERFORM(create_devfs_device, mp, dev, de, &de->de_label);
307195fab37eSRobert Watson }
307295fab37eSRobert Watson 
307374e62b1bSRobert Watson void
3074990b4b2dSRobert Watson mac_create_devfs_symlink(struct ucred *cred, struct mount *mp,
3075990b4b2dSRobert Watson     struct devfs_dirent *dd, struct devfs_dirent *de)
307674e62b1bSRobert Watson {
307774e62b1bSRobert Watson 
3078990b4b2dSRobert Watson 	MAC_PERFORM(create_devfs_symlink, cred, mp, dd, &dd->de_label, de,
307974e62b1bSRobert Watson 	    &de->de_label);
308074e62b1bSRobert Watson }
308174e62b1bSRobert Watson 
308295fab37eSRobert Watson void
3083990b4b2dSRobert Watson mac_create_devfs_directory(struct mount *mp, char *dirname, int dirnamelen,
308495fab37eSRobert Watson     struct devfs_dirent *de)
308595fab37eSRobert Watson {
308695fab37eSRobert Watson 
3087990b4b2dSRobert Watson 	MAC_PERFORM(create_devfs_directory, mp, dirname, dirnamelen, de,
308895fab37eSRobert Watson 	    &de->de_label);
308995fab37eSRobert Watson }
309095fab37eSRobert Watson 
309195fab37eSRobert Watson int
309295fab37eSRobert Watson mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
3093f7b951a8SRobert Watson     struct mac *mac)
309495fab37eSRobert Watson {
309595fab37eSRobert Watson 	struct label intlabel;
3096f7b951a8SRobert Watson 	char *buffer;
309795fab37eSRobert Watson 	int error;
309895fab37eSRobert Watson 
3099f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(mac);
310095fab37eSRobert Watson 	if (error)
310195fab37eSRobert Watson 		return (error);
310295fab37eSRobert Watson 
3103a163d034SWarner Losh 	buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
3104f7b951a8SRobert Watson 	error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL);
3105f7b951a8SRobert Watson 	if (error) {
3106f7b951a8SRobert Watson 		free(buffer, M_MACTEMP);
3107f7b951a8SRobert Watson 		return (error);
3108f7b951a8SRobert Watson 	}
3109f7b951a8SRobert Watson 
3110a163d034SWarner Losh 	mac_init_socket_label(&intlabel, M_WAITOK);
3111f7b951a8SRobert Watson 	error = mac_internalize_socket_label(&intlabel, buffer);
3112f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3113f7b951a8SRobert Watson 	if (error) {
3114f7b951a8SRobert Watson 		mac_destroy_socket_label(&intlabel);
3115f7b951a8SRobert Watson 		return (error);
3116f7b951a8SRobert Watson 	}
3117f7b951a8SRobert Watson 
311895fab37eSRobert Watson 	mac_check_socket_relabel(cred, so, &intlabel);
311995fab37eSRobert Watson 	if (error) {
3120f7b951a8SRobert Watson 		mac_destroy_socket_label(&intlabel);
312195fab37eSRobert Watson 		return (error);
312295fab37eSRobert Watson 	}
312395fab37eSRobert Watson 
312495fab37eSRobert Watson 	mac_relabel_socket(cred, so, &intlabel);
312595fab37eSRobert Watson 
3126f7b951a8SRobert Watson 	mac_destroy_socket_label(&intlabel);
312795fab37eSRobert Watson 	return (0);
312895fab37eSRobert Watson }
312995fab37eSRobert Watson 
313095fab37eSRobert Watson int
313195fab37eSRobert Watson mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label)
313295fab37eSRobert Watson {
313395fab37eSRobert Watson 	int error;
313495fab37eSRobert Watson 
31351aa37f53SRobert Watson 	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
31361aa37f53SRobert Watson 
313795fab37eSRobert Watson 	error = mac_check_pipe_relabel(cred, pipe, label);
313895fab37eSRobert Watson 	if (error)
313995fab37eSRobert Watson 		return (error);
314095fab37eSRobert Watson 
314195fab37eSRobert Watson 	mac_relabel_pipe(cred, pipe, label);
314295fab37eSRobert Watson 
314395fab37eSRobert Watson 	return (0);
314495fab37eSRobert Watson }
314595fab37eSRobert Watson 
314695fab37eSRobert Watson int
314795fab37eSRobert Watson mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
3148f7b951a8SRobert Watson     struct mac *mac)
314995fab37eSRobert Watson {
3150f7b951a8SRobert Watson 	char *buffer, *elements;
3151f7b951a8SRobert Watson 	int error;
315295fab37eSRobert Watson 
3153f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(mac);
3154f7b951a8SRobert Watson 	if (error)
3155f7b951a8SRobert Watson 		return (error);
3156f7b951a8SRobert Watson 
3157a163d034SWarner Losh 	elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
3158f7b951a8SRobert Watson 	error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
3159f7b951a8SRobert Watson 	if (error) {
3160f7b951a8SRobert Watson 		free(elements, M_MACTEMP);
3161f7b951a8SRobert Watson 		return (error);
3162f7b951a8SRobert Watson 	}
3163f7b951a8SRobert Watson 
3164a163d034SWarner Losh 	buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3165f7b951a8SRobert Watson 	error = mac_externalize_socket_label(&so->so_label, elements,
3166a163d034SWarner Losh 	    buffer, mac->m_buflen, M_WAITOK);
3167f7b951a8SRobert Watson 	if (error == 0)
3168f7b951a8SRobert Watson 		error = copyout(buffer, mac->m_string, strlen(buffer)+1);
3169f7b951a8SRobert Watson 
3170f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3171f7b951a8SRobert Watson 	free(elements, M_MACTEMP);
3172f7b951a8SRobert Watson 
3173f7b951a8SRobert Watson 	return (error);
317495fab37eSRobert Watson }
317595fab37eSRobert Watson 
317695fab37eSRobert Watson int
317795fab37eSRobert Watson mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
3178f7b951a8SRobert Watson     struct mac *mac)
317995fab37eSRobert Watson {
3180f7b951a8SRobert Watson 	char *elements, *buffer;
3181f7b951a8SRobert Watson 	int error;
318295fab37eSRobert Watson 
3183f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(mac);
3184f7b951a8SRobert Watson 	if (error)
3185f7b951a8SRobert Watson 		return (error);
3186f7b951a8SRobert Watson 
3187a163d034SWarner Losh 	elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
3188f7b951a8SRobert Watson 	error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
3189f7b951a8SRobert Watson 	if (error) {
3190f7b951a8SRobert Watson 		free(elements, M_MACTEMP);
3191f7b951a8SRobert Watson 		return (error);
3192f7b951a8SRobert Watson 	}
3193f7b951a8SRobert Watson 
3194a163d034SWarner Losh 	buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3195f7b951a8SRobert Watson 	error = mac_externalize_socket_peer_label(&so->so_peerlabel,
3196a163d034SWarner Losh 	    elements, buffer, mac->m_buflen, M_WAITOK);
3197f7b951a8SRobert Watson 	if (error == 0)
3198f7b951a8SRobert Watson 		error = copyout(buffer, mac->m_string, strlen(buffer)+1);
3199f7b951a8SRobert Watson 
3200f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3201f7b951a8SRobert Watson 	free(elements, M_MACTEMP);
3202f7b951a8SRobert Watson 
3203f7b951a8SRobert Watson 	return (error);
320495fab37eSRobert Watson }
320595fab37eSRobert Watson 
320695fab37eSRobert Watson /*
320795fab37eSRobert Watson  * Implementation of VOP_SETLABEL() that relies on extended attributes
320895fab37eSRobert Watson  * to store label data.  Can be referenced by filesystems supporting
320995fab37eSRobert Watson  * extended attributes.
321095fab37eSRobert Watson  */
321195fab37eSRobert Watson int
321295fab37eSRobert Watson vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
321395fab37eSRobert Watson {
321495fab37eSRobert Watson 	struct vnode *vp = ap->a_vp;
321595fab37eSRobert Watson 	struct label *intlabel = ap->a_label;
321695fab37eSRobert Watson 	int error;
321795fab37eSRobert Watson 
321895fab37eSRobert Watson 	ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
321995fab37eSRobert Watson 
3220763bbd2fSRobert Watson 	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
3221763bbd2fSRobert Watson 		return (EOPNOTSUPP);
322295fab37eSRobert Watson 
3223763bbd2fSRobert Watson 	error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel);
322495fab37eSRobert Watson 	if (error)
322595fab37eSRobert Watson 		return (error);
322695fab37eSRobert Watson 
322795fab37eSRobert Watson 	mac_relabel_vnode(ap->a_cred, vp, intlabel);
322895fab37eSRobert Watson 
322995fab37eSRobert Watson 	return (0);
323095fab37eSRobert Watson }
323195fab37eSRobert Watson 
323295fab37eSRobert Watson static int
323395fab37eSRobert Watson vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred)
323495fab37eSRobert Watson {
323595fab37eSRobert Watson 	int error;
323695fab37eSRobert Watson 
323795fab37eSRobert Watson 	if (vp->v_mount == NULL) {
323895fab37eSRobert Watson 		/* printf("vn_setlabel: null v_mount\n"); */
323906be2aaaSNate Lawson 		if (vp->v_type != VNON)
324006be2aaaSNate Lawson 			printf("vn_setlabel: null v_mount with non-VNON\n");
324195fab37eSRobert Watson 		return (EBADF);
324295fab37eSRobert Watson 	}
324395fab37eSRobert Watson 
324495fab37eSRobert Watson 	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
324595fab37eSRobert Watson 		return (EOPNOTSUPP);
324695fab37eSRobert Watson 
324795fab37eSRobert Watson 	/*
324895fab37eSRobert Watson 	 * Multi-phase commit.  First check the policies to confirm the
324995fab37eSRobert Watson 	 * change is OK.  Then commit via the filesystem.  Finally,
325095fab37eSRobert Watson 	 * update the actual vnode label.  Question: maybe the filesystem
325195fab37eSRobert Watson 	 * should update the vnode at the end as part of VOP_SETLABEL()?
325295fab37eSRobert Watson 	 */
325395fab37eSRobert Watson 	error = mac_check_vnode_relabel(cred, vp, intlabel);
325495fab37eSRobert Watson 	if (error)
325595fab37eSRobert Watson 		return (error);
325695fab37eSRobert Watson 
325795fab37eSRobert Watson 	/*
325895fab37eSRobert Watson 	 * VADMIN provides the opportunity for the filesystem to make
325995fab37eSRobert Watson 	 * decisions about who is and is not able to modify labels
326095fab37eSRobert Watson 	 * and protections on files.  This might not be right.  We can't
326195fab37eSRobert Watson 	 * assume VOP_SETLABEL() will do it, because we might implement
326295fab37eSRobert Watson 	 * that as part of vop_stdsetlabel_ea().
326395fab37eSRobert Watson 	 */
326495fab37eSRobert Watson 	error = VOP_ACCESS(vp, VADMIN, cred, curthread);
326595fab37eSRobert Watson 	if (error)
326695fab37eSRobert Watson 		return (error);
326795fab37eSRobert Watson 
326895fab37eSRobert Watson 	error = VOP_SETLABEL(vp, intlabel, cred, curthread);
326995fab37eSRobert Watson 	if (error)
327095fab37eSRobert Watson 		return (error);
327195fab37eSRobert Watson 
327295fab37eSRobert Watson 	return (0);
327395fab37eSRobert Watson }
327495fab37eSRobert Watson 
3275f7b951a8SRobert Watson int
3276f7b951a8SRobert Watson __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
3277f7b951a8SRobert Watson {
3278f7b951a8SRobert Watson 	char *elements, *buffer;
3279f7b951a8SRobert Watson 	struct mac mac;
3280f7b951a8SRobert Watson 	struct proc *tproc;
3281f7b951a8SRobert Watson 	struct ucred *tcred;
3282f7b951a8SRobert Watson 	int error;
3283f7b951a8SRobert Watson 
3284d1e405c5SAlfred Perlstein 	error = copyin(uap->mac_p, &mac, sizeof(mac));
3285f7b951a8SRobert Watson 	if (error)
3286f7b951a8SRobert Watson 		return (error);
3287f7b951a8SRobert Watson 
3288f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
3289f7b951a8SRobert Watson 	if (error)
3290f7b951a8SRobert Watson 		return (error);
3291f7b951a8SRobert Watson 
3292f7b951a8SRobert Watson 	tproc = pfind(uap->pid);
3293f7b951a8SRobert Watson 	if (tproc == NULL)
3294f7b951a8SRobert Watson 		return (ESRCH);
3295f7b951a8SRobert Watson 
3296f7b951a8SRobert Watson 	tcred = NULL;				/* Satisfy gcc. */
3297f7b951a8SRobert Watson 	error = p_cansee(td, tproc);
3298f7b951a8SRobert Watson 	if (error == 0)
3299f7b951a8SRobert Watson 		tcred = crhold(tproc->p_ucred);
3300f7b951a8SRobert Watson 	PROC_UNLOCK(tproc);
3301f7b951a8SRobert Watson 	if (error)
3302f7b951a8SRobert Watson 		return (error);
3303f7b951a8SRobert Watson 
3304a163d034SWarner Losh 	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3305f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
3306f7b951a8SRobert Watson 	if (error) {
3307f7b951a8SRobert Watson 		free(elements, M_MACTEMP);
3308f7b951a8SRobert Watson 		crfree(tcred);
3309f7b951a8SRobert Watson 		return (error);
3310f7b951a8SRobert Watson 	}
3311f7b951a8SRobert Watson 
3312a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3313f7b951a8SRobert Watson 	error = mac_externalize_cred_label(&tcred->cr_label, elements,
3314a163d034SWarner Losh 	    buffer, mac.m_buflen, M_WAITOK);
3315f7b951a8SRobert Watson 	if (error == 0)
3316f7b951a8SRobert Watson 		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
3317f7b951a8SRobert Watson 
3318f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3319f7b951a8SRobert Watson 	free(elements, M_MACTEMP);
3320f7b951a8SRobert Watson 	crfree(tcred);
3321f7b951a8SRobert Watson 	return (error);
3322f7b951a8SRobert Watson }
3323f7b951a8SRobert Watson 
332495fab37eSRobert Watson /*
332595fab37eSRobert Watson  * MPSAFE
332695fab37eSRobert Watson  */
332795fab37eSRobert Watson int
332895fab37eSRobert Watson __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
332995fab37eSRobert Watson {
3330f7b951a8SRobert Watson 	char *elements, *buffer;
3331f7b951a8SRobert Watson 	struct mac mac;
333295fab37eSRobert Watson 	int error;
333395fab37eSRobert Watson 
3334f7b951a8SRobert Watson 	error = copyin(uap->mac_p, &mac, sizeof(mac));
3335f7b951a8SRobert Watson 	if (error)
3336f7b951a8SRobert Watson 		return (error);
333795fab37eSRobert Watson 
3338f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
3339f7b951a8SRobert Watson 	if (error)
3340f7b951a8SRobert Watson 		return (error);
3341f7b951a8SRobert Watson 
3342a163d034SWarner Losh 	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3343f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
3344f7b951a8SRobert Watson 	if (error) {
3345f7b951a8SRobert Watson 		free(elements, M_MACTEMP);
3346f7b951a8SRobert Watson 		return (error);
3347f7b951a8SRobert Watson 	}
3348f7b951a8SRobert Watson 
3349a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3350f7b951a8SRobert Watson 	error = mac_externalize_cred_label(&td->td_ucred->cr_label,
3351a163d034SWarner Losh 	    elements, buffer, mac.m_buflen, M_WAITOK);
3352f7b951a8SRobert Watson 	if (error == 0)
3353f7b951a8SRobert Watson 		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
3354f7b951a8SRobert Watson 
3355f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3356f7b951a8SRobert Watson 	free(elements, M_MACTEMP);
335795fab37eSRobert Watson 	return (error);
335895fab37eSRobert Watson }
335995fab37eSRobert Watson 
336095fab37eSRobert Watson /*
336195fab37eSRobert Watson  * MPSAFE
336295fab37eSRobert Watson  */
336395fab37eSRobert Watson int
336495fab37eSRobert Watson __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
336595fab37eSRobert Watson {
336695fab37eSRobert Watson 	struct ucred *newcred, *oldcred;
336795fab37eSRobert Watson 	struct label intlabel;
3368f7b951a8SRobert Watson 	struct proc *p;
3369f7b951a8SRobert Watson 	struct mac mac;
3370f7b951a8SRobert Watson 	char *buffer;
337195fab37eSRobert Watson 	int error;
337295fab37eSRobert Watson 
3373f7b951a8SRobert Watson 	error = copyin(uap->mac_p, &mac, sizeof(mac));
337495fab37eSRobert Watson 	if (error)
337595fab37eSRobert Watson 		return (error);
337695fab37eSRobert Watson 
3377f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
337895fab37eSRobert Watson 	if (error)
337995fab37eSRobert Watson 		return (error);
338095fab37eSRobert Watson 
3381a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3382f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
3383f7b951a8SRobert Watson 	if (error) {
3384f7b951a8SRobert Watson 		free(buffer, M_MACTEMP);
3385f7b951a8SRobert Watson 		return (error);
3386f7b951a8SRobert Watson 	}
3387f7b951a8SRobert Watson 
3388f7b951a8SRobert Watson 	mac_init_cred_label(&intlabel);
3389f7b951a8SRobert Watson 	error = mac_internalize_cred_label(&intlabel, buffer);
3390f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3391f7b951a8SRobert Watson 	if (error) {
3392f7b951a8SRobert Watson 		mac_destroy_cred_label(&intlabel);
3393f7b951a8SRobert Watson 		return (error);
3394f7b951a8SRobert Watson 	}
3395f7b951a8SRobert Watson 
339695fab37eSRobert Watson 	newcred = crget();
339795fab37eSRobert Watson 
339895fab37eSRobert Watson 	p = td->td_proc;
339995fab37eSRobert Watson 	PROC_LOCK(p);
340095fab37eSRobert Watson 	oldcred = p->p_ucred;
340195fab37eSRobert Watson 
340295fab37eSRobert Watson 	error = mac_check_cred_relabel(oldcred, &intlabel);
340395fab37eSRobert Watson 	if (error) {
340495fab37eSRobert Watson 		PROC_UNLOCK(p);
340595fab37eSRobert Watson 		crfree(newcred);
3406f7b951a8SRobert Watson 		goto out;
340795fab37eSRobert Watson 	}
340895fab37eSRobert Watson 
340995fab37eSRobert Watson 	setsugid(p);
341095fab37eSRobert Watson 	crcopy(newcred, oldcred);
341195fab37eSRobert Watson 	mac_relabel_cred(newcred, &intlabel);
341295fab37eSRobert Watson 	p->p_ucred = newcred;
3413e5cb5e37SRobert Watson 
3414e5cb5e37SRobert Watson 	/*
3415e5cb5e37SRobert Watson 	 * Grab additional reference for use while revoking mmaps, prior
3416e5cb5e37SRobert Watson 	 * to releasing the proc lock and sharing the cred.
3417e5cb5e37SRobert Watson 	 */
3418e5cb5e37SRobert Watson 	crhold(newcred);
341995fab37eSRobert Watson 	PROC_UNLOCK(p);
3420e5cb5e37SRobert Watson 
3421f7b951a8SRobert Watson 	if (mac_enforce_vm) {
342216140035SRobert Watson 		mtx_lock(&Giant);
3423e5cb5e37SRobert Watson 		mac_cred_mmapped_drop_perms(td, newcred);
342416140035SRobert Watson 		mtx_unlock(&Giant);
3425f7b951a8SRobert Watson 	}
3426e5cb5e37SRobert Watson 
3427e5cb5e37SRobert Watson 	crfree(newcred);	/* Free revocation reference. */
342895fab37eSRobert Watson 	crfree(oldcred);
3429f7b951a8SRobert Watson 
3430f7b951a8SRobert Watson out:
3431f7b951a8SRobert Watson 	mac_destroy_cred_label(&intlabel);
3432f7b951a8SRobert Watson 	return (error);
343395fab37eSRobert Watson }
343495fab37eSRobert Watson 
343595fab37eSRobert Watson /*
343695fab37eSRobert Watson  * MPSAFE
343795fab37eSRobert Watson  */
343895fab37eSRobert Watson int
343995fab37eSRobert Watson __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
344095fab37eSRobert Watson {
3441f7b951a8SRobert Watson 	char *elements, *buffer;
3442f7b951a8SRobert Watson 	struct label intlabel;
344395fab37eSRobert Watson 	struct file *fp;
3444f7b951a8SRobert Watson 	struct mac mac;
344595fab37eSRobert Watson 	struct vnode *vp;
344695fab37eSRobert Watson 	struct pipe *pipe;
3447f7b951a8SRobert Watson 	short label_type;
344895fab37eSRobert Watson 	int error;
344995fab37eSRobert Watson 
3450f7b951a8SRobert Watson 	error = copyin(uap->mac_p, &mac, sizeof(mac));
3451f7b951a8SRobert Watson 	if (error)
3452f7b951a8SRobert Watson 		return (error);
345395fab37eSRobert Watson 
3454f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
3455f7b951a8SRobert Watson 	if (error)
3456f7b951a8SRobert Watson 		return (error);
3457f7b951a8SRobert Watson 
3458a163d034SWarner Losh 	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3459f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
3460f7b951a8SRobert Watson 	if (error) {
3461f7b951a8SRobert Watson 		free(elements, M_MACTEMP);
3462f7b951a8SRobert Watson 		return (error);
3463f7b951a8SRobert Watson 	}
3464f7b951a8SRobert Watson 
3465a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3466f7b951a8SRobert Watson 	mtx_lock(&Giant);				/* VFS */
3467d1e405c5SAlfred Perlstein 	error = fget(td, uap->fd, &fp);
346895fab37eSRobert Watson 	if (error)
346995fab37eSRobert Watson 		goto out;
347095fab37eSRobert Watson 
3471f7b951a8SRobert Watson 	label_type = fp->f_type;
347295fab37eSRobert Watson 	switch (fp->f_type) {
347395fab37eSRobert Watson 	case DTYPE_FIFO:
347495fab37eSRobert Watson 	case DTYPE_VNODE:
34753b6d9652SPoul-Henning Kamp 		vp = fp->f_vnode;
347695fab37eSRobert Watson 
3477f7b951a8SRobert Watson 		mac_init_vnode_label(&intlabel);
3478f7b951a8SRobert Watson 
347995fab37eSRobert Watson 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3480f7b951a8SRobert Watson 		mac_copy_vnode_label(&vp->v_label, &intlabel);
348195fab37eSRobert Watson 		VOP_UNLOCK(vp, 0, td);
3482f7b951a8SRobert Watson 
348395fab37eSRobert Watson 		break;
348495fab37eSRobert Watson 	case DTYPE_PIPE:
348548e3128bSMatthew Dillon 		pipe = fp->f_data;
3486f7b951a8SRobert Watson 
3487f7b951a8SRobert Watson 		mac_init_pipe_label(&intlabel);
3488f7b951a8SRobert Watson 
3489f7b951a8SRobert Watson 		PIPE_LOCK(pipe);
3490f7b951a8SRobert Watson 		mac_copy_pipe_label(pipe->pipe_label, &intlabel);
3491f7b951a8SRobert Watson 		PIPE_UNLOCK(pipe);
349295fab37eSRobert Watson 		break;
349395fab37eSRobert Watson 	default:
349495fab37eSRobert Watson 		error = EINVAL;
3495f7b951a8SRobert Watson 		fdrop(fp, td);
3496f7b951a8SRobert Watson 		goto out;
3497f7b951a8SRobert Watson 	}
3498f7b951a8SRobert Watson 	fdrop(fp, td);
3499f7b951a8SRobert Watson 
3500f7b951a8SRobert Watson 	switch (label_type) {
3501f7b951a8SRobert Watson 	case DTYPE_FIFO:
3502f7b951a8SRobert Watson 	case DTYPE_VNODE:
3503f7b951a8SRobert Watson 		if (error == 0)
3504f7b951a8SRobert Watson 			error = mac_externalize_vnode_label(&intlabel,
3505a163d034SWarner Losh 			    elements, buffer, mac.m_buflen, M_WAITOK);
3506f7b951a8SRobert Watson 		mac_destroy_vnode_label(&intlabel);
3507f7b951a8SRobert Watson 		break;
3508f7b951a8SRobert Watson 	case DTYPE_PIPE:
3509f7b951a8SRobert Watson 		error = mac_externalize_pipe_label(&intlabel, elements,
3510a163d034SWarner Losh 		    buffer, mac.m_buflen, M_WAITOK);
3511f7b951a8SRobert Watson 		mac_destroy_pipe_label(&intlabel);
3512f7b951a8SRobert Watson 		break;
3513f7b951a8SRobert Watson 	default:
3514f7b951a8SRobert Watson 		panic("__mac_get_fd: corrupted label_type");
351595fab37eSRobert Watson 	}
351695fab37eSRobert Watson 
351795fab37eSRobert Watson 	if (error == 0)
3518f7b951a8SRobert Watson 		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
351995fab37eSRobert Watson 
352095fab37eSRobert Watson out:
3521f7b951a8SRobert Watson 	mtx_unlock(&Giant);				/* VFS */
3522f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3523f7b951a8SRobert Watson 	free(elements, M_MACTEMP);
3524f7b951a8SRobert Watson 
352595fab37eSRobert Watson 	return (error);
352695fab37eSRobert Watson }
352795fab37eSRobert Watson 
352895fab37eSRobert Watson /*
352995fab37eSRobert Watson  * MPSAFE
353095fab37eSRobert Watson  */
353195fab37eSRobert Watson int
353295fab37eSRobert Watson __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
353395fab37eSRobert Watson {
3534f7b951a8SRobert Watson 	char *elements, *buffer;
353595fab37eSRobert Watson 	struct nameidata nd;
3536f7b951a8SRobert Watson 	struct label intlabel;
3537f7b951a8SRobert Watson 	struct mac mac;
353895fab37eSRobert Watson 	int error;
353995fab37eSRobert Watson 
3540f7b951a8SRobert Watson 	error = copyin(uap->mac_p, &mac, sizeof(mac));
3541f7b951a8SRobert Watson 	if (error)
3542f7b951a8SRobert Watson 		return (error);
3543f7b951a8SRobert Watson 
3544f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
3545f7b951a8SRobert Watson 	if (error)
3546f7b951a8SRobert Watson 		return (error);
3547f7b951a8SRobert Watson 
3548a163d034SWarner Losh 	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3549f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
3550f7b951a8SRobert Watson 	if (error) {
3551f7b951a8SRobert Watson 		free(elements, M_MACTEMP);
3552f7b951a8SRobert Watson 		return (error);
3553f7b951a8SRobert Watson 	}
3554f7b951a8SRobert Watson 
3555a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3556f7b951a8SRobert Watson 	mtx_lock(&Giant);				/* VFS */
3557f7b951a8SRobert Watson 	NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p,
3558f7b951a8SRobert Watson 	    td);
355995fab37eSRobert Watson 	error = namei(&nd);
356095fab37eSRobert Watson 	if (error)
356195fab37eSRobert Watson 		goto out;
356295fab37eSRobert Watson 
3563f7b951a8SRobert Watson 	mac_init_vnode_label(&intlabel);
3564f7b951a8SRobert Watson 	mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
3565763bbd2fSRobert Watson 	error = mac_externalize_vnode_label(&intlabel, elements, buffer,
3566a163d034SWarner Losh 	    mac.m_buflen, M_WAITOK);
3567f7b951a8SRobert Watson 
356895fab37eSRobert Watson 	NDFREE(&nd, 0);
3569f7b951a8SRobert Watson 	mac_destroy_vnode_label(&intlabel);
3570f7b951a8SRobert Watson 
3571f7b951a8SRobert Watson 	if (error == 0)
3572f7b951a8SRobert Watson 		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
3573f7b951a8SRobert Watson 
3574f7b951a8SRobert Watson out:
3575f7b951a8SRobert Watson 	mtx_unlock(&Giant);				/* VFS */
3576f7b951a8SRobert Watson 
3577f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3578f7b951a8SRobert Watson 	free(elements, M_MACTEMP);
3579f7b951a8SRobert Watson 
3580f7b951a8SRobert Watson 	return (error);
3581f7b951a8SRobert Watson }
3582f7b951a8SRobert Watson 
3583f7b951a8SRobert Watson /*
3584f7b951a8SRobert Watson  * MPSAFE
3585f7b951a8SRobert Watson  */
3586f7b951a8SRobert Watson int
3587f7b951a8SRobert Watson __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
3588f7b951a8SRobert Watson {
3589f7b951a8SRobert Watson 	char *elements, *buffer;
3590f7b951a8SRobert Watson 	struct nameidata nd;
3591f7b951a8SRobert Watson 	struct label intlabel;
3592f7b951a8SRobert Watson 	struct mac mac;
3593f7b951a8SRobert Watson 	int error;
3594f7b951a8SRobert Watson 
3595f7b951a8SRobert Watson 	error = copyin(uap->mac_p, &mac, sizeof(mac));
3596f7b951a8SRobert Watson 	if (error)
3597f7b951a8SRobert Watson 		return (error);
3598f7b951a8SRobert Watson 
3599f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
3600f7b951a8SRobert Watson 	if (error)
3601f7b951a8SRobert Watson 		return (error);
3602f7b951a8SRobert Watson 
3603a163d034SWarner Losh 	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3604f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
3605f7b951a8SRobert Watson 	if (error) {
3606f7b951a8SRobert Watson 		free(elements, M_MACTEMP);
3607f7b951a8SRobert Watson 		return (error);
3608f7b951a8SRobert Watson 	}
3609f7b951a8SRobert Watson 
3610a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3611f7b951a8SRobert Watson 	mtx_lock(&Giant);				/* VFS */
3612f7b951a8SRobert Watson 	NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p,
3613f7b951a8SRobert Watson 	    td);
3614f7b951a8SRobert Watson 	error = namei(&nd);
361595fab37eSRobert Watson 	if (error)
361695fab37eSRobert Watson 		goto out;
361795fab37eSRobert Watson 
3618f7b951a8SRobert Watson 	mac_init_vnode_label(&intlabel);
3619f7b951a8SRobert Watson 	mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
3620763bbd2fSRobert Watson 	error = mac_externalize_vnode_label(&intlabel, elements, buffer,
3621a163d034SWarner Losh 	    mac.m_buflen, M_WAITOK);
3622f7b951a8SRobert Watson 	NDFREE(&nd, 0);
3623f7b951a8SRobert Watson 	mac_destroy_vnode_label(&intlabel);
3624f7b951a8SRobert Watson 
3625f7b951a8SRobert Watson 	if (error == 0)
3626f7b951a8SRobert Watson 		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
362795fab37eSRobert Watson 
362895fab37eSRobert Watson out:
3629f7b951a8SRobert Watson 	mtx_unlock(&Giant);				/* VFS */
3630f7b951a8SRobert Watson 
3631f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3632f7b951a8SRobert Watson 	free(elements, M_MACTEMP);
3633f7b951a8SRobert Watson 
363495fab37eSRobert Watson 	return (error);
363595fab37eSRobert Watson }
363695fab37eSRobert Watson 
363795fab37eSRobert Watson /*
363895fab37eSRobert Watson  * MPSAFE
363995fab37eSRobert Watson  */
364095fab37eSRobert Watson int
364195fab37eSRobert Watson __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
364295fab37eSRobert Watson {
364395fab37eSRobert Watson 	struct label intlabel;
3644f7b951a8SRobert Watson 	struct pipe *pipe;
3645f7b951a8SRobert Watson 	struct file *fp;
364695fab37eSRobert Watson 	struct mount *mp;
364795fab37eSRobert Watson 	struct vnode *vp;
3648f7b951a8SRobert Watson 	struct mac mac;
3649f7b951a8SRobert Watson 	char *buffer;
365095fab37eSRobert Watson 	int error;
365195fab37eSRobert Watson 
3652f7b951a8SRobert Watson 	error = copyin(uap->mac_p, &mac, sizeof(mac));
3653f7b951a8SRobert Watson 	if (error)
3654f7b951a8SRobert Watson 		return (error);
3655f7b951a8SRobert Watson 
3656f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
3657f7b951a8SRobert Watson 	if (error)
3658f7b951a8SRobert Watson 		return (error);
3659f7b951a8SRobert Watson 
3660a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3661f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
3662f7b951a8SRobert Watson 	if (error) {
3663f7b951a8SRobert Watson 		free(buffer, M_MACTEMP);
3664f7b951a8SRobert Watson 		return (error);
3665f7b951a8SRobert Watson 	}
3666f7b951a8SRobert Watson 
3667f7b951a8SRobert Watson 	mtx_lock(&Giant);				/* VFS */
3668f7b951a8SRobert Watson 
3669d1e405c5SAlfred Perlstein 	error = fget(td, uap->fd, &fp);
367095fab37eSRobert Watson 	if (error)
3671f7b951a8SRobert Watson 		goto out;
367295fab37eSRobert Watson 
367395fab37eSRobert Watson 	switch (fp->f_type) {
367495fab37eSRobert Watson 	case DTYPE_FIFO:
367595fab37eSRobert Watson 	case DTYPE_VNODE:
3676f7b951a8SRobert Watson 		mac_init_vnode_label(&intlabel);
3677f7b951a8SRobert Watson 		error = mac_internalize_vnode_label(&intlabel, buffer);
3678f7b951a8SRobert Watson 		if (error) {
3679f7b951a8SRobert Watson 			mac_destroy_vnode_label(&intlabel);
3680f7b951a8SRobert Watson 			break;
3681f7b951a8SRobert Watson 		}
3682f7b951a8SRobert Watson 
36833b6d9652SPoul-Henning Kamp 		vp = fp->f_vnode;
368495fab37eSRobert Watson 		error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
3685f7b951a8SRobert Watson 		if (error != 0) {
3686f7b951a8SRobert Watson 			mac_destroy_vnode_label(&intlabel);
368795fab37eSRobert Watson 			break;
3688f7b951a8SRobert Watson 		}
368995fab37eSRobert Watson 
369095fab37eSRobert Watson 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
369195fab37eSRobert Watson 		error = vn_setlabel(vp, &intlabel, td->td_ucred);
369295fab37eSRobert Watson 		VOP_UNLOCK(vp, 0, td);
369395fab37eSRobert Watson 		vn_finished_write(mp);
3694f7b951a8SRobert Watson 
3695f7b951a8SRobert Watson 		mac_destroy_vnode_label(&intlabel);
369695fab37eSRobert Watson 		break;
3697f7b951a8SRobert Watson 
369895fab37eSRobert Watson 	case DTYPE_PIPE:
3699f7b951a8SRobert Watson 		mac_init_pipe_label(&intlabel);
3700f7b951a8SRobert Watson 		error = mac_internalize_pipe_label(&intlabel, buffer);
3701f7b951a8SRobert Watson 		if (error == 0) {
370248e3128bSMatthew Dillon 			pipe = fp->f_data;
37031aa37f53SRobert Watson 			PIPE_LOCK(pipe);
3704f7b951a8SRobert Watson 			error = mac_pipe_label_set(td->td_ucred, pipe,
3705f7b951a8SRobert Watson 			    &intlabel);
37061aa37f53SRobert Watson 			PIPE_UNLOCK(pipe);
3707f7b951a8SRobert Watson 		}
3708f7b951a8SRobert Watson 
3709f7b951a8SRobert Watson 		mac_destroy_pipe_label(&intlabel);
371095fab37eSRobert Watson 		break;
3711f7b951a8SRobert Watson 
371295fab37eSRobert Watson 	default:
371395fab37eSRobert Watson 		error = EINVAL;
371495fab37eSRobert Watson 	}
371595fab37eSRobert Watson 
371695fab37eSRobert Watson 	fdrop(fp, td);
3717f7b951a8SRobert Watson out:
3718f7b951a8SRobert Watson 	mtx_unlock(&Giant);				/* VFS */
3719f7b951a8SRobert Watson 
3720f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3721f7b951a8SRobert Watson 
372295fab37eSRobert Watson 	return (error);
372395fab37eSRobert Watson }
372495fab37eSRobert Watson 
372595fab37eSRobert Watson /*
372695fab37eSRobert Watson  * MPSAFE
372795fab37eSRobert Watson  */
372895fab37eSRobert Watson int
372995fab37eSRobert Watson __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
373095fab37eSRobert Watson {
373195fab37eSRobert Watson 	struct label intlabel;
3732f7b951a8SRobert Watson 	struct nameidata nd;
373395fab37eSRobert Watson 	struct mount *mp;
3734f7b951a8SRobert Watson 	struct mac mac;
3735f7b951a8SRobert Watson 	char *buffer;
373695fab37eSRobert Watson 	int error;
373795fab37eSRobert Watson 
3738f7b951a8SRobert Watson 	error = copyin(uap->mac_p, &mac, sizeof(mac));
373995fab37eSRobert Watson 	if (error)
3740f7b951a8SRobert Watson 		return (error);
374195fab37eSRobert Watson 
3742f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
374395fab37eSRobert Watson 	if (error)
3744f7b951a8SRobert Watson 		return (error);
374595fab37eSRobert Watson 
3746a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3747f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
3748f7b951a8SRobert Watson 	if (error) {
3749f7b951a8SRobert Watson 		free(buffer, M_MACTEMP);
375095fab37eSRobert Watson 		return (error);
375195fab37eSRobert Watson 	}
375295fab37eSRobert Watson 
3753f7b951a8SRobert Watson 	mac_init_vnode_label(&intlabel);
3754f7b951a8SRobert Watson 	error = mac_internalize_vnode_label(&intlabel, buffer);
3755f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3756f7b951a8SRobert Watson 	if (error) {
3757f7b951a8SRobert Watson 		mac_destroy_vnode_label(&intlabel);
3758f7b951a8SRobert Watson 		return (error);
3759f7b951a8SRobert Watson 	}
3760f7b951a8SRobert Watson 
3761f7b951a8SRobert Watson 	mtx_lock(&Giant);				/* VFS */
3762f7b951a8SRobert Watson 
3763f7b951a8SRobert Watson 	NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p,
3764f7b951a8SRobert Watson 	    td);
3765f7b951a8SRobert Watson 	error = namei(&nd);
3766f7b951a8SRobert Watson 	if (error == 0) {
3767f7b951a8SRobert Watson 		error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
3768f7b951a8SRobert Watson 		if (error == 0)
3769f7b951a8SRobert Watson 			error = vn_setlabel(nd.ni_vp, &intlabel,
3770f7b951a8SRobert Watson 			    td->td_ucred);
3771f7b951a8SRobert Watson 		vn_finished_write(mp);
3772f7b951a8SRobert Watson 	}
3773f7b951a8SRobert Watson 
3774f7b951a8SRobert Watson 	NDFREE(&nd, 0);
3775f7b951a8SRobert Watson 	mtx_unlock(&Giant);				/* VFS */
3776f7b951a8SRobert Watson 	mac_destroy_vnode_label(&intlabel);
3777f7b951a8SRobert Watson 
3778f7b951a8SRobert Watson 	return (error);
3779f7b951a8SRobert Watson }
3780f7b951a8SRobert Watson 
3781f7b951a8SRobert Watson /*
3782f7b951a8SRobert Watson  * MPSAFE
3783f7b951a8SRobert Watson  */
3784f7b951a8SRobert Watson int
3785f7b951a8SRobert Watson __mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
3786f7b951a8SRobert Watson {
3787f7b951a8SRobert Watson 	struct label intlabel;
3788f7b951a8SRobert Watson 	struct nameidata nd;
3789f7b951a8SRobert Watson 	struct mount *mp;
3790f7b951a8SRobert Watson 	struct mac mac;
3791f7b951a8SRobert Watson 	char *buffer;
3792f7b951a8SRobert Watson 	int error;
3793f7b951a8SRobert Watson 
3794f7b951a8SRobert Watson 	error = copyin(uap->mac_p, &mac, sizeof(mac));
3795f7b951a8SRobert Watson 	if (error)
3796f7b951a8SRobert Watson 		return (error);
3797f7b951a8SRobert Watson 
3798f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
3799f7b951a8SRobert Watson 	if (error)
3800f7b951a8SRobert Watson 		return (error);
3801f7b951a8SRobert Watson 
3802a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3803f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
3804f7b951a8SRobert Watson 	if (error) {
3805f7b951a8SRobert Watson 		free(buffer, M_MACTEMP);
3806f7b951a8SRobert Watson 		return (error);
3807f7b951a8SRobert Watson 	}
3808f7b951a8SRobert Watson 
3809f7b951a8SRobert Watson 	mac_init_vnode_label(&intlabel);
3810f7b951a8SRobert Watson 	error = mac_internalize_vnode_label(&intlabel, buffer);
3811f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
3812f7b951a8SRobert Watson 	if (error) {
3813f7b951a8SRobert Watson 		mac_destroy_vnode_label(&intlabel);
3814f7b951a8SRobert Watson 		return (error);
3815f7b951a8SRobert Watson 	}
3816f7b951a8SRobert Watson 
3817f7b951a8SRobert Watson 	mtx_lock(&Giant);				/* VFS */
3818f7b951a8SRobert Watson 
3819f7b951a8SRobert Watson 	NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p,
3820f7b951a8SRobert Watson 	    td);
3821f7b951a8SRobert Watson 	error = namei(&nd);
3822f7b951a8SRobert Watson 	if (error == 0) {
3823f7b951a8SRobert Watson 		error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
3824f7b951a8SRobert Watson 		if (error == 0)
3825f7b951a8SRobert Watson 			error = vn_setlabel(nd.ni_vp, &intlabel,
3826f7b951a8SRobert Watson 			    td->td_ucred);
3827f7b951a8SRobert Watson 		vn_finished_write(mp);
3828f7b951a8SRobert Watson 	}
3829f7b951a8SRobert Watson 
3830f7b951a8SRobert Watson 	NDFREE(&nd, 0);
3831f7b951a8SRobert Watson 	mtx_unlock(&Giant);				/* VFS */
3832f7b951a8SRobert Watson 	mac_destroy_vnode_label(&intlabel);
3833f7b951a8SRobert Watson 
3834f7b951a8SRobert Watson 	return (error);
3835f7b951a8SRobert Watson }
3836f7b951a8SRobert Watson 
3837f7b951a8SRobert Watson /*
3838f7b951a8SRobert Watson  * MPSAFE
3839f7b951a8SRobert Watson  */
384027f2eac7SRobert Watson int
384127f2eac7SRobert Watson mac_syscall(struct thread *td, struct mac_syscall_args *uap)
384227f2eac7SRobert Watson {
384327f2eac7SRobert Watson 	struct mac_policy_conf *mpc;
384427f2eac7SRobert Watson 	char target[MAC_MAX_POLICY_NAME];
384541a17fe3SRobert Watson 	int entrycount, error;
384627f2eac7SRobert Watson 
3847d1e405c5SAlfred Perlstein 	error = copyinstr(uap->policy, target, sizeof(target), NULL);
384827f2eac7SRobert Watson 	if (error)
384927f2eac7SRobert Watson 		return (error);
385027f2eac7SRobert Watson 
385127f2eac7SRobert Watson 	error = ENOSYS;
3852a6a65b05SRobert Watson 	LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {
385327f2eac7SRobert Watson 		if (strcmp(mpc->mpc_name, target) == 0 &&
385427f2eac7SRobert Watson 		    mpc->mpc_ops->mpo_syscall != NULL) {
385527f2eac7SRobert Watson 			error = mpc->mpc_ops->mpo_syscall(td,
3856d1e405c5SAlfred Perlstein 			    uap->call, uap->arg);
385727f2eac7SRobert Watson 			goto out;
385827f2eac7SRobert Watson 		}
385927f2eac7SRobert Watson 	}
386027f2eac7SRobert Watson 
386141a17fe3SRobert Watson 	if ((entrycount = mac_policy_list_conditional_busy()) != 0) {
386241a17fe3SRobert Watson 		LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {
386341a17fe3SRobert Watson 			if (strcmp(mpc->mpc_name, target) == 0 &&
386441a17fe3SRobert Watson 			    mpc->mpc_ops->mpo_syscall != NULL) {
386541a17fe3SRobert Watson 				error = mpc->mpc_ops->mpo_syscall(td,
386641a17fe3SRobert Watson 				    uap->call, uap->arg);
386741a17fe3SRobert Watson 				break;
386841a17fe3SRobert Watson 			}
386941a17fe3SRobert Watson 		}
387041a17fe3SRobert Watson 		mac_policy_list_unbusy();
387141a17fe3SRobert Watson 	}
387227f2eac7SRobert Watson out:
387327f2eac7SRobert Watson 	return (error);
387427f2eac7SRobert Watson }
387527f2eac7SRobert Watson 
387695fab37eSRobert Watson SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL);
387795fab37eSRobert Watson SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL);
387895fab37eSRobert Watson 
387995fab37eSRobert Watson #else /* !MAC */
38807bc82500SRobert Watson 
38817bc82500SRobert Watson int
3882f7b951a8SRobert Watson __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
3883f7b951a8SRobert Watson {
3884f7b951a8SRobert Watson 
3885f7b951a8SRobert Watson 	return (ENOSYS);
3886f7b951a8SRobert Watson }
3887f7b951a8SRobert Watson 
3888f7b951a8SRobert Watson int
38897bc82500SRobert Watson __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
38907bc82500SRobert Watson {
38917bc82500SRobert Watson 
38927bc82500SRobert Watson 	return (ENOSYS);
38937bc82500SRobert Watson }
38947bc82500SRobert Watson 
38957bc82500SRobert Watson int
38967bc82500SRobert Watson __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
38977bc82500SRobert Watson {
38987bc82500SRobert Watson 
38997bc82500SRobert Watson 	return (ENOSYS);
39007bc82500SRobert Watson }
39017bc82500SRobert Watson 
39027bc82500SRobert Watson int
39037bc82500SRobert Watson __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
39047bc82500SRobert Watson {
39057bc82500SRobert Watson 
39067bc82500SRobert Watson 	return (ENOSYS);
39077bc82500SRobert Watson }
39087bc82500SRobert Watson 
39097bc82500SRobert Watson int
39107bc82500SRobert Watson __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
39117bc82500SRobert Watson {
39127bc82500SRobert Watson 
39137bc82500SRobert Watson 	return (ENOSYS);
39147bc82500SRobert Watson }
39157bc82500SRobert Watson 
39167bc82500SRobert Watson int
3917f7b951a8SRobert Watson __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
3918f7b951a8SRobert Watson {
3919f7b951a8SRobert Watson 
3920f7b951a8SRobert Watson 	return (ENOSYS);
3921f7b951a8SRobert Watson }
3922f7b951a8SRobert Watson 
3923f7b951a8SRobert Watson int
39247bc82500SRobert Watson __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
39257bc82500SRobert Watson {
39267bc82500SRobert Watson 
39277bc82500SRobert Watson 	return (ENOSYS);
39287bc82500SRobert Watson }
39297bc82500SRobert Watson 
39307bc82500SRobert Watson int
39317bc82500SRobert Watson __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
39327bc82500SRobert Watson {
39337bc82500SRobert Watson 
39347bc82500SRobert Watson 	return (ENOSYS);
39357bc82500SRobert Watson }
393695fab37eSRobert Watson 
393727f2eac7SRobert Watson int
3938f7b951a8SRobert Watson __mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
3939f7b951a8SRobert Watson {
3940f7b951a8SRobert Watson 
3941f7b951a8SRobert Watson 	return (ENOSYS);
3942f7b951a8SRobert Watson }
3943f7b951a8SRobert Watson 
3944f7b951a8SRobert Watson int
394527f2eac7SRobert Watson mac_syscall(struct thread *td, struct mac_syscall_args *uap)
394627f2eac7SRobert Watson {
394727f2eac7SRobert Watson 
394827f2eac7SRobert Watson 	return (ENOSYS);
394927f2eac7SRobert Watson }
395027f2eac7SRobert Watson 
3951f7b951a8SRobert Watson #endif
3952