17bc82500SRobert Watson /*- 27bc82500SRobert Watson * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 37bc82500SRobert Watson * Copyright (c) 2001 Ilmar S. Habibulin 47bc82500SRobert Watson * Copyright (c) 2001, 2002 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 * 107bc82500SRobert Watson * This software was developed for the FreeBSD Project in part by NAI Labs, 117bc82500SRobert Watson * the Security Research Division of Network Associates, Inc. under 127bc82500SRobert Watson * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 137bc82500SRobert Watson * 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 * 3. The names of the authors may not be used to endorse or promote 247bc82500SRobert Watson * products derived from this software without specific prior written 257bc82500SRobert Watson * permission. 267bc82500SRobert Watson * 277bc82500SRobert Watson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 287bc82500SRobert Watson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 297bc82500SRobert Watson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 307bc82500SRobert Watson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 317bc82500SRobert Watson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 327bc82500SRobert Watson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 337bc82500SRobert Watson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 347bc82500SRobert Watson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 357bc82500SRobert Watson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 367bc82500SRobert Watson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 377bc82500SRobert Watson * SUCH DAMAGE. 387bc82500SRobert Watson * 397bc82500SRobert Watson * $FreeBSD$ 407bc82500SRobert Watson */ 417bc82500SRobert Watson /* 427bc82500SRobert Watson * Developed by the TrustedBSD Project. 437bc82500SRobert Watson * 447bc82500SRobert Watson * Framework for extensible kernel access control. Kernel and userland 457bc82500SRobert Watson * interface to the framework, policy registration and composition. 467bc82500SRobert Watson */ 477bc82500SRobert Watson 487bc82500SRobert Watson #include "opt_mac.h" 49328048bcSPoul-Henning Kamp #include "opt_devfs.h" 50f9d0d524SRobert Watson 517bc82500SRobert Watson #include <sys/param.h> 5295fab37eSRobert Watson #include <sys/extattr.h> 5395fab37eSRobert Watson #include <sys/kernel.h> 5495fab37eSRobert Watson #include <sys/lock.h> 55b656366bSBruce Evans #include <sys/malloc.h> 5695fab37eSRobert Watson #include <sys/mutex.h> 5795fab37eSRobert Watson #include <sys/mac.h> 587ba28492SRobert Watson #include <sys/module.h> 5995fab37eSRobert Watson #include <sys/proc.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 10295fab37eSRobert Watson #if MAC_MAX_POLICIES > 32 10395fab37eSRobert Watson #error "MAC_MAX_POLICIES too large" 10495fab37eSRobert Watson #endif 105a13c67daSRobert Watson 10695fab37eSRobert Watson static unsigned int mac_max_policies = MAC_MAX_POLICIES; 10795fab37eSRobert Watson static unsigned int mac_policy_offsets_free = (1 << MAC_MAX_POLICIES) - 1; 10895fab37eSRobert Watson SYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD, 10995fab37eSRobert Watson &mac_max_policies, 0, ""); 11095fab37eSRobert Watson 111a67fe518SRobert Watson /* 112a67fe518SRobert Watson * Has the kernel started generating labeled objects yet? All read/write 113a67fe518SRobert Watson * access to this variable is serialized during the boot process. Following 114a67fe518SRobert Watson * the end of serialization, we don't update this flag; no locking. 115a67fe518SRobert Watson */ 11695fab37eSRobert Watson static int mac_late = 0; 11795fab37eSRobert Watson 118763bbd2fSRobert Watson /* 119763bbd2fSRobert Watson * Warn about EA transactions only the first time they happen. 120763bbd2fSRobert Watson * Weak coherency, no locking. 121763bbd2fSRobert Watson */ 122763bbd2fSRobert Watson static int ea_warn_once = 0; 123763bbd2fSRobert Watson 12495fab37eSRobert Watson static int mac_enforce_fs = 1; 12595fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW, 12695fab37eSRobert Watson &mac_enforce_fs, 0, "Enforce MAC policy on file system objects"); 12795fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs); 12895fab37eSRobert Watson 12995fab37eSRobert Watson static int mac_enforce_network = 1; 13095fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, 13195fab37eSRobert Watson &mac_enforce_network, 0, "Enforce MAC policy on network packets"); 13295fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); 13395fab37eSRobert Watson 134b88c98f6SRobert Watson static int mac_enforce_pipe = 1; 135b88c98f6SRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW, 136b88c98f6SRobert Watson &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations"); 137c031391bSRobert Watson TUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe); 138b88c98f6SRobert Watson 13995fab37eSRobert Watson static int mac_enforce_process = 1; 14095fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW, 14195fab37eSRobert Watson &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations"); 14295fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_process", &mac_enforce_process); 14395fab37eSRobert Watson 144a2ecb9b7SRobert Watson static int mac_enforce_reboot = 1; 145a2ecb9b7SRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_reboot, CTLFLAG_RW, 146a2ecb9b7SRobert Watson &mac_enforce_reboot, 0, "Enforce MAC policy for reboot operations"); 147a2ecb9b7SRobert Watson TUNABLE_INT("security.mac.enforce_reboot", &mac_enforce_reboot); 148a2ecb9b7SRobert Watson 14995fab37eSRobert Watson static int mac_enforce_socket = 1; 15095fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 15195fab37eSRobert Watson &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 15295fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 15395fab37eSRobert Watson 154d3fc69eeSRobert Watson static int mac_enforce_sysctl = 1; 155d3fc69eeSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_sysctl, CTLFLAG_RW, 156d3fc69eeSRobert Watson &mac_enforce_sysctl, 0, "Enforce MAC policy on sysctl operations"); 157d3fc69eeSRobert Watson TUNABLE_INT("security.mac.enforce_sysctl", &mac_enforce_sysctl); 158d3fc69eeSRobert Watson 159ca7850c3SRobert Watson static int mac_enforce_vm = 1; 160ca7850c3SRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW, 161ca7850c3SRobert Watson &mac_enforce_vm, 0, "Enforce MAC policy on vm operations"); 162c031391bSRobert Watson TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm); 163ca7850c3SRobert Watson 16495fab37eSRobert Watson static int mac_cache_fslabel_in_vnode = 1; 16595fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW, 16695fab37eSRobert Watson &mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode"); 16795fab37eSRobert Watson TUNABLE_INT("security.mac.cache_fslabel_in_vnode", 16895fab37eSRobert Watson &mac_cache_fslabel_in_vnode); 16995fab37eSRobert Watson 170c0f39905SRobert Watson static int mac_mmap_revocation = 1; 171c0f39905SRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW, 172c0f39905SRobert Watson &mac_mmap_revocation, 0, "Revoke mmap access to files on subject " 173c0f39905SRobert Watson "relabel"); 17499fa64f8SRobert Watson static int mac_mmap_revocation_via_cow = 0; 17595fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW, 17695fab37eSRobert Watson &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via " 17795fab37eSRobert Watson "copy-on-write semantics, or by removing all write access"); 17895fab37eSRobert Watson 179f050add5SRobert Watson #ifdef MAC_DEBUG 1806be0c25eSRobert Watson SYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0, 1816be0c25eSRobert Watson "TrustedBSD MAC debug info"); 1826be0c25eSRobert Watson 1836be0c25eSRobert Watson static int mac_debug_label_fallback = 0; 1846be0c25eSRobert Watson SYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW, 1856be0c25eSRobert Watson &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label" 1866be0c25eSRobert Watson "when label is corrupted."); 1876be0c25eSRobert Watson TUNABLE_INT("security.mac.debug_label_fallback", 1886be0c25eSRobert Watson &mac_debug_label_fallback); 1896be0c25eSRobert Watson 190b2f0927aSRobert Watson SYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0, 191b2f0927aSRobert Watson "TrustedBSD MAC object counters"); 192b2f0927aSRobert Watson 19395fab37eSRobert Watson static unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs, 19495fab37eSRobert Watson nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents, 19595fab37eSRobert Watson nmacipqs, nmacpipes; 196b2f0927aSRobert Watson 197b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD, 19895fab37eSRobert Watson &nmacmbufs, 0, "number of mbufs in use"); 199b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD, 20095fab37eSRobert Watson &nmaccreds, 0, "number of ucreds in use"); 201b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD, 20295fab37eSRobert Watson &nmacifnets, 0, "number of ifnets in use"); 203b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD, 20495fab37eSRobert Watson &nmacipqs, 0, "number of ipqs in use"); 205b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD, 20695fab37eSRobert Watson &nmacbpfdescs, 0, "number of bpfdescs in use"); 207b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD, 20895fab37eSRobert Watson &nmacsockets, 0, "number of sockets in use"); 209b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, pipes, CTLFLAG_RD, 21095fab37eSRobert Watson &nmacpipes, 0, "number of pipes in use"); 211b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD, 21295fab37eSRobert Watson &nmacmounts, 0, "number of mounts in use"); 213b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD, 21495fab37eSRobert Watson &nmactemp, 0, "number of temporary labels in use"); 215b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD, 21695fab37eSRobert Watson &nmacvnodes, 0, "number of vnodes in use"); 217b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD, 21895fab37eSRobert Watson &nmacdevfsdirents, 0, "number of devfs dirents inuse"); 219f050add5SRobert Watson #endif 22095fab37eSRobert Watson 22195fab37eSRobert Watson static int error_select(int error1, int error2); 22295fab37eSRobert Watson static int mac_policy_register(struct mac_policy_conf *mpc); 22395fab37eSRobert Watson static int mac_policy_unregister(struct mac_policy_conf *mpc); 22495fab37eSRobert Watson 225e183f80eSRobert Watson static void mac_check_vnode_mmap_downgrade(struct ucred *cred, 226e183f80eSRobert Watson struct vnode *vp, int *prot); 22795fab37eSRobert Watson static void mac_cred_mmapped_drop_perms_recurse(struct thread *td, 22895fab37eSRobert Watson struct ucred *cred, struct vm_map *map); 22995fab37eSRobert Watson 23083985c26SRobert Watson static void mac_destroy_socket_label(struct label *label); 23183985c26SRobert Watson 232763bbd2fSRobert Watson static int mac_setlabel_vnode_extattr(struct ucred *cred, 233763bbd2fSRobert Watson struct vnode *vp, struct label *intlabel); 234763bbd2fSRobert Watson 235763bbd2fSRobert Watson 23695fab37eSRobert Watson MALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector"); 23795fab37eSRobert Watson MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes"); 238f7b951a8SRobert Watson MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage"); 23995fab37eSRobert Watson 24095fab37eSRobert Watson /* 24195fab37eSRobert Watson * mac_policy_list_lock protects the consistency of 'mac_policy_list', 24295fab37eSRobert Watson * the linked list of attached policy modules. Read-only consumers of 24395fab37eSRobert Watson * the list must acquire a shared lock for the duration of their use; 24495fab37eSRobert Watson * writers must acquire an exclusive lock. Note that for compound 24595fab37eSRobert Watson * operations, locks should be held for the entire compound operation, 24695fab37eSRobert Watson * and that this is not yet done for relabel requests. 24795fab37eSRobert Watson */ 24895fab37eSRobert Watson static struct mtx mac_policy_list_lock; 24995fab37eSRobert Watson static LIST_HEAD(, mac_policy_conf) mac_policy_list; 25095fab37eSRobert Watson static int mac_policy_list_busy; 25195fab37eSRobert Watson #define MAC_POLICY_LIST_LOCKINIT() mtx_init(&mac_policy_list_lock, \ 25295fab37eSRobert Watson "mac_policy_list_lock", NULL, MTX_DEF); 25395fab37eSRobert Watson #define MAC_POLICY_LIST_LOCK() mtx_lock(&mac_policy_list_lock); 25495fab37eSRobert Watson #define MAC_POLICY_LIST_UNLOCK() mtx_unlock(&mac_policy_list_lock); 25595fab37eSRobert Watson 25695fab37eSRobert Watson #define MAC_POLICY_LIST_BUSY() do { \ 25795fab37eSRobert Watson MAC_POLICY_LIST_LOCK(); \ 25895fab37eSRobert Watson mac_policy_list_busy++; \ 25995fab37eSRobert Watson MAC_POLICY_LIST_UNLOCK(); \ 26095fab37eSRobert Watson } while (0) 26195fab37eSRobert Watson 26295fab37eSRobert Watson #define MAC_POLICY_LIST_UNBUSY() do { \ 26395fab37eSRobert Watson MAC_POLICY_LIST_LOCK(); \ 26495fab37eSRobert Watson mac_policy_list_busy--; \ 26595fab37eSRobert Watson if (mac_policy_list_busy < 0) \ 26695fab37eSRobert Watson panic("Extra mac_policy_list_busy--"); \ 26795fab37eSRobert Watson MAC_POLICY_LIST_UNLOCK(); \ 26895fab37eSRobert Watson } while (0) 26995fab37eSRobert Watson 27095fab37eSRobert Watson /* 27195fab37eSRobert Watson * MAC_CHECK performs the designated check by walking the policy 27295fab37eSRobert Watson * module list and checking with each as to how it feels about the 27395fab37eSRobert Watson * request. Note that it returns its value via 'error' in the scope 27495fab37eSRobert Watson * of the caller. 27595fab37eSRobert Watson */ 27695fab37eSRobert Watson #define MAC_CHECK(check, args...) do { \ 27795fab37eSRobert Watson struct mac_policy_conf *mpc; \ 27895fab37eSRobert Watson \ 27995fab37eSRobert Watson error = 0; \ 28095fab37eSRobert Watson MAC_POLICY_LIST_BUSY(); \ 28195fab37eSRobert Watson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 28295fab37eSRobert Watson if (mpc->mpc_ops->mpo_ ## check != NULL) \ 28395fab37eSRobert Watson error = error_select( \ 28495fab37eSRobert Watson mpc->mpc_ops->mpo_ ## check (args), \ 28595fab37eSRobert Watson error); \ 28695fab37eSRobert Watson } \ 28795fab37eSRobert Watson MAC_POLICY_LIST_UNBUSY(); \ 28895fab37eSRobert Watson } while (0) 28995fab37eSRobert Watson 29095fab37eSRobert Watson /* 29195fab37eSRobert Watson * MAC_BOOLEAN performs the designated boolean composition by walking 29295fab37eSRobert Watson * the module list, invoking each instance of the operation, and 29395fab37eSRobert Watson * combining the results using the passed C operator. Note that it 29495fab37eSRobert Watson * returns its value via 'result' in the scope of the caller, which 29595fab37eSRobert Watson * should be initialized by the caller in a meaningful way to get 29695fab37eSRobert Watson * a meaningful result. 29795fab37eSRobert Watson */ 29895fab37eSRobert Watson #define MAC_BOOLEAN(operation, composition, args...) do { \ 29995fab37eSRobert Watson struct mac_policy_conf *mpc; \ 30095fab37eSRobert Watson \ 30195fab37eSRobert Watson MAC_POLICY_LIST_BUSY(); \ 30295fab37eSRobert Watson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 30395fab37eSRobert Watson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 30495fab37eSRobert Watson result = result composition \ 30595fab37eSRobert Watson mpc->mpc_ops->mpo_ ## operation (args); \ 30695fab37eSRobert Watson } \ 30795fab37eSRobert Watson MAC_POLICY_LIST_UNBUSY(); \ 30895fab37eSRobert Watson } while (0) 30995fab37eSRobert Watson 310f7b951a8SRobert Watson #define MAC_EXTERNALIZE(type, label, elementlist, outbuf, \ 311f7b951a8SRobert Watson outbuflen) do { \ 312f7b951a8SRobert Watson char *curptr, *curptr_start, *element_name, *element_temp; \ 313f7b951a8SRobert Watson size_t left, left_start, len; \ 314f7b951a8SRobert Watson int claimed, first, first_start, ignorenotfound; \ 315f7b951a8SRobert Watson \ 316f7b951a8SRobert Watson error = 0; \ 317f7b951a8SRobert Watson element_temp = elementlist; \ 318f7b951a8SRobert Watson curptr = outbuf; \ 319f7b951a8SRobert Watson curptr[0] = '\0'; \ 320f7b951a8SRobert Watson left = outbuflen; \ 321f7b951a8SRobert Watson first = 1; \ 322f7b951a8SRobert Watson while ((element_name = strsep(&element_temp, ",")) != NULL) { \ 323f7b951a8SRobert Watson curptr_start = curptr; \ 324f7b951a8SRobert Watson left_start = left; \ 325f7b951a8SRobert Watson first_start = first; \ 326f7b951a8SRobert Watson if (element_name[0] == '?') { \ 327f7b951a8SRobert Watson element_name++; \ 328f7b951a8SRobert Watson ignorenotfound = 1; \ 329f7b951a8SRobert Watson } else \ 330f7b951a8SRobert Watson ignorenotfound = 0; \ 331f7b951a8SRobert Watson claimed = 0; \ 332f7b951a8SRobert Watson if (first) { \ 333f7b951a8SRobert Watson len = snprintf(curptr, left, "%s/", \ 334f7b951a8SRobert Watson element_name); \ 335f7b951a8SRobert Watson first = 0; \ 336f7b951a8SRobert Watson } else \ 337f7b951a8SRobert Watson len = snprintf(curptr, left, ",%s/", \ 338f7b951a8SRobert Watson element_name); \ 339f7b951a8SRobert Watson if (len >= left) { \ 340f7b951a8SRobert Watson error = EINVAL; /* XXXMAC: E2BIG */ \ 341f7b951a8SRobert Watson break; \ 342f7b951a8SRobert Watson } \ 343f7b951a8SRobert Watson curptr += len; \ 344f7b951a8SRobert Watson left -= len; \ 345f7b951a8SRobert Watson \ 346f7b951a8SRobert Watson MAC_CHECK(externalize_ ## type, label, element_name, \ 347f7b951a8SRobert Watson curptr, left, &len, &claimed); \ 348f7b951a8SRobert Watson if (error) \ 349f7b951a8SRobert Watson break; \ 350f7b951a8SRobert Watson if (claimed == 1) { \ 351f7b951a8SRobert Watson if (len >= outbuflen) { \ 352f7b951a8SRobert Watson error = EINVAL; /* XXXMAC: E2BIG */ \ 353f7b951a8SRobert Watson break; \ 354f7b951a8SRobert Watson } \ 355f7b951a8SRobert Watson curptr += len; \ 356f7b951a8SRobert Watson left -= len; \ 357f7b951a8SRobert Watson } else if (claimed == 0 && ignorenotfound) { \ 358f7b951a8SRobert Watson /* \ 359f7b951a8SRobert Watson * Revert addition of the label element \ 360f7b951a8SRobert Watson * name. \ 361f7b951a8SRobert Watson */ \ 362f7b951a8SRobert Watson curptr = curptr_start; \ 363f7b951a8SRobert Watson *curptr = '\0'; \ 364f7b951a8SRobert Watson left = left_start; \ 365f7b951a8SRobert Watson first = first_start; \ 366f7b951a8SRobert Watson } else { \ 367f7b951a8SRobert Watson error = EINVAL; /* XXXMAC: ENOLABEL */ \ 368f7b951a8SRobert Watson break; \ 369f7b951a8SRobert Watson } \ 370f7b951a8SRobert Watson } \ 371f7b951a8SRobert Watson } while (0) 372f7b951a8SRobert Watson 373f7b951a8SRobert Watson #define MAC_INTERNALIZE(type, label, instring) do { \ 374f7b951a8SRobert Watson char *element, *element_name, *element_data; \ 375f7b951a8SRobert Watson int claimed; \ 376f7b951a8SRobert Watson \ 377f7b951a8SRobert Watson error = 0; \ 378f7b951a8SRobert Watson element = instring; \ 379f7b951a8SRobert Watson while ((element_name = strsep(&element, ",")) != NULL) { \ 380f7b951a8SRobert Watson element_data = element_name; \ 381f7b951a8SRobert Watson element_name = strsep(&element_data, "/"); \ 382f7b951a8SRobert Watson if (element_data == NULL) { \ 383f7b951a8SRobert Watson error = EINVAL; \ 384f7b951a8SRobert Watson break; \ 385f7b951a8SRobert Watson } \ 386f7b951a8SRobert Watson claimed = 0; \ 387f7b951a8SRobert Watson MAC_CHECK(internalize_ ## type, label, element_name, \ 388f7b951a8SRobert Watson element_data, &claimed); \ 389f7b951a8SRobert Watson if (error) \ 390f7b951a8SRobert Watson break; \ 391f7b951a8SRobert Watson if (claimed != 1) { \ 392f7b951a8SRobert Watson /* XXXMAC: Another error here? */ \ 393f7b951a8SRobert Watson error = EINVAL; \ 394f7b951a8SRobert Watson break; \ 395f7b951a8SRobert Watson } \ 396f7b951a8SRobert Watson } \ 397f7b951a8SRobert Watson } while (0) 398f7b951a8SRobert Watson 39995fab37eSRobert Watson /* 40095fab37eSRobert Watson * MAC_PERFORM performs the designated operation by walking the policy 40195fab37eSRobert Watson * module list and invoking that operation for each policy. 40295fab37eSRobert Watson */ 40395fab37eSRobert Watson #define MAC_PERFORM(operation, args...) do { \ 40495fab37eSRobert Watson struct mac_policy_conf *mpc; \ 40595fab37eSRobert Watson \ 40695fab37eSRobert Watson MAC_POLICY_LIST_BUSY(); \ 40795fab37eSRobert Watson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 40895fab37eSRobert Watson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 40995fab37eSRobert Watson mpc->mpc_ops->mpo_ ## operation (args); \ 41095fab37eSRobert Watson } \ 41195fab37eSRobert Watson MAC_POLICY_LIST_UNBUSY(); \ 41295fab37eSRobert Watson } while (0) 41395fab37eSRobert Watson 41495fab37eSRobert Watson /* 41595fab37eSRobert Watson * Initialize the MAC subsystem, including appropriate SMP locks. 41695fab37eSRobert Watson */ 41795fab37eSRobert Watson static void 41895fab37eSRobert Watson mac_init(void) 41995fab37eSRobert Watson { 42095fab37eSRobert Watson 42195fab37eSRobert Watson LIST_INIT(&mac_policy_list); 42295fab37eSRobert Watson MAC_POLICY_LIST_LOCKINIT(); 42395fab37eSRobert Watson } 42495fab37eSRobert Watson 42595fab37eSRobert Watson /* 42695fab37eSRobert Watson * For the purposes of modules that want to know if they were loaded 42795fab37eSRobert Watson * "early", set the mac_late flag once we've processed modules either 42895fab37eSRobert Watson * linked into the kernel, or loaded before the kernel startup. 42995fab37eSRobert Watson */ 43095fab37eSRobert Watson static void 43195fab37eSRobert Watson mac_late_init(void) 43295fab37eSRobert Watson { 43395fab37eSRobert Watson 43495fab37eSRobert Watson mac_late = 1; 43595fab37eSRobert Watson } 43695fab37eSRobert Watson 43795fab37eSRobert Watson /* 43895fab37eSRobert Watson * Allow MAC policy modules to register during boot, etc. 43995fab37eSRobert Watson */ 44095fab37eSRobert Watson int 44195fab37eSRobert Watson mac_policy_modevent(module_t mod, int type, void *data) 44295fab37eSRobert Watson { 44395fab37eSRobert Watson struct mac_policy_conf *mpc; 44495fab37eSRobert Watson int error; 44595fab37eSRobert Watson 44695fab37eSRobert Watson error = 0; 44795fab37eSRobert Watson mpc = (struct mac_policy_conf *) data; 44895fab37eSRobert Watson 44995fab37eSRobert Watson switch (type) { 45095fab37eSRobert Watson case MOD_LOAD: 45195fab37eSRobert Watson if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && 45295fab37eSRobert Watson mac_late) { 45395fab37eSRobert Watson printf("mac_policy_modevent: can't load %s policy " 45495fab37eSRobert Watson "after booting\n", mpc->mpc_name); 45595fab37eSRobert Watson error = EBUSY; 45695fab37eSRobert Watson break; 45795fab37eSRobert Watson } 45895fab37eSRobert Watson error = mac_policy_register(mpc); 45995fab37eSRobert Watson break; 46095fab37eSRobert Watson case MOD_UNLOAD: 46195fab37eSRobert Watson /* Don't unregister the module if it was never registered. */ 46295fab37eSRobert Watson if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) 46395fab37eSRobert Watson != 0) 46495fab37eSRobert Watson error = mac_policy_unregister(mpc); 46595fab37eSRobert Watson else 46695fab37eSRobert Watson error = 0; 46795fab37eSRobert Watson break; 46895fab37eSRobert Watson default: 46995fab37eSRobert Watson break; 47095fab37eSRobert Watson } 47195fab37eSRobert Watson 47295fab37eSRobert Watson return (error); 47395fab37eSRobert Watson } 47495fab37eSRobert Watson 47595fab37eSRobert Watson static int 47695fab37eSRobert Watson mac_policy_register(struct mac_policy_conf *mpc) 47795fab37eSRobert Watson { 47895fab37eSRobert Watson struct mac_policy_conf *tmpc; 47995fab37eSRobert Watson struct mac_policy_op_entry *mpe; 48095fab37eSRobert Watson int slot; 48195fab37eSRobert Watson 482cc51a2b5SRobert Watson MALLOC(mpc->mpc_ops, struct mac_policy_ops *, sizeof(*mpc->mpc_ops), 483cc51a2b5SRobert Watson M_MACOPVEC, M_WAITOK | M_ZERO); 48495fab37eSRobert Watson for (mpe = mpc->mpc_entries; mpe->mpe_constant != MAC_OP_LAST; mpe++) { 48595fab37eSRobert Watson switch (mpe->mpe_constant) { 48695fab37eSRobert Watson case MAC_OP_LAST: 48795fab37eSRobert Watson /* 48895fab37eSRobert Watson * Doesn't actually happen, but this allows checking 48995fab37eSRobert Watson * that all enumerated values are handled. 49095fab37eSRobert Watson */ 49195fab37eSRobert Watson break; 49295fab37eSRobert Watson case MAC_DESTROY: 49395fab37eSRobert Watson mpc->mpc_ops->mpo_destroy = 49495fab37eSRobert Watson mpe->mpe_function; 49595fab37eSRobert Watson break; 49695fab37eSRobert Watson case MAC_INIT: 49795fab37eSRobert Watson mpc->mpc_ops->mpo_init = 49895fab37eSRobert Watson mpe->mpe_function; 49995fab37eSRobert Watson break; 50027f2eac7SRobert Watson case MAC_SYSCALL: 50127f2eac7SRobert Watson mpc->mpc_ops->mpo_syscall = 50227f2eac7SRobert Watson mpe->mpe_function; 50327f2eac7SRobert Watson break; 50496adb909SRobert Watson case MAC_INIT_BPFDESC_LABEL: 50596adb909SRobert Watson mpc->mpc_ops->mpo_init_bpfdesc_label = 50695fab37eSRobert Watson mpe->mpe_function; 50795fab37eSRobert Watson break; 50896adb909SRobert Watson case MAC_INIT_CRED_LABEL: 50996adb909SRobert Watson mpc->mpc_ops->mpo_init_cred_label = 51095fab37eSRobert Watson mpe->mpe_function; 51195fab37eSRobert Watson break; 51296adb909SRobert Watson case MAC_INIT_DEVFSDIRENT_LABEL: 51396adb909SRobert Watson mpc->mpc_ops->mpo_init_devfsdirent_label = 51495fab37eSRobert Watson mpe->mpe_function; 51595fab37eSRobert Watson break; 51696adb909SRobert Watson case MAC_INIT_IFNET_LABEL: 51796adb909SRobert Watson mpc->mpc_ops->mpo_init_ifnet_label = 51895fab37eSRobert Watson mpe->mpe_function; 51995fab37eSRobert Watson break; 52096adb909SRobert Watson case MAC_INIT_IPQ_LABEL: 52196adb909SRobert Watson mpc->mpc_ops->mpo_init_ipq_label = 52295fab37eSRobert Watson mpe->mpe_function; 52395fab37eSRobert Watson break; 52496adb909SRobert Watson case MAC_INIT_MBUF_LABEL: 52596adb909SRobert Watson mpc->mpc_ops->mpo_init_mbuf_label = 52695fab37eSRobert Watson mpe->mpe_function; 52795fab37eSRobert Watson break; 52896adb909SRobert Watson case MAC_INIT_MOUNT_LABEL: 52996adb909SRobert Watson mpc->mpc_ops->mpo_init_mount_label = 53095fab37eSRobert Watson mpe->mpe_function; 53195fab37eSRobert Watson break; 53296adb909SRobert Watson case MAC_INIT_MOUNT_FS_LABEL: 53396adb909SRobert Watson mpc->mpc_ops->mpo_init_mount_fs_label = 53495fab37eSRobert Watson mpe->mpe_function; 53595fab37eSRobert Watson break; 53696adb909SRobert Watson case MAC_INIT_PIPE_LABEL: 53796adb909SRobert Watson mpc->mpc_ops->mpo_init_pipe_label = 53895fab37eSRobert Watson mpe->mpe_function; 53995fab37eSRobert Watson break; 54096adb909SRobert Watson case MAC_INIT_SOCKET_LABEL: 54196adb909SRobert Watson mpc->mpc_ops->mpo_init_socket_label = 54295fab37eSRobert Watson mpe->mpe_function; 54395fab37eSRobert Watson break; 54496adb909SRobert Watson case MAC_INIT_SOCKET_PEER_LABEL: 54596adb909SRobert Watson mpc->mpc_ops->mpo_init_socket_peer_label = 54695fab37eSRobert Watson mpe->mpe_function; 54795fab37eSRobert Watson break; 54896adb909SRobert Watson case MAC_INIT_VNODE_LABEL: 54996adb909SRobert Watson mpc->mpc_ops->mpo_init_vnode_label = 55095fab37eSRobert Watson mpe->mpe_function; 55195fab37eSRobert Watson break; 55296adb909SRobert Watson case MAC_DESTROY_BPFDESC_LABEL: 55396adb909SRobert Watson mpc->mpc_ops->mpo_destroy_bpfdesc_label = 55495fab37eSRobert Watson mpe->mpe_function; 55595fab37eSRobert Watson break; 55696adb909SRobert Watson case MAC_DESTROY_CRED_LABEL: 55796adb909SRobert Watson mpc->mpc_ops->mpo_destroy_cred_label = 55895fab37eSRobert Watson mpe->mpe_function; 55995fab37eSRobert Watson break; 56096adb909SRobert Watson case MAC_DESTROY_DEVFSDIRENT_LABEL: 56196adb909SRobert Watson mpc->mpc_ops->mpo_destroy_devfsdirent_label = 56295fab37eSRobert Watson mpe->mpe_function; 56395fab37eSRobert Watson break; 56496adb909SRobert Watson case MAC_DESTROY_IFNET_LABEL: 56596adb909SRobert Watson mpc->mpc_ops->mpo_destroy_ifnet_label = 56695fab37eSRobert Watson mpe->mpe_function; 56795fab37eSRobert Watson break; 56896adb909SRobert Watson case MAC_DESTROY_IPQ_LABEL: 56996adb909SRobert Watson mpc->mpc_ops->mpo_destroy_ipq_label = 57095fab37eSRobert Watson mpe->mpe_function; 57195fab37eSRobert Watson break; 57296adb909SRobert Watson case MAC_DESTROY_MBUF_LABEL: 57396adb909SRobert Watson mpc->mpc_ops->mpo_destroy_mbuf_label = 57495fab37eSRobert Watson mpe->mpe_function; 57595fab37eSRobert Watson break; 57696adb909SRobert Watson case MAC_DESTROY_MOUNT_LABEL: 57796adb909SRobert Watson mpc->mpc_ops->mpo_destroy_mount_label = 57895fab37eSRobert Watson mpe->mpe_function; 57995fab37eSRobert Watson break; 58096adb909SRobert Watson case MAC_DESTROY_MOUNT_FS_LABEL: 58196adb909SRobert Watson mpc->mpc_ops->mpo_destroy_mount_fs_label = 58295fab37eSRobert Watson mpe->mpe_function; 58395fab37eSRobert Watson break; 58496adb909SRobert Watson case MAC_DESTROY_PIPE_LABEL: 58596adb909SRobert Watson mpc->mpc_ops->mpo_destroy_pipe_label = 58696adb909SRobert Watson mpe->mpe_function; 58796adb909SRobert Watson break; 58896adb909SRobert Watson case MAC_DESTROY_SOCKET_LABEL: 58996adb909SRobert Watson mpc->mpc_ops->mpo_destroy_socket_label = 59096adb909SRobert Watson mpe->mpe_function; 59196adb909SRobert Watson break; 59296adb909SRobert Watson case MAC_DESTROY_SOCKET_PEER_LABEL: 59396adb909SRobert Watson mpc->mpc_ops->mpo_destroy_socket_peer_label = 59496adb909SRobert Watson mpe->mpe_function; 59596adb909SRobert Watson break; 59696adb909SRobert Watson case MAC_DESTROY_VNODE_LABEL: 59796adb909SRobert Watson mpc->mpc_ops->mpo_destroy_vnode_label = 59895fab37eSRobert Watson mpe->mpe_function; 59995fab37eSRobert Watson break; 600f7b951a8SRobert Watson case MAC_COPY_PIPE_LABEL: 601f7b951a8SRobert Watson mpc->mpc_ops->mpo_copy_pipe_label = 60295fab37eSRobert Watson mpe->mpe_function; 60395fab37eSRobert Watson break; 604f7b951a8SRobert Watson case MAC_COPY_VNODE_LABEL: 605f7b951a8SRobert Watson mpc->mpc_ops->mpo_copy_vnode_label = 606f7b951a8SRobert Watson mpe->mpe_function; 607f7b951a8SRobert Watson break; 608f7b951a8SRobert Watson case MAC_EXTERNALIZE_CRED_LABEL: 609f7b951a8SRobert Watson mpc->mpc_ops->mpo_externalize_cred_label = 610f7b951a8SRobert Watson mpe->mpe_function; 611f7b951a8SRobert Watson break; 612f7b951a8SRobert Watson case MAC_EXTERNALIZE_IFNET_LABEL: 613f7b951a8SRobert Watson mpc->mpc_ops->mpo_externalize_ifnet_label = 614f7b951a8SRobert Watson mpe->mpe_function; 615f7b951a8SRobert Watson break; 616f7b951a8SRobert Watson case MAC_EXTERNALIZE_PIPE_LABEL: 617f7b951a8SRobert Watson mpc->mpc_ops->mpo_externalize_pipe_label = 618f7b951a8SRobert Watson mpe->mpe_function; 619f7b951a8SRobert Watson break; 620f7b951a8SRobert Watson case MAC_EXTERNALIZE_SOCKET_LABEL: 621f7b951a8SRobert Watson mpc->mpc_ops->mpo_externalize_socket_label = 622f7b951a8SRobert Watson mpe->mpe_function; 623f7b951a8SRobert Watson break; 624f7b951a8SRobert Watson case MAC_EXTERNALIZE_SOCKET_PEER_LABEL: 625f7b951a8SRobert Watson mpc->mpc_ops->mpo_externalize_socket_peer_label = 626f7b951a8SRobert Watson mpe->mpe_function; 627f7b951a8SRobert Watson break; 628f7b951a8SRobert Watson case MAC_EXTERNALIZE_VNODE_LABEL: 629f7b951a8SRobert Watson mpc->mpc_ops->mpo_externalize_vnode_label = 630f7b951a8SRobert Watson mpe->mpe_function; 631f7b951a8SRobert Watson break; 632f7b951a8SRobert Watson case MAC_INTERNALIZE_CRED_LABEL: 633f7b951a8SRobert Watson mpc->mpc_ops->mpo_internalize_cred_label = 634f7b951a8SRobert Watson mpe->mpe_function; 635f7b951a8SRobert Watson break; 636f7b951a8SRobert Watson case MAC_INTERNALIZE_IFNET_LABEL: 637f7b951a8SRobert Watson mpc->mpc_ops->mpo_internalize_ifnet_label = 638f7b951a8SRobert Watson mpe->mpe_function; 639f7b951a8SRobert Watson break; 640f7b951a8SRobert Watson case MAC_INTERNALIZE_PIPE_LABEL: 641f7b951a8SRobert Watson mpc->mpc_ops->mpo_internalize_pipe_label = 642f7b951a8SRobert Watson mpe->mpe_function; 643f7b951a8SRobert Watson break; 644f7b951a8SRobert Watson case MAC_INTERNALIZE_SOCKET_LABEL: 645f7b951a8SRobert Watson mpc->mpc_ops->mpo_internalize_socket_label = 646f7b951a8SRobert Watson mpe->mpe_function; 647f7b951a8SRobert Watson break; 648f7b951a8SRobert Watson case MAC_INTERNALIZE_VNODE_LABEL: 649f7b951a8SRobert Watson mpc->mpc_ops->mpo_internalize_vnode_label = 65095fab37eSRobert Watson mpe->mpe_function; 65195fab37eSRobert Watson break; 65295fab37eSRobert Watson case MAC_CREATE_DEVFS_DEVICE: 65395fab37eSRobert Watson mpc->mpc_ops->mpo_create_devfs_device = 65495fab37eSRobert Watson mpe->mpe_function; 65595fab37eSRobert Watson break; 65695fab37eSRobert Watson case MAC_CREATE_DEVFS_DIRECTORY: 65795fab37eSRobert Watson mpc->mpc_ops->mpo_create_devfs_directory = 65895fab37eSRobert Watson mpe->mpe_function; 65995fab37eSRobert Watson break; 66074e62b1bSRobert Watson case MAC_CREATE_DEVFS_SYMLINK: 66174e62b1bSRobert Watson mpc->mpc_ops->mpo_create_devfs_symlink = 66274e62b1bSRobert Watson mpe->mpe_function; 66374e62b1bSRobert Watson break; 66495fab37eSRobert Watson case MAC_CREATE_DEVFS_VNODE: 66595fab37eSRobert Watson mpc->mpc_ops->mpo_create_devfs_vnode = 66695fab37eSRobert Watson mpe->mpe_function; 66795fab37eSRobert Watson break; 66895fab37eSRobert Watson case MAC_CREATE_MOUNT: 66995fab37eSRobert Watson mpc->mpc_ops->mpo_create_mount = 67095fab37eSRobert Watson mpe->mpe_function; 67195fab37eSRobert Watson break; 67295fab37eSRobert Watson case MAC_CREATE_ROOT_MOUNT: 67395fab37eSRobert Watson mpc->mpc_ops->mpo_create_root_mount = 67495fab37eSRobert Watson mpe->mpe_function; 67595fab37eSRobert Watson break; 67695fab37eSRobert Watson case MAC_RELABEL_VNODE: 67795fab37eSRobert Watson mpc->mpc_ops->mpo_relabel_vnode = 67895fab37eSRobert Watson mpe->mpe_function; 67995fab37eSRobert Watson break; 68095fab37eSRobert Watson case MAC_UPDATE_DEVFSDIRENT: 68195fab37eSRobert Watson mpc->mpc_ops->mpo_update_devfsdirent = 68295fab37eSRobert Watson mpe->mpe_function; 68395fab37eSRobert Watson break; 684763bbd2fSRobert Watson case MAC_ASSOCIATE_VNODE_DEVFS: 685763bbd2fSRobert Watson mpc->mpc_ops->mpo_associate_vnode_devfs = 68695fab37eSRobert Watson mpe->mpe_function; 68795fab37eSRobert Watson break; 688763bbd2fSRobert Watson case MAC_ASSOCIATE_VNODE_EXTATTR: 689763bbd2fSRobert Watson mpc->mpc_ops->mpo_associate_vnode_extattr = 69095fab37eSRobert Watson mpe->mpe_function; 69195fab37eSRobert Watson break; 692763bbd2fSRobert Watson case MAC_ASSOCIATE_VNODE_SINGLELABEL: 693763bbd2fSRobert Watson mpc->mpc_ops->mpo_associate_vnode_singlelabel = 69495fab37eSRobert Watson mpe->mpe_function; 69595fab37eSRobert Watson break; 696763bbd2fSRobert Watson case MAC_CREATE_VNODE_EXTATTR: 697763bbd2fSRobert Watson mpc->mpc_ops->mpo_create_vnode_extattr = 698763bbd2fSRobert Watson mpe->mpe_function; 699763bbd2fSRobert Watson break; 700763bbd2fSRobert Watson case MAC_SETLABEL_VNODE_EXTATTR: 701763bbd2fSRobert Watson mpc->mpc_ops->mpo_setlabel_vnode_extattr = 70295fab37eSRobert Watson mpe->mpe_function; 70395fab37eSRobert Watson break; 70495fab37eSRobert Watson case MAC_CREATE_MBUF_FROM_SOCKET: 70595fab37eSRobert Watson mpc->mpc_ops->mpo_create_mbuf_from_socket = 70695fab37eSRobert Watson mpe->mpe_function; 70795fab37eSRobert Watson break; 70895fab37eSRobert Watson case MAC_CREATE_PIPE: 70995fab37eSRobert Watson mpc->mpc_ops->mpo_create_pipe = 71095fab37eSRobert Watson mpe->mpe_function; 71195fab37eSRobert Watson break; 71295fab37eSRobert Watson case MAC_CREATE_SOCKET: 71395fab37eSRobert Watson mpc->mpc_ops->mpo_create_socket = 71495fab37eSRobert Watson mpe->mpe_function; 71595fab37eSRobert Watson break; 71695fab37eSRobert Watson case MAC_CREATE_SOCKET_FROM_SOCKET: 71795fab37eSRobert Watson mpc->mpc_ops->mpo_create_socket_from_socket = 71895fab37eSRobert Watson mpe->mpe_function; 71995fab37eSRobert Watson break; 72095fab37eSRobert Watson case MAC_RELABEL_PIPE: 72195fab37eSRobert Watson mpc->mpc_ops->mpo_relabel_pipe = 72295fab37eSRobert Watson mpe->mpe_function; 72395fab37eSRobert Watson break; 72495fab37eSRobert Watson case MAC_RELABEL_SOCKET: 72595fab37eSRobert Watson mpc->mpc_ops->mpo_relabel_socket = 72695fab37eSRobert Watson mpe->mpe_function; 72795fab37eSRobert Watson break; 72895fab37eSRobert Watson case MAC_SET_SOCKET_PEER_FROM_MBUF: 72995fab37eSRobert Watson mpc->mpc_ops->mpo_set_socket_peer_from_mbuf = 73095fab37eSRobert Watson mpe->mpe_function; 73195fab37eSRobert Watson break; 73295fab37eSRobert Watson case MAC_SET_SOCKET_PEER_FROM_SOCKET: 73395fab37eSRobert Watson mpc->mpc_ops->mpo_set_socket_peer_from_socket = 73495fab37eSRobert Watson mpe->mpe_function; 73595fab37eSRobert Watson break; 73695fab37eSRobert Watson case MAC_CREATE_BPFDESC: 73795fab37eSRobert Watson mpc->mpc_ops->mpo_create_bpfdesc = 73895fab37eSRobert Watson mpe->mpe_function; 73995fab37eSRobert Watson break; 74095fab37eSRobert Watson case MAC_CREATE_DATAGRAM_FROM_IPQ: 74195fab37eSRobert Watson mpc->mpc_ops->mpo_create_datagram_from_ipq = 74295fab37eSRobert Watson mpe->mpe_function; 74395fab37eSRobert Watson break; 74495fab37eSRobert Watson case MAC_CREATE_FRAGMENT: 74595fab37eSRobert Watson mpc->mpc_ops->mpo_create_fragment = 74695fab37eSRobert Watson mpe->mpe_function; 74795fab37eSRobert Watson break; 74895fab37eSRobert Watson case MAC_CREATE_IFNET: 74995fab37eSRobert Watson mpc->mpc_ops->mpo_create_ifnet = 75095fab37eSRobert Watson mpe->mpe_function; 75195fab37eSRobert Watson break; 75295fab37eSRobert Watson case MAC_CREATE_IPQ: 75395fab37eSRobert Watson mpc->mpc_ops->mpo_create_ipq = 75495fab37eSRobert Watson mpe->mpe_function; 75595fab37eSRobert Watson break; 75695fab37eSRobert Watson case MAC_CREATE_MBUF_FROM_MBUF: 75795fab37eSRobert Watson mpc->mpc_ops->mpo_create_mbuf_from_mbuf = 75895fab37eSRobert Watson mpe->mpe_function; 75995fab37eSRobert Watson break; 76095fab37eSRobert Watson case MAC_CREATE_MBUF_LINKLAYER: 76195fab37eSRobert Watson mpc->mpc_ops->mpo_create_mbuf_linklayer = 76295fab37eSRobert Watson mpe->mpe_function; 76395fab37eSRobert Watson break; 76495fab37eSRobert Watson case MAC_CREATE_MBUF_FROM_BPFDESC: 76595fab37eSRobert Watson mpc->mpc_ops->mpo_create_mbuf_from_bpfdesc = 76695fab37eSRobert Watson mpe->mpe_function; 76795fab37eSRobert Watson break; 76895fab37eSRobert Watson case MAC_CREATE_MBUF_FROM_IFNET: 76995fab37eSRobert Watson mpc->mpc_ops->mpo_create_mbuf_from_ifnet = 77095fab37eSRobert Watson mpe->mpe_function; 77195fab37eSRobert Watson break; 77295fab37eSRobert Watson case MAC_CREATE_MBUF_MULTICAST_ENCAP: 77395fab37eSRobert Watson mpc->mpc_ops->mpo_create_mbuf_multicast_encap = 77495fab37eSRobert Watson mpe->mpe_function; 77595fab37eSRobert Watson break; 77695fab37eSRobert Watson case MAC_CREATE_MBUF_NETLAYER: 77795fab37eSRobert Watson mpc->mpc_ops->mpo_create_mbuf_netlayer = 77895fab37eSRobert Watson mpe->mpe_function; 77995fab37eSRobert Watson break; 78095fab37eSRobert Watson case MAC_FRAGMENT_MATCH: 78195fab37eSRobert Watson mpc->mpc_ops->mpo_fragment_match = 78295fab37eSRobert Watson mpe->mpe_function; 78395fab37eSRobert Watson break; 78495fab37eSRobert Watson case MAC_RELABEL_IFNET: 78595fab37eSRobert Watson mpc->mpc_ops->mpo_relabel_ifnet = 78695fab37eSRobert Watson mpe->mpe_function; 78795fab37eSRobert Watson break; 78895fab37eSRobert Watson case MAC_UPDATE_IPQ: 78995fab37eSRobert Watson mpc->mpc_ops->mpo_update_ipq = 79095fab37eSRobert Watson mpe->mpe_function; 79195fab37eSRobert Watson break; 79295fab37eSRobert Watson case MAC_CREATE_CRED: 79395fab37eSRobert Watson mpc->mpc_ops->mpo_create_cred = 79495fab37eSRobert Watson mpe->mpe_function; 79595fab37eSRobert Watson break; 79695fab37eSRobert Watson case MAC_EXECVE_TRANSITION: 79795fab37eSRobert Watson mpc->mpc_ops->mpo_execve_transition = 79895fab37eSRobert Watson mpe->mpe_function; 79995fab37eSRobert Watson break; 80095fab37eSRobert Watson case MAC_EXECVE_WILL_TRANSITION: 80195fab37eSRobert Watson mpc->mpc_ops->mpo_execve_will_transition = 80295fab37eSRobert Watson mpe->mpe_function; 80395fab37eSRobert Watson break; 80495fab37eSRobert Watson case MAC_CREATE_PROC0: 805226b96fbSRobert Watson mpc->mpc_ops->mpo_create_proc0 = 806226b96fbSRobert Watson mpe->mpe_function; 80795fab37eSRobert Watson break; 80895fab37eSRobert Watson case MAC_CREATE_PROC1: 809226b96fbSRobert Watson mpc->mpc_ops->mpo_create_proc1 = 810226b96fbSRobert Watson mpe->mpe_function; 81195fab37eSRobert Watson break; 81295fab37eSRobert Watson case MAC_RELABEL_CRED: 81395fab37eSRobert Watson mpc->mpc_ops->mpo_relabel_cred = 81495fab37eSRobert Watson mpe->mpe_function; 81595fab37eSRobert Watson break; 81692dbb82aSRobert Watson case MAC_THREAD_USERRET: 81792dbb82aSRobert Watson mpc->mpc_ops->mpo_thread_userret = 81892dbb82aSRobert Watson mpe->mpe_function; 81992dbb82aSRobert Watson break; 82095fab37eSRobert Watson case MAC_CHECK_BPFDESC_RECEIVE: 82195fab37eSRobert Watson mpc->mpc_ops->mpo_check_bpfdesc_receive = 82295fab37eSRobert Watson mpe->mpe_function; 82395fab37eSRobert Watson break; 82495fab37eSRobert Watson case MAC_CHECK_CRED_RELABEL: 82595fab37eSRobert Watson mpc->mpc_ops->mpo_check_cred_relabel = 82695fab37eSRobert Watson mpe->mpe_function; 82795fab37eSRobert Watson break; 82895fab37eSRobert Watson case MAC_CHECK_CRED_VISIBLE: 82995fab37eSRobert Watson mpc->mpc_ops->mpo_check_cred_visible = 83095fab37eSRobert Watson mpe->mpe_function; 83195fab37eSRobert Watson break; 83295fab37eSRobert Watson case MAC_CHECK_IFNET_RELABEL: 83395fab37eSRobert Watson mpc->mpc_ops->mpo_check_ifnet_relabel = 83495fab37eSRobert Watson mpe->mpe_function; 83595fab37eSRobert Watson break; 83695fab37eSRobert Watson case MAC_CHECK_IFNET_TRANSMIT: 83795fab37eSRobert Watson mpc->mpc_ops->mpo_check_ifnet_transmit = 83895fab37eSRobert Watson mpe->mpe_function; 83995fab37eSRobert Watson break; 84095fab37eSRobert Watson case MAC_CHECK_MOUNT_STAT: 84195fab37eSRobert Watson mpc->mpc_ops->mpo_check_mount_stat = 84295fab37eSRobert Watson mpe->mpe_function; 84395fab37eSRobert Watson break; 84495fab37eSRobert Watson case MAC_CHECK_PIPE_IOCTL: 84595fab37eSRobert Watson mpc->mpc_ops->mpo_check_pipe_ioctl = 84695fab37eSRobert Watson mpe->mpe_function; 84795fab37eSRobert Watson break; 848c024c3eeSRobert Watson case MAC_CHECK_PIPE_POLL: 849c024c3eeSRobert Watson mpc->mpc_ops->mpo_check_pipe_poll = 850c024c3eeSRobert Watson mpe->mpe_function; 851c024c3eeSRobert Watson break; 852c024c3eeSRobert Watson case MAC_CHECK_PIPE_READ: 853c024c3eeSRobert Watson mpc->mpc_ops->mpo_check_pipe_read = 85495fab37eSRobert Watson mpe->mpe_function; 85595fab37eSRobert Watson break; 85695fab37eSRobert Watson case MAC_CHECK_PIPE_RELABEL: 85795fab37eSRobert Watson mpc->mpc_ops->mpo_check_pipe_relabel = 85895fab37eSRobert Watson mpe->mpe_function; 85995fab37eSRobert Watson break; 860c024c3eeSRobert Watson case MAC_CHECK_PIPE_STAT: 861c024c3eeSRobert Watson mpc->mpc_ops->mpo_check_pipe_stat = 862c024c3eeSRobert Watson mpe->mpe_function; 863c024c3eeSRobert Watson break; 864c024c3eeSRobert Watson case MAC_CHECK_PIPE_WRITE: 865c024c3eeSRobert Watson mpc->mpc_ops->mpo_check_pipe_write = 866c024c3eeSRobert Watson mpe->mpe_function; 867c024c3eeSRobert Watson break; 86895fab37eSRobert Watson case MAC_CHECK_PROC_DEBUG: 86995fab37eSRobert Watson mpc->mpc_ops->mpo_check_proc_debug = 87095fab37eSRobert Watson mpe->mpe_function; 87195fab37eSRobert Watson break; 87295fab37eSRobert Watson case MAC_CHECK_PROC_SCHED: 87395fab37eSRobert Watson mpc->mpc_ops->mpo_check_proc_sched = 87495fab37eSRobert Watson mpe->mpe_function; 87595fab37eSRobert Watson break; 87695fab37eSRobert Watson case MAC_CHECK_PROC_SIGNAL: 87795fab37eSRobert Watson mpc->mpc_ops->mpo_check_proc_signal = 87895fab37eSRobert Watson mpe->mpe_function; 87995fab37eSRobert Watson break; 88095fab37eSRobert Watson case MAC_CHECK_SOCKET_BIND: 88195fab37eSRobert Watson mpc->mpc_ops->mpo_check_socket_bind = 88295fab37eSRobert Watson mpe->mpe_function; 88395fab37eSRobert Watson break; 88495fab37eSRobert Watson case MAC_CHECK_SOCKET_CONNECT: 88595fab37eSRobert Watson mpc->mpc_ops->mpo_check_socket_connect = 88695fab37eSRobert Watson mpe->mpe_function; 88795fab37eSRobert Watson break; 888d61198e4SRobert Watson case MAC_CHECK_SOCKET_DELIVER: 889d61198e4SRobert Watson mpc->mpc_ops->mpo_check_socket_deliver = 89095fab37eSRobert Watson mpe->mpe_function; 89195fab37eSRobert Watson break; 892d61198e4SRobert Watson case MAC_CHECK_SOCKET_LISTEN: 893d61198e4SRobert Watson mpc->mpc_ops->mpo_check_socket_listen = 89495fab37eSRobert Watson mpe->mpe_function; 89595fab37eSRobert Watson break; 896b371c939SRobert Watson case MAC_CHECK_SOCKET_RECEIVE: 897b371c939SRobert Watson mpc->mpc_ops->mpo_check_socket_receive = 898b371c939SRobert Watson mpe->mpe_function; 899b371c939SRobert Watson break; 90095fab37eSRobert Watson case MAC_CHECK_SOCKET_RELABEL: 90195fab37eSRobert Watson mpc->mpc_ops->mpo_check_socket_relabel = 90295fab37eSRobert Watson mpe->mpe_function; 90395fab37eSRobert Watson break; 904b371c939SRobert Watson case MAC_CHECK_SOCKET_SEND: 905b371c939SRobert Watson mpc->mpc_ops->mpo_check_socket_send = 906b371c939SRobert Watson mpe->mpe_function; 907b371c939SRobert Watson break; 90895fab37eSRobert Watson case MAC_CHECK_SOCKET_VISIBLE: 90995fab37eSRobert Watson mpc->mpc_ops->mpo_check_socket_visible = 91095fab37eSRobert Watson mpe->mpe_function; 91195fab37eSRobert Watson break; 912a2ecb9b7SRobert Watson case MAC_CHECK_SYSTEM_REBOOT: 913a2ecb9b7SRobert Watson mpc->mpc_ops->mpo_check_system_reboot = 914a2ecb9b7SRobert Watson mpe->mpe_function; 915a2ecb9b7SRobert Watson break; 91603ce2c0cSRobert Watson case MAC_CHECK_SYSTEM_SWAPON: 91703ce2c0cSRobert Watson mpc->mpc_ops->mpo_check_system_swapon = 91803ce2c0cSRobert Watson mpe->mpe_function; 91903ce2c0cSRobert Watson break; 920d3fc69eeSRobert Watson case MAC_CHECK_SYSTEM_SYSCTL: 921d3fc69eeSRobert Watson mpc->mpc_ops->mpo_check_system_sysctl = 922d3fc69eeSRobert Watson mpe->mpe_function; 923d3fc69eeSRobert Watson break; 92495fab37eSRobert Watson case MAC_CHECK_VNODE_ACCESS: 92595fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_access = 92695fab37eSRobert Watson mpe->mpe_function; 92795fab37eSRobert Watson break; 92895fab37eSRobert Watson case MAC_CHECK_VNODE_CHDIR: 92995fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_chdir = 93095fab37eSRobert Watson mpe->mpe_function; 93195fab37eSRobert Watson break; 93295fab37eSRobert Watson case MAC_CHECK_VNODE_CHROOT: 93395fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_chroot = 93495fab37eSRobert Watson mpe->mpe_function; 93595fab37eSRobert Watson break; 93695fab37eSRobert Watson case MAC_CHECK_VNODE_CREATE: 93795fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_create = 93895fab37eSRobert Watson mpe->mpe_function; 93995fab37eSRobert Watson break; 94095fab37eSRobert Watson case MAC_CHECK_VNODE_DELETE: 94195fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_delete = 94295fab37eSRobert Watson mpe->mpe_function; 94395fab37eSRobert Watson break; 94495fab37eSRobert Watson case MAC_CHECK_VNODE_DELETEACL: 94595fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_deleteacl = 94695fab37eSRobert Watson mpe->mpe_function; 94795fab37eSRobert Watson break; 94895fab37eSRobert Watson case MAC_CHECK_VNODE_EXEC: 94995fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_exec = 95095fab37eSRobert Watson mpe->mpe_function; 95195fab37eSRobert Watson break; 95295fab37eSRobert Watson case MAC_CHECK_VNODE_GETACL: 95395fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_getacl = 95495fab37eSRobert Watson mpe->mpe_function; 95595fab37eSRobert Watson break; 95695fab37eSRobert Watson case MAC_CHECK_VNODE_GETEXTATTR: 95795fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_getextattr = 95895fab37eSRobert Watson mpe->mpe_function; 95995fab37eSRobert Watson break; 9600a694196SRobert Watson case MAC_CHECK_VNODE_LINK: 9610a694196SRobert Watson mpc->mpc_ops->mpo_check_vnode_link = 9620a694196SRobert Watson mpe->mpe_function; 9630a694196SRobert Watson break; 96495fab37eSRobert Watson case MAC_CHECK_VNODE_LOOKUP: 96595fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_lookup = 96695fab37eSRobert Watson mpe->mpe_function; 96795fab37eSRobert Watson break; 968e183f80eSRobert Watson case MAC_CHECK_VNODE_MMAP: 969e183f80eSRobert Watson mpc->mpc_ops->mpo_check_vnode_mmap = 970e183f80eSRobert Watson mpe->mpe_function; 971e183f80eSRobert Watson break; 972e183f80eSRobert Watson case MAC_CHECK_VNODE_MMAP_DOWNGRADE: 973e183f80eSRobert Watson mpc->mpc_ops->mpo_check_vnode_mmap_downgrade = 974e183f80eSRobert Watson mpe->mpe_function; 975e183f80eSRobert Watson break; 976e183f80eSRobert Watson case MAC_CHECK_VNODE_MPROTECT: 977e183f80eSRobert Watson mpc->mpc_ops->mpo_check_vnode_mprotect = 97895fab37eSRobert Watson mpe->mpe_function; 97995fab37eSRobert Watson break; 98095fab37eSRobert Watson case MAC_CHECK_VNODE_OPEN: 98195fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_open = 98295fab37eSRobert Watson mpe->mpe_function; 98395fab37eSRobert Watson break; 9847f724f8bSRobert Watson case MAC_CHECK_VNODE_POLL: 9857f724f8bSRobert Watson mpc->mpc_ops->mpo_check_vnode_poll = 9867f724f8bSRobert Watson mpe->mpe_function; 9877f724f8bSRobert Watson break; 9887f724f8bSRobert Watson case MAC_CHECK_VNODE_READ: 9897f724f8bSRobert Watson mpc->mpc_ops->mpo_check_vnode_read = 9907f724f8bSRobert Watson mpe->mpe_function; 9917f724f8bSRobert Watson break; 99295fab37eSRobert Watson case MAC_CHECK_VNODE_READDIR: 99395fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_readdir = 99495fab37eSRobert Watson mpe->mpe_function; 99595fab37eSRobert Watson break; 99695fab37eSRobert Watson case MAC_CHECK_VNODE_READLINK: 99795fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_readlink = 99895fab37eSRobert Watson mpe->mpe_function; 99995fab37eSRobert Watson break; 100095fab37eSRobert Watson case MAC_CHECK_VNODE_RELABEL: 100195fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_relabel = 100295fab37eSRobert Watson mpe->mpe_function; 100395fab37eSRobert Watson break; 100495fab37eSRobert Watson case MAC_CHECK_VNODE_RENAME_FROM: 100595fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_rename_from = 100695fab37eSRobert Watson mpe->mpe_function; 100795fab37eSRobert Watson break; 100895fab37eSRobert Watson case MAC_CHECK_VNODE_RENAME_TO: 100995fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_rename_to = 101095fab37eSRobert Watson mpe->mpe_function; 101195fab37eSRobert Watson break; 101295fab37eSRobert Watson case MAC_CHECK_VNODE_REVOKE: 101395fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_revoke = 101495fab37eSRobert Watson mpe->mpe_function; 101595fab37eSRobert Watson break; 101695fab37eSRobert Watson case MAC_CHECK_VNODE_SETACL: 101795fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_setacl = 101895fab37eSRobert Watson mpe->mpe_function; 101995fab37eSRobert Watson break; 102095fab37eSRobert Watson case MAC_CHECK_VNODE_SETEXTATTR: 102195fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_setextattr = 102295fab37eSRobert Watson mpe->mpe_function; 102395fab37eSRobert Watson break; 102495fab37eSRobert Watson case MAC_CHECK_VNODE_SETFLAGS: 102595fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_setflags = 102695fab37eSRobert Watson mpe->mpe_function; 102795fab37eSRobert Watson break; 102895fab37eSRobert Watson case MAC_CHECK_VNODE_SETMODE: 102995fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_setmode = 103095fab37eSRobert Watson mpe->mpe_function; 103195fab37eSRobert Watson break; 103295fab37eSRobert Watson case MAC_CHECK_VNODE_SETOWNER: 103395fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_setowner = 103495fab37eSRobert Watson mpe->mpe_function; 103595fab37eSRobert Watson break; 103695fab37eSRobert Watson case MAC_CHECK_VNODE_SETUTIMES: 103795fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_setutimes = 103895fab37eSRobert Watson mpe->mpe_function; 103995fab37eSRobert Watson break; 104095fab37eSRobert Watson case MAC_CHECK_VNODE_STAT: 104195fab37eSRobert Watson mpc->mpc_ops->mpo_check_vnode_stat = 104295fab37eSRobert Watson mpe->mpe_function; 104395fab37eSRobert Watson break; 10447f724f8bSRobert Watson case MAC_CHECK_VNODE_WRITE: 10457f724f8bSRobert Watson mpc->mpc_ops->mpo_check_vnode_write = 10467f724f8bSRobert Watson mpe->mpe_function; 10477f724f8bSRobert Watson break; 104895fab37eSRobert Watson /* 104995fab37eSRobert Watson default: 105095fab37eSRobert Watson printf("MAC policy `%s': unknown operation %d\n", 105195fab37eSRobert Watson mpc->mpc_name, mpe->mpe_constant); 105295fab37eSRobert Watson return (EINVAL); 105395fab37eSRobert Watson */ 105495fab37eSRobert Watson } 105595fab37eSRobert Watson } 105695fab37eSRobert Watson MAC_POLICY_LIST_LOCK(); 105795fab37eSRobert Watson if (mac_policy_list_busy > 0) { 105895fab37eSRobert Watson MAC_POLICY_LIST_UNLOCK(); 105995fab37eSRobert Watson FREE(mpc->mpc_ops, M_MACOPVEC); 106095fab37eSRobert Watson mpc->mpc_ops = NULL; 106195fab37eSRobert Watson return (EBUSY); 106295fab37eSRobert Watson } 106395fab37eSRobert Watson LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 106495fab37eSRobert Watson if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 106595fab37eSRobert Watson MAC_POLICY_LIST_UNLOCK(); 106695fab37eSRobert Watson FREE(mpc->mpc_ops, M_MACOPVEC); 106795fab37eSRobert Watson mpc->mpc_ops = NULL; 106895fab37eSRobert Watson return (EEXIST); 106995fab37eSRobert Watson } 107095fab37eSRobert Watson } 107195fab37eSRobert Watson if (mpc->mpc_field_off != NULL) { 107295fab37eSRobert Watson slot = ffs(mac_policy_offsets_free); 107395fab37eSRobert Watson if (slot == 0) { 107495fab37eSRobert Watson MAC_POLICY_LIST_UNLOCK(); 107595fab37eSRobert Watson FREE(mpc->mpc_ops, M_MACOPVEC); 107695fab37eSRobert Watson mpc->mpc_ops = NULL; 107795fab37eSRobert Watson return (ENOMEM); 107895fab37eSRobert Watson } 107995fab37eSRobert Watson slot--; 108095fab37eSRobert Watson mac_policy_offsets_free &= ~(1 << slot); 108195fab37eSRobert Watson *mpc->mpc_field_off = slot; 108295fab37eSRobert Watson } 108395fab37eSRobert Watson mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; 108495fab37eSRobert Watson LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); 108595fab37eSRobert Watson 108695fab37eSRobert Watson /* Per-policy initialization. */ 108795fab37eSRobert Watson if (mpc->mpc_ops->mpo_init != NULL) 108895fab37eSRobert Watson (*(mpc->mpc_ops->mpo_init))(mpc); 108995fab37eSRobert Watson MAC_POLICY_LIST_UNLOCK(); 109095fab37eSRobert Watson 109195fab37eSRobert Watson printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, 109295fab37eSRobert Watson mpc->mpc_name); 109395fab37eSRobert Watson 109495fab37eSRobert Watson return (0); 109595fab37eSRobert Watson } 109695fab37eSRobert Watson 109795fab37eSRobert Watson static int 109895fab37eSRobert Watson mac_policy_unregister(struct mac_policy_conf *mpc) 109995fab37eSRobert Watson { 110095fab37eSRobert Watson 1101ea599aa0SRobert Watson /* 1102ea599aa0SRobert Watson * If we fail the load, we may get a request to unload. Check 1103ea599aa0SRobert Watson * to see if we did the run-time registration, and if not, 1104ea599aa0SRobert Watson * silently succeed. 1105ea599aa0SRobert Watson */ 1106ea599aa0SRobert Watson MAC_POLICY_LIST_LOCK(); 1107ea599aa0SRobert Watson if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) { 1108ea599aa0SRobert Watson MAC_POLICY_LIST_UNLOCK(); 1109ea599aa0SRobert Watson return (0); 1110ea599aa0SRobert Watson } 111195fab37eSRobert Watson #if 0 111295fab37eSRobert Watson /* 111395fab37eSRobert Watson * Don't allow unloading modules with private data. 111495fab37eSRobert Watson */ 1115ea599aa0SRobert Watson if (mpc->mpc_field_off != NULL) { 1116ea599aa0SRobert Watson MAC_POLICY_LIST_UNLOCK(); 111795fab37eSRobert Watson return (EBUSY); 1118ea599aa0SRobert Watson } 111995fab37eSRobert Watson #endif 1120ea599aa0SRobert Watson /* 1121ea599aa0SRobert Watson * Only allow the unload to proceed if the module is unloadable 1122ea599aa0SRobert Watson * by its own definition. 1123ea599aa0SRobert Watson */ 1124ea599aa0SRobert Watson if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) { 1125ea599aa0SRobert Watson MAC_POLICY_LIST_UNLOCK(); 112695fab37eSRobert Watson return (EBUSY); 1127ea599aa0SRobert Watson } 1128ea599aa0SRobert Watson /* 1129ea599aa0SRobert Watson * Right now, we EBUSY if the list is in use. In the future, 1130ea599aa0SRobert Watson * for reliability reasons, we might want to sleep and wakeup 1131ea599aa0SRobert Watson * later to try again. 1132ea599aa0SRobert Watson */ 113395fab37eSRobert Watson if (mac_policy_list_busy > 0) { 113495fab37eSRobert Watson MAC_POLICY_LIST_UNLOCK(); 113595fab37eSRobert Watson return (EBUSY); 113695fab37eSRobert Watson } 113795fab37eSRobert Watson if (mpc->mpc_ops->mpo_destroy != NULL) 113895fab37eSRobert Watson (*(mpc->mpc_ops->mpo_destroy))(mpc); 113995fab37eSRobert Watson 114095fab37eSRobert Watson LIST_REMOVE(mpc, mpc_list); 114195fab37eSRobert Watson MAC_POLICY_LIST_UNLOCK(); 114295fab37eSRobert Watson 114395fab37eSRobert Watson FREE(mpc->mpc_ops, M_MACOPVEC); 114495fab37eSRobert Watson mpc->mpc_ops = NULL; 11459aeffb2bSRobert Watson mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED; 114695fab37eSRobert Watson 114795fab37eSRobert Watson printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, 114895fab37eSRobert Watson mpc->mpc_name); 114995fab37eSRobert Watson 115095fab37eSRobert Watson return (0); 115195fab37eSRobert Watson } 115295fab37eSRobert Watson 115395fab37eSRobert Watson /* 115495fab37eSRobert Watson * Define an error value precedence, and given two arguments, selects the 115595fab37eSRobert Watson * value with the higher precedence. 115695fab37eSRobert Watson */ 115795fab37eSRobert Watson static int 115895fab37eSRobert Watson error_select(int error1, int error2) 115995fab37eSRobert Watson { 116095fab37eSRobert Watson 116195fab37eSRobert Watson /* Certain decision-making errors take top priority. */ 116295fab37eSRobert Watson if (error1 == EDEADLK || error2 == EDEADLK) 116395fab37eSRobert Watson return (EDEADLK); 116495fab37eSRobert Watson 116595fab37eSRobert Watson /* Invalid arguments should be reported where possible. */ 116695fab37eSRobert Watson if (error1 == EINVAL || error2 == EINVAL) 116795fab37eSRobert Watson return (EINVAL); 116895fab37eSRobert Watson 116995fab37eSRobert Watson /* Precedence goes to "visibility", with both process and file. */ 117095fab37eSRobert Watson if (error1 == ESRCH || error2 == ESRCH) 117195fab37eSRobert Watson return (ESRCH); 117295fab37eSRobert Watson 117395fab37eSRobert Watson if (error1 == ENOENT || error2 == ENOENT) 117495fab37eSRobert Watson return (ENOENT); 117595fab37eSRobert Watson 117695fab37eSRobert Watson /* Precedence goes to DAC/MAC protections. */ 117795fab37eSRobert Watson if (error1 == EACCES || error2 == EACCES) 117895fab37eSRobert Watson return (EACCES); 117995fab37eSRobert Watson 118095fab37eSRobert Watson /* Precedence goes to privilege. */ 118195fab37eSRobert Watson if (error1 == EPERM || error2 == EPERM) 118295fab37eSRobert Watson return (EPERM); 118395fab37eSRobert Watson 118495fab37eSRobert Watson /* Precedence goes to error over success; otherwise, arbitrary. */ 118595fab37eSRobert Watson if (error1 != 0) 118695fab37eSRobert Watson return (error1); 118795fab37eSRobert Watson return (error2); 118895fab37eSRobert Watson } 118995fab37eSRobert Watson 119008bcdc58SRobert Watson static void 119108bcdc58SRobert Watson mac_init_label(struct label *label) 119208bcdc58SRobert Watson { 119308bcdc58SRobert Watson 119408bcdc58SRobert Watson bzero(label, sizeof(*label)); 119508bcdc58SRobert Watson label->l_flags = MAC_FLAG_INITIALIZED; 119608bcdc58SRobert Watson } 119708bcdc58SRobert Watson 119808bcdc58SRobert Watson static void 119908bcdc58SRobert Watson mac_destroy_label(struct label *label) 120008bcdc58SRobert Watson { 120108bcdc58SRobert Watson 120208bcdc58SRobert Watson KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 120308bcdc58SRobert Watson ("destroying uninitialized label")); 120408bcdc58SRobert Watson 120508bcdc58SRobert Watson bzero(label, sizeof(*label)); 120608bcdc58SRobert Watson /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 120708bcdc58SRobert Watson } 120808bcdc58SRobert Watson 120908bcdc58SRobert Watson void 121087807196SRobert Watson mac_init_bpfdesc(struct bpf_d *bpf_d) 121108bcdc58SRobert Watson { 121208bcdc58SRobert Watson 121387807196SRobert Watson mac_init_label(&bpf_d->bd_label); 121487807196SRobert Watson MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label); 121508bcdc58SRobert Watson #ifdef MAC_DEBUG 121687807196SRobert Watson atomic_add_int(&nmacbpfdescs, 1); 121708bcdc58SRobert Watson #endif 121808bcdc58SRobert Watson } 121908bcdc58SRobert Watson 1220f7b951a8SRobert Watson static void 1221f7b951a8SRobert Watson mac_init_cred_label(struct label *label) 122208bcdc58SRobert Watson { 122308bcdc58SRobert Watson 1224f7b951a8SRobert Watson mac_init_label(label); 1225f7b951a8SRobert Watson MAC_PERFORM(init_cred_label, label); 122608bcdc58SRobert Watson #ifdef MAC_DEBUG 122708bcdc58SRobert Watson atomic_add_int(&nmaccreds, 1); 122808bcdc58SRobert Watson #endif 122908bcdc58SRobert Watson } 123008bcdc58SRobert Watson 123108bcdc58SRobert Watson void 1232f7b951a8SRobert Watson mac_init_cred(struct ucred *cred) 1233f7b951a8SRobert Watson { 1234f7b951a8SRobert Watson 1235f7b951a8SRobert Watson mac_init_cred_label(&cred->cr_label); 1236f7b951a8SRobert Watson } 1237f7b951a8SRobert Watson 1238f7b951a8SRobert Watson void 123987807196SRobert Watson mac_init_devfsdirent(struct devfs_dirent *de) 124008bcdc58SRobert Watson { 124108bcdc58SRobert Watson 124287807196SRobert Watson mac_init_label(&de->de_label); 124387807196SRobert Watson MAC_PERFORM(init_devfsdirent_label, &de->de_label); 124408bcdc58SRobert Watson #ifdef MAC_DEBUG 124587807196SRobert Watson atomic_add_int(&nmacdevfsdirents, 1); 124608bcdc58SRobert Watson #endif 124708bcdc58SRobert Watson } 124808bcdc58SRobert Watson 1249f7b951a8SRobert Watson static void 1250f7b951a8SRobert Watson mac_init_ifnet_label(struct label *label) 1251f7b951a8SRobert Watson { 1252f7b951a8SRobert Watson 1253f7b951a8SRobert Watson mac_init_label(label); 1254f7b951a8SRobert Watson MAC_PERFORM(init_ifnet_label, label); 1255f7b951a8SRobert Watson #ifdef MAC_DEBUG 1256f7b951a8SRobert Watson atomic_add_int(&nmacifnets, 1); 1257f7b951a8SRobert Watson #endif 1258f7b951a8SRobert Watson } 1259f7b951a8SRobert Watson 126008bcdc58SRobert Watson void 126108bcdc58SRobert Watson mac_init_ifnet(struct ifnet *ifp) 126208bcdc58SRobert Watson { 126308bcdc58SRobert Watson 1264f7b951a8SRobert Watson mac_init_ifnet_label(&ifp->if_label); 126508bcdc58SRobert Watson } 126608bcdc58SRobert Watson 126708bcdc58SRobert Watson void 126808bcdc58SRobert Watson mac_init_ipq(struct ipq *ipq) 126908bcdc58SRobert Watson { 127008bcdc58SRobert Watson 127108bcdc58SRobert Watson mac_init_label(&ipq->ipq_label); 127208bcdc58SRobert Watson MAC_PERFORM(init_ipq_label, &ipq->ipq_label); 127308bcdc58SRobert Watson #ifdef MAC_DEBUG 127408bcdc58SRobert Watson atomic_add_int(&nmacipqs, 1); 127508bcdc58SRobert Watson #endif 127608bcdc58SRobert Watson } 127708bcdc58SRobert Watson 127887807196SRobert Watson int 127987807196SRobert Watson mac_init_mbuf(struct mbuf *m, int flag) 128008bcdc58SRobert Watson { 128156c15412SRobert Watson int error; 128256c15412SRobert Watson 128387807196SRobert Watson KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf")); 128408bcdc58SRobert Watson 128587807196SRobert Watson mac_init_label(&m->m_pkthdr.label); 128687807196SRobert Watson 128756c15412SRobert Watson MAC_CHECK(init_mbuf_label, &m->m_pkthdr.label, flag); 128856c15412SRobert Watson if (error) { 128956c15412SRobert Watson MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 129056c15412SRobert Watson mac_destroy_label(&m->m_pkthdr.label); 129156c15412SRobert Watson } 129256c15412SRobert Watson 129308bcdc58SRobert Watson #ifdef MAC_DEBUG 129456c15412SRobert Watson if (error == 0) 129587807196SRobert Watson atomic_add_int(&nmacmbufs, 1); 129608bcdc58SRobert Watson #endif 129756c15412SRobert Watson return (error); 129808bcdc58SRobert Watson } 129908bcdc58SRobert Watson 130008bcdc58SRobert Watson void 130187807196SRobert Watson mac_init_mount(struct mount *mp) 130208bcdc58SRobert Watson { 130308bcdc58SRobert Watson 130487807196SRobert Watson mac_init_label(&mp->mnt_mntlabel); 130587807196SRobert Watson mac_init_label(&mp->mnt_fslabel); 130687807196SRobert Watson MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel); 130787807196SRobert Watson MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel); 130808bcdc58SRobert Watson #ifdef MAC_DEBUG 130987807196SRobert Watson atomic_add_int(&nmacmounts, 1); 131008bcdc58SRobert Watson #endif 131108bcdc58SRobert Watson } 131208bcdc58SRobert Watson 1313f7b951a8SRobert Watson static void 1314f7b951a8SRobert Watson mac_init_pipe_label(struct label *label) 1315f7b951a8SRobert Watson { 1316f7b951a8SRobert Watson 1317f7b951a8SRobert Watson mac_init_label(label); 1318f7b951a8SRobert Watson MAC_PERFORM(init_pipe_label, label); 1319f7b951a8SRobert Watson #ifdef MAC_DEBUG 1320f7b951a8SRobert Watson atomic_add_int(&nmacpipes, 1); 1321f7b951a8SRobert Watson #endif 1322f7b951a8SRobert Watson } 1323f7b951a8SRobert Watson 132408bcdc58SRobert Watson void 132508bcdc58SRobert Watson mac_init_pipe(struct pipe *pipe) 132608bcdc58SRobert Watson { 132708bcdc58SRobert Watson struct label *label; 132808bcdc58SRobert Watson 132908bcdc58SRobert Watson label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 133008bcdc58SRobert Watson pipe->pipe_label = label; 133108bcdc58SRobert Watson pipe->pipe_peer->pipe_label = label; 1332f7b951a8SRobert Watson mac_init_pipe_label(label); 133308bcdc58SRobert Watson } 133408bcdc58SRobert Watson 133583985c26SRobert Watson static int 133683985c26SRobert Watson mac_init_socket_label(struct label *label, int flag) 133708bcdc58SRobert Watson { 133883985c26SRobert Watson int error; 133908bcdc58SRobert Watson 134083985c26SRobert Watson mac_init_label(label); 134183985c26SRobert Watson 134283985c26SRobert Watson MAC_CHECK(init_socket_label, label, flag); 134383985c26SRobert Watson if (error) { 134483985c26SRobert Watson MAC_PERFORM(destroy_socket_label, label); 134583985c26SRobert Watson mac_destroy_label(label); 134683985c26SRobert Watson } 134783985c26SRobert Watson 134808bcdc58SRobert Watson #ifdef MAC_DEBUG 134983985c26SRobert Watson if (error == 0) 135087807196SRobert Watson atomic_add_int(&nmacsockets, 1); 135187807196SRobert Watson #endif 135283985c26SRobert Watson 135383985c26SRobert Watson return (error); 135483985c26SRobert Watson } 135583985c26SRobert Watson 135683985c26SRobert Watson static int 135783985c26SRobert Watson mac_init_socket_peer_label(struct label *label, int flag) 135883985c26SRobert Watson { 135983985c26SRobert Watson int error; 136083985c26SRobert Watson 136183985c26SRobert Watson mac_init_label(label); 136283985c26SRobert Watson 136383985c26SRobert Watson MAC_CHECK(init_socket_peer_label, label, flag); 136483985c26SRobert Watson if (error) { 136583985c26SRobert Watson MAC_PERFORM(destroy_socket_label, label); 136683985c26SRobert Watson mac_destroy_label(label); 136783985c26SRobert Watson } 136883985c26SRobert Watson 136983985c26SRobert Watson return (error); 137083985c26SRobert Watson } 137183985c26SRobert Watson 137283985c26SRobert Watson int 137383985c26SRobert Watson mac_init_socket(struct socket *socket, int flag) 137483985c26SRobert Watson { 137583985c26SRobert Watson int error; 137683985c26SRobert Watson 137783985c26SRobert Watson error = mac_init_socket_label(&socket->so_label, flag); 137883985c26SRobert Watson if (error) 137983985c26SRobert Watson return (error); 138083985c26SRobert Watson 138183985c26SRobert Watson error = mac_init_socket_peer_label(&socket->so_peerlabel, flag); 138283985c26SRobert Watson if (error) 138383985c26SRobert Watson mac_destroy_socket_label(&socket->so_label); 138483985c26SRobert Watson 138583985c26SRobert Watson return (error); 138687807196SRobert Watson } 138787807196SRobert Watson 1388763bbd2fSRobert Watson void 1389f7b951a8SRobert Watson mac_init_vnode_label(struct label *label) 139087807196SRobert Watson { 139187807196SRobert Watson 139287807196SRobert Watson mac_init_label(label); 1393f7b951a8SRobert Watson MAC_PERFORM(init_vnode_label, label); 139487807196SRobert Watson #ifdef MAC_DEBUG 1395f7b951a8SRobert Watson atomic_add_int(&nmacvnodes, 1); 139608bcdc58SRobert Watson #endif 139708bcdc58SRobert Watson } 139808bcdc58SRobert Watson 139908bcdc58SRobert Watson void 140087807196SRobert Watson mac_init_vnode(struct vnode *vp) 140108bcdc58SRobert Watson { 140208bcdc58SRobert Watson 1403f7b951a8SRobert Watson mac_init_vnode_label(&vp->v_label); 140408bcdc58SRobert Watson } 140508bcdc58SRobert Watson 140608bcdc58SRobert Watson void 140708bcdc58SRobert Watson mac_destroy_bpfdesc(struct bpf_d *bpf_d) 140808bcdc58SRobert Watson { 140908bcdc58SRobert Watson 141008bcdc58SRobert Watson MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label); 141108bcdc58SRobert Watson mac_destroy_label(&bpf_d->bd_label); 141208bcdc58SRobert Watson #ifdef MAC_DEBUG 141308bcdc58SRobert Watson atomic_subtract_int(&nmacbpfdescs, 1); 141408bcdc58SRobert Watson #endif 141508bcdc58SRobert Watson } 141608bcdc58SRobert Watson 1417f7b951a8SRobert Watson static void 1418f7b951a8SRobert Watson mac_destroy_cred_label(struct label *label) 141908bcdc58SRobert Watson { 142008bcdc58SRobert Watson 1421f7b951a8SRobert Watson MAC_PERFORM(destroy_cred_label, label); 1422f7b951a8SRobert Watson mac_destroy_label(label); 142308bcdc58SRobert Watson #ifdef MAC_DEBUG 142487807196SRobert Watson atomic_subtract_int(&nmaccreds, 1); 142587807196SRobert Watson #endif 142687807196SRobert Watson } 142787807196SRobert Watson 142887807196SRobert Watson void 1429f7b951a8SRobert Watson mac_destroy_cred(struct ucred *cred) 1430f7b951a8SRobert Watson { 1431f7b951a8SRobert Watson 1432f7b951a8SRobert Watson mac_destroy_cred_label(&cred->cr_label); 1433f7b951a8SRobert Watson } 1434f7b951a8SRobert Watson 1435f7b951a8SRobert Watson void 143687807196SRobert Watson mac_destroy_devfsdirent(struct devfs_dirent *de) 143787807196SRobert Watson { 143887807196SRobert Watson 143987807196SRobert Watson MAC_PERFORM(destroy_devfsdirent_label, &de->de_label); 144087807196SRobert Watson mac_destroy_label(&de->de_label); 144187807196SRobert Watson #ifdef MAC_DEBUG 144287807196SRobert Watson atomic_subtract_int(&nmacdevfsdirents, 1); 144387807196SRobert Watson #endif 144487807196SRobert Watson } 144587807196SRobert Watson 1446f7b951a8SRobert Watson static void 1447f7b951a8SRobert Watson mac_destroy_ifnet_label(struct label *label) 1448f7b951a8SRobert Watson { 1449f7b951a8SRobert Watson 1450f7b951a8SRobert Watson MAC_PERFORM(destroy_ifnet_label, label); 1451f7b951a8SRobert Watson mac_destroy_label(label); 1452f7b951a8SRobert Watson #ifdef MAC_DEBUG 1453f7b951a8SRobert Watson atomic_subtract_int(&nmacifnets, 1); 1454f7b951a8SRobert Watson #endif 1455f7b951a8SRobert Watson } 1456f7b951a8SRobert Watson 145787807196SRobert Watson void 145887807196SRobert Watson mac_destroy_ifnet(struct ifnet *ifp) 145987807196SRobert Watson { 146087807196SRobert Watson 1461f7b951a8SRobert Watson mac_destroy_ifnet_label(&ifp->if_label); 146287807196SRobert Watson } 146387807196SRobert Watson 146487807196SRobert Watson void 146587807196SRobert Watson mac_destroy_ipq(struct ipq *ipq) 146687807196SRobert Watson { 146787807196SRobert Watson 146887807196SRobert Watson MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 146987807196SRobert Watson mac_destroy_label(&ipq->ipq_label); 147087807196SRobert Watson #ifdef MAC_DEBUG 147187807196SRobert Watson atomic_subtract_int(&nmacipqs, 1); 147287807196SRobert Watson #endif 147387807196SRobert Watson } 147487807196SRobert Watson 147587807196SRobert Watson void 147687807196SRobert Watson mac_destroy_mbuf(struct mbuf *m) 147787807196SRobert Watson { 147887807196SRobert Watson 147987807196SRobert Watson MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 148087807196SRobert Watson mac_destroy_label(&m->m_pkthdr.label); 148187807196SRobert Watson #ifdef MAC_DEBUG 148287807196SRobert Watson atomic_subtract_int(&nmacmbufs, 1); 148308bcdc58SRobert Watson #endif 148408bcdc58SRobert Watson } 148508bcdc58SRobert Watson 148608bcdc58SRobert Watson void 148708bcdc58SRobert Watson mac_destroy_mount(struct mount *mp) 148808bcdc58SRobert Watson { 148908bcdc58SRobert Watson 149008bcdc58SRobert Watson MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel); 149108bcdc58SRobert Watson MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel); 149208bcdc58SRobert Watson mac_destroy_label(&mp->mnt_fslabel); 149308bcdc58SRobert Watson mac_destroy_label(&mp->mnt_mntlabel); 149408bcdc58SRobert Watson #ifdef MAC_DEBUG 149508bcdc58SRobert Watson atomic_subtract_int(&nmacmounts, 1); 149608bcdc58SRobert Watson #endif 149708bcdc58SRobert Watson } 149808bcdc58SRobert Watson 1499f7b951a8SRobert Watson static void 1500f7b951a8SRobert Watson mac_destroy_pipe_label(struct label *label) 1501f7b951a8SRobert Watson { 1502f7b951a8SRobert Watson 1503f7b951a8SRobert Watson MAC_PERFORM(destroy_pipe_label, label); 1504f7b951a8SRobert Watson mac_destroy_label(label); 1505f7b951a8SRobert Watson #ifdef MAC_DEBUG 1506f7b951a8SRobert Watson atomic_subtract_int(&nmacpipes, 1); 1507f7b951a8SRobert Watson #endif 1508f7b951a8SRobert Watson } 1509f7b951a8SRobert Watson 151087807196SRobert Watson void 151187807196SRobert Watson mac_destroy_pipe(struct pipe *pipe) 151208bcdc58SRobert Watson { 151308bcdc58SRobert Watson 1514f7b951a8SRobert Watson mac_destroy_pipe_label(pipe->pipe_label); 151587807196SRobert Watson free(pipe->pipe_label, M_MACPIPELABEL); 151687807196SRobert Watson } 151787807196SRobert Watson 151883985c26SRobert Watson static void 151983985c26SRobert Watson mac_destroy_socket_label(struct label *label) 152083985c26SRobert Watson { 152183985c26SRobert Watson 152283985c26SRobert Watson MAC_PERFORM(destroy_socket_label, label); 152383985c26SRobert Watson mac_destroy_label(label); 152483985c26SRobert Watson #ifdef MAC_DEBUG 152583985c26SRobert Watson atomic_subtract_int(&nmacsockets, 1); 152683985c26SRobert Watson #endif 152783985c26SRobert Watson } 152883985c26SRobert Watson 152983985c26SRobert Watson static void 153083985c26SRobert Watson mac_destroy_socket_peer_label(struct label *label) 153183985c26SRobert Watson { 153283985c26SRobert Watson 153383985c26SRobert Watson MAC_PERFORM(destroy_socket_peer_label, label); 153483985c26SRobert Watson mac_destroy_label(label); 153583985c26SRobert Watson } 153683985c26SRobert Watson 153787807196SRobert Watson void 153887807196SRobert Watson mac_destroy_socket(struct socket *socket) 153987807196SRobert Watson { 154087807196SRobert Watson 154183985c26SRobert Watson mac_destroy_socket_label(&socket->so_label); 154283985c26SRobert Watson mac_destroy_socket_peer_label(&socket->so_peerlabel); 154308bcdc58SRobert Watson } 154408bcdc58SRobert Watson 1545763bbd2fSRobert Watson void 1546f7b951a8SRobert Watson mac_destroy_vnode_label(struct label *label) 154708bcdc58SRobert Watson { 154808bcdc58SRobert Watson 1549f7b951a8SRobert Watson MAC_PERFORM(destroy_vnode_label, label); 155008bcdc58SRobert Watson mac_destroy_label(label); 155108bcdc58SRobert Watson #ifdef MAC_DEBUG 1552f7b951a8SRobert Watson atomic_subtract_int(&nmacvnodes, 1); 155308bcdc58SRobert Watson #endif 155408bcdc58SRobert Watson } 155508bcdc58SRobert Watson 155608bcdc58SRobert Watson void 155708bcdc58SRobert Watson mac_destroy_vnode(struct vnode *vp) 155808bcdc58SRobert Watson { 155908bcdc58SRobert Watson 1560f7b951a8SRobert Watson mac_destroy_vnode_label(&vp->v_label); 1561f7b951a8SRobert Watson } 1562f7b951a8SRobert Watson 1563f7b951a8SRobert Watson static void 1564f7b951a8SRobert Watson mac_copy_pipe_label(struct label *src, struct label *dest) 1565f7b951a8SRobert Watson { 1566f7b951a8SRobert Watson 1567f7b951a8SRobert Watson MAC_PERFORM(copy_pipe_label, src, dest); 1568f7b951a8SRobert Watson } 1569f7b951a8SRobert Watson 1570763bbd2fSRobert Watson void 1571f7b951a8SRobert Watson mac_copy_vnode_label(struct label *src, struct label *dest) 1572f7b951a8SRobert Watson { 1573f7b951a8SRobert Watson 1574f7b951a8SRobert Watson MAC_PERFORM(copy_vnode_label, src, dest); 157508bcdc58SRobert Watson } 157608bcdc58SRobert Watson 157769bbb5b1SRobert Watson static int 1578f7b951a8SRobert Watson mac_check_structmac_consistent(struct mac *mac) 1579f7b951a8SRobert Watson { 1580f7b951a8SRobert Watson 1581f7b951a8SRobert Watson if (mac->m_buflen > MAC_MAX_LABEL_BUF_LEN) 1582f7b951a8SRobert Watson return (EINVAL); 1583f7b951a8SRobert Watson 1584f7b951a8SRobert Watson return (0); 1585f7b951a8SRobert Watson } 1586f7b951a8SRobert Watson 1587f7b951a8SRobert Watson static int 1588f7b951a8SRobert Watson mac_externalize_cred_label(struct label *label, char *elements, 1589f7b951a8SRobert Watson char *outbuf, size_t outbuflen, int flags) 159069bbb5b1SRobert Watson { 159169bbb5b1SRobert Watson int error; 159269bbb5b1SRobert Watson 1593f7b951a8SRobert Watson MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen); 159469bbb5b1SRobert Watson 159569bbb5b1SRobert Watson return (error); 159669bbb5b1SRobert Watson } 159769bbb5b1SRobert Watson 159869bbb5b1SRobert Watson static int 1599f7b951a8SRobert Watson mac_externalize_ifnet_label(struct label *label, char *elements, 1600f7b951a8SRobert Watson char *outbuf, size_t outbuflen, int flags) 160169bbb5b1SRobert Watson { 160269bbb5b1SRobert Watson int error; 160369bbb5b1SRobert Watson 1604f7b951a8SRobert Watson MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen); 1605f7b951a8SRobert Watson 1606f7b951a8SRobert Watson return (error); 1607f7b951a8SRobert Watson } 1608f7b951a8SRobert Watson 1609f7b951a8SRobert Watson static int 1610f7b951a8SRobert Watson mac_externalize_pipe_label(struct label *label, char *elements, 1611f7b951a8SRobert Watson char *outbuf, size_t outbuflen, int flags) 1612f7b951a8SRobert Watson { 1613f7b951a8SRobert Watson int error; 1614f7b951a8SRobert Watson 1615f7b951a8SRobert Watson MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen); 1616f7b951a8SRobert Watson 1617f7b951a8SRobert Watson return (error); 1618f7b951a8SRobert Watson } 1619f7b951a8SRobert Watson 1620f7b951a8SRobert Watson static int 1621f7b951a8SRobert Watson mac_externalize_socket_label(struct label *label, char *elements, 1622f7b951a8SRobert Watson char *outbuf, size_t outbuflen, int flags) 1623f7b951a8SRobert Watson { 1624f7b951a8SRobert Watson int error; 1625f7b951a8SRobert Watson 1626f7b951a8SRobert Watson MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen); 1627f7b951a8SRobert Watson 1628f7b951a8SRobert Watson return (error); 1629f7b951a8SRobert Watson } 1630f7b951a8SRobert Watson 1631f7b951a8SRobert Watson static int 1632f7b951a8SRobert Watson mac_externalize_socket_peer_label(struct label *label, char *elements, 1633f7b951a8SRobert Watson char *outbuf, size_t outbuflen, int flags) 1634f7b951a8SRobert Watson { 1635f7b951a8SRobert Watson int error; 1636f7b951a8SRobert Watson 1637f7b951a8SRobert Watson MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen); 1638f7b951a8SRobert Watson 1639f7b951a8SRobert Watson return (error); 1640f7b951a8SRobert Watson } 1641f7b951a8SRobert Watson 1642f7b951a8SRobert Watson static int 1643f7b951a8SRobert Watson mac_externalize_vnode_label(struct label *label, char *elements, 1644f7b951a8SRobert Watson char *outbuf, size_t outbuflen, int flags) 1645f7b951a8SRobert Watson { 1646f7b951a8SRobert Watson int error; 1647f7b951a8SRobert Watson 1648f7b951a8SRobert Watson MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen); 1649f7b951a8SRobert Watson 1650f7b951a8SRobert Watson return (error); 1651f7b951a8SRobert Watson } 1652f7b951a8SRobert Watson 1653f7b951a8SRobert Watson static int 1654f7b951a8SRobert Watson mac_internalize_cred_label(struct label *label, char *string) 1655f7b951a8SRobert Watson { 1656f7b951a8SRobert Watson int error; 1657f7b951a8SRobert Watson 1658f7b951a8SRobert Watson MAC_INTERNALIZE(cred_label, label, string); 1659f7b951a8SRobert Watson 1660f7b951a8SRobert Watson return (error); 1661f7b951a8SRobert Watson } 1662f7b951a8SRobert Watson 1663f7b951a8SRobert Watson static int 1664f7b951a8SRobert Watson mac_internalize_ifnet_label(struct label *label, char *string) 1665f7b951a8SRobert Watson { 1666f7b951a8SRobert Watson int error; 1667f7b951a8SRobert Watson 1668f7b951a8SRobert Watson MAC_INTERNALIZE(ifnet_label, label, string); 1669f7b951a8SRobert Watson 1670f7b951a8SRobert Watson return (error); 1671f7b951a8SRobert Watson } 1672f7b951a8SRobert Watson 1673f7b951a8SRobert Watson static int 1674f7b951a8SRobert Watson mac_internalize_pipe_label(struct label *label, char *string) 1675f7b951a8SRobert Watson { 1676f7b951a8SRobert Watson int error; 1677f7b951a8SRobert Watson 1678f7b951a8SRobert Watson MAC_INTERNALIZE(pipe_label, label, string); 1679f7b951a8SRobert Watson 1680f7b951a8SRobert Watson return (error); 1681f7b951a8SRobert Watson } 1682f7b951a8SRobert Watson 1683f7b951a8SRobert Watson static int 1684f7b951a8SRobert Watson mac_internalize_socket_label(struct label *label, char *string) 1685f7b951a8SRobert Watson { 1686f7b951a8SRobert Watson int error; 1687f7b951a8SRobert Watson 1688f7b951a8SRobert Watson MAC_INTERNALIZE(socket_label, label, string); 1689f7b951a8SRobert Watson 1690f7b951a8SRobert Watson return (error); 1691f7b951a8SRobert Watson } 1692f7b951a8SRobert Watson 1693f7b951a8SRobert Watson static int 1694f7b951a8SRobert Watson mac_internalize_vnode_label(struct label *label, char *string) 1695f7b951a8SRobert Watson { 1696f7b951a8SRobert Watson int error; 1697f7b951a8SRobert Watson 1698f7b951a8SRobert Watson MAC_INTERNALIZE(vnode_label, label, string); 169969bbb5b1SRobert Watson 170069bbb5b1SRobert Watson return (error); 170169bbb5b1SRobert Watson } 170269bbb5b1SRobert Watson 170369bbb5b1SRobert Watson /* 170469bbb5b1SRobert Watson * Initialize MAC label for the first kernel process, from which other 170569bbb5b1SRobert Watson * kernel processes and threads are spawned. 170669bbb5b1SRobert Watson */ 170769bbb5b1SRobert Watson void 170869bbb5b1SRobert Watson mac_create_proc0(struct ucred *cred) 170969bbb5b1SRobert Watson { 171069bbb5b1SRobert Watson 171169bbb5b1SRobert Watson MAC_PERFORM(create_proc0, cred); 171269bbb5b1SRobert Watson } 171369bbb5b1SRobert Watson 171469bbb5b1SRobert Watson /* 171569bbb5b1SRobert Watson * Initialize MAC label for the first userland process, from which other 171669bbb5b1SRobert Watson * userland processes and threads are spawned. 171769bbb5b1SRobert Watson */ 171869bbb5b1SRobert Watson void 171969bbb5b1SRobert Watson mac_create_proc1(struct ucred *cred) 172069bbb5b1SRobert Watson { 172169bbb5b1SRobert Watson 172269bbb5b1SRobert Watson MAC_PERFORM(create_proc1, cred); 172369bbb5b1SRobert Watson } 172469bbb5b1SRobert Watson 172569bbb5b1SRobert Watson void 172669bbb5b1SRobert Watson mac_thread_userret(struct thread *td) 172769bbb5b1SRobert Watson { 172869bbb5b1SRobert Watson 172969bbb5b1SRobert Watson MAC_PERFORM(thread_userret, td); 173069bbb5b1SRobert Watson } 173169bbb5b1SRobert Watson 173269bbb5b1SRobert Watson /* 173369bbb5b1SRobert Watson * When a new process is created, its label must be initialized. Generally, 173469bbb5b1SRobert Watson * this involves inheritence from the parent process, modulo possible 173569bbb5b1SRobert Watson * deltas. This function allows that processing to take place. 173669bbb5b1SRobert Watson */ 173769bbb5b1SRobert Watson void 173869bbb5b1SRobert Watson mac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 173969bbb5b1SRobert Watson { 174069bbb5b1SRobert Watson 174169bbb5b1SRobert Watson MAC_PERFORM(create_cred, parent_cred, child_cred); 174269bbb5b1SRobert Watson } 174369bbb5b1SRobert Watson 174495fab37eSRobert Watson void 174595fab37eSRobert Watson mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp) 174695fab37eSRobert Watson { 174795fab37eSRobert Watson 174895fab37eSRobert Watson MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label); 174995fab37eSRobert Watson } 175095fab37eSRobert Watson 175195fab37eSRobert Watson void 1752763bbd2fSRobert Watson mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, 1753763bbd2fSRobert Watson struct vnode *vp) 175495fab37eSRobert Watson { 175595fab37eSRobert Watson 1756763bbd2fSRobert Watson MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de, 1757763bbd2fSRobert Watson &de->de_label, vp, &vp->v_label); 175895fab37eSRobert Watson } 175995fab37eSRobert Watson 1760763bbd2fSRobert Watson int 1761763bbd2fSRobert Watson mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp) 176295fab37eSRobert Watson { 176395fab37eSRobert Watson int error; 176495fab37eSRobert Watson 1765763bbd2fSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr"); 1766763bbd2fSRobert Watson 1767763bbd2fSRobert Watson MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp, 1768763bbd2fSRobert Watson &vp->v_label); 176995fab37eSRobert Watson 177095fab37eSRobert Watson return (error); 177195fab37eSRobert Watson } 177295fab37eSRobert Watson 177395fab37eSRobert Watson void 1774763bbd2fSRobert Watson mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp) 177595fab37eSRobert Watson { 177695fab37eSRobert Watson 1777763bbd2fSRobert Watson MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp, 1778763bbd2fSRobert Watson &vp->v_label); 177995fab37eSRobert Watson } 178095fab37eSRobert Watson 178195fab37eSRobert Watson int 1782763bbd2fSRobert Watson mac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1783763bbd2fSRobert Watson struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 178495fab37eSRobert Watson { 1785763bbd2fSRobert Watson int error; 178695fab37eSRobert Watson 1787763bbd2fSRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr"); 1788763bbd2fSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr"); 178995fab37eSRobert Watson 1790763bbd2fSRobert Watson error = VOP_OPENEXTATTR(vp, cred, curthread); 1791763bbd2fSRobert Watson if (error == EOPNOTSUPP) { 1792763bbd2fSRobert Watson /* XXX: Optionally abort if transactions not supported. */ 1793763bbd2fSRobert Watson if (ea_warn_once == 0) { 1794763bbd2fSRobert Watson printf("Warning: transactions not supported " 1795763bbd2fSRobert Watson "in EA write.\n"); 1796763bbd2fSRobert Watson ea_warn_once = 1; 1797763bbd2fSRobert Watson } 1798763bbd2fSRobert Watson } else if (error) 179995fab37eSRobert Watson return (error); 180095fab37eSRobert Watson 1801763bbd2fSRobert Watson MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel, 1802763bbd2fSRobert Watson dvp, &dvp->v_label, vp, &vp->v_label, cnp); 180395fab37eSRobert Watson 1804763bbd2fSRobert Watson if (error) { 1805763bbd2fSRobert Watson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 180695fab37eSRobert Watson return (error); 180795fab37eSRobert Watson } 180895fab37eSRobert Watson 1809763bbd2fSRobert Watson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 181095fab37eSRobert Watson 1811763bbd2fSRobert Watson if (error == EOPNOTSUPP) 1812763bbd2fSRobert Watson error = 0; /* XXX */ 181395fab37eSRobert Watson 181495fab37eSRobert Watson return (error); 181595fab37eSRobert Watson } 181695fab37eSRobert Watson 181795fab37eSRobert Watson static int 1818763bbd2fSRobert Watson mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1819763bbd2fSRobert Watson struct label *intlabel) 182095fab37eSRobert Watson { 182195fab37eSRobert Watson int error; 182295fab37eSRobert Watson 1823763bbd2fSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr"); 182495fab37eSRobert Watson 1825763bbd2fSRobert Watson error = VOP_OPENEXTATTR(vp, cred, curthread); 1826763bbd2fSRobert Watson if (error == EOPNOTSUPP) { 1827763bbd2fSRobert Watson /* XXX: Optionally abort if transactions not supported. */ 1828763bbd2fSRobert Watson if (ea_warn_once == 0) { 1829763bbd2fSRobert Watson printf("Warning: transactions not supported " 1830763bbd2fSRobert Watson "in EA write.\n"); 1831763bbd2fSRobert Watson ea_warn_once = 1; 183295fab37eSRobert Watson } 1833763bbd2fSRobert Watson } else if (error) 183495fab37eSRobert Watson return (error); 183595fab37eSRobert Watson 1836763bbd2fSRobert Watson MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel); 183795fab37eSRobert Watson 1838763bbd2fSRobert Watson if (error) { 1839763bbd2fSRobert Watson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 184095fab37eSRobert Watson return (error); 184195fab37eSRobert Watson } 184295fab37eSRobert Watson 1843763bbd2fSRobert Watson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1844763bbd2fSRobert Watson 1845763bbd2fSRobert Watson if (error == EOPNOTSUPP) 1846763bbd2fSRobert Watson error = 0; /* XXX */ 1847763bbd2fSRobert Watson 1848763bbd2fSRobert Watson return (error); 184995fab37eSRobert Watson } 185095fab37eSRobert Watson 185195fab37eSRobert Watson void 185295fab37eSRobert Watson mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp) 185395fab37eSRobert Watson { 185495fab37eSRobert Watson 185595fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 185695fab37eSRobert Watson 185795fab37eSRobert Watson MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label); 185895fab37eSRobert Watson } 185995fab37eSRobert Watson 186095fab37eSRobert Watson int 186195fab37eSRobert Watson mac_execve_will_transition(struct ucred *old, struct vnode *vp) 186295fab37eSRobert Watson { 1863763bbd2fSRobert Watson int result; 186495fab37eSRobert Watson 186595fab37eSRobert Watson result = 0; 186695fab37eSRobert Watson MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label); 186795fab37eSRobert Watson 186895fab37eSRobert Watson return (result); 186995fab37eSRobert Watson } 187095fab37eSRobert Watson 187195fab37eSRobert Watson int 187295fab37eSRobert Watson mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags) 187395fab37eSRobert Watson { 187495fab37eSRobert Watson int error; 187595fab37eSRobert Watson 187695fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 187795fab37eSRobert Watson 187895fab37eSRobert Watson if (!mac_enforce_fs) 187995fab37eSRobert Watson return (0); 188095fab37eSRobert Watson 188195fab37eSRobert Watson MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags); 188295fab37eSRobert Watson return (error); 188395fab37eSRobert Watson } 188495fab37eSRobert Watson 188595fab37eSRobert Watson int 188695fab37eSRobert Watson mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 188795fab37eSRobert Watson { 188895fab37eSRobert Watson int error; 188995fab37eSRobert Watson 189095fab37eSRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 189195fab37eSRobert Watson 189295fab37eSRobert Watson if (!mac_enforce_fs) 189395fab37eSRobert Watson return (0); 189495fab37eSRobert Watson 189595fab37eSRobert Watson MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 189695fab37eSRobert Watson return (error); 189795fab37eSRobert Watson } 189895fab37eSRobert Watson 189995fab37eSRobert Watson int 190095fab37eSRobert Watson mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 190195fab37eSRobert Watson { 190295fab37eSRobert Watson int error; 190395fab37eSRobert Watson 190495fab37eSRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 190595fab37eSRobert Watson 190695fab37eSRobert Watson if (!mac_enforce_fs) 190795fab37eSRobert Watson return (0); 190895fab37eSRobert Watson 190995fab37eSRobert Watson MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 191095fab37eSRobert Watson return (error); 191195fab37eSRobert Watson } 191295fab37eSRobert Watson 191395fab37eSRobert Watson int 191495fab37eSRobert Watson mac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 191595fab37eSRobert Watson struct componentname *cnp, struct vattr *vap) 191695fab37eSRobert Watson { 191795fab37eSRobert Watson int error; 191895fab37eSRobert Watson 191995fab37eSRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 192095fab37eSRobert Watson 192195fab37eSRobert Watson if (!mac_enforce_fs) 192295fab37eSRobert Watson return (0); 192395fab37eSRobert Watson 192495fab37eSRobert Watson MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 192595fab37eSRobert Watson return (error); 192695fab37eSRobert Watson } 192795fab37eSRobert Watson 192895fab37eSRobert Watson int 192995fab37eSRobert Watson mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 193095fab37eSRobert Watson struct componentname *cnp) 193195fab37eSRobert Watson { 193295fab37eSRobert Watson int error; 193395fab37eSRobert Watson 193495fab37eSRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 193595fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 193695fab37eSRobert Watson 193795fab37eSRobert Watson if (!mac_enforce_fs) 193895fab37eSRobert Watson return (0); 193995fab37eSRobert Watson 194095fab37eSRobert Watson MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 194195fab37eSRobert Watson &vp->v_label, cnp); 194295fab37eSRobert Watson return (error); 194395fab37eSRobert Watson } 194495fab37eSRobert Watson 194595fab37eSRobert Watson int 194695fab37eSRobert Watson mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 194795fab37eSRobert Watson acl_type_t type) 194895fab37eSRobert Watson { 194995fab37eSRobert Watson int error; 195095fab37eSRobert Watson 195195fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 195295fab37eSRobert Watson 195395fab37eSRobert Watson if (!mac_enforce_fs) 195495fab37eSRobert Watson return (0); 195595fab37eSRobert Watson 195695fab37eSRobert Watson MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 195795fab37eSRobert Watson return (error); 195895fab37eSRobert Watson } 195995fab37eSRobert Watson 196095fab37eSRobert Watson int 196195fab37eSRobert Watson mac_check_vnode_exec(struct ucred *cred, struct vnode *vp) 196295fab37eSRobert Watson { 196395fab37eSRobert Watson int error; 196495fab37eSRobert Watson 1965851704bbSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1966851704bbSRobert Watson 196795fab37eSRobert Watson if (!mac_enforce_process && !mac_enforce_fs) 196895fab37eSRobert Watson return (0); 196995fab37eSRobert Watson 197095fab37eSRobert Watson MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label); 197195fab37eSRobert Watson 197295fab37eSRobert Watson return (error); 197395fab37eSRobert Watson } 197495fab37eSRobert Watson 197595fab37eSRobert Watson int 197695fab37eSRobert Watson mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 197795fab37eSRobert Watson { 197895fab37eSRobert Watson int error; 197995fab37eSRobert Watson 198095fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 198195fab37eSRobert Watson 198295fab37eSRobert Watson if (!mac_enforce_fs) 198395fab37eSRobert Watson return (0); 198495fab37eSRobert Watson 198595fab37eSRobert Watson MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 198695fab37eSRobert Watson return (error); 198795fab37eSRobert Watson } 198895fab37eSRobert Watson 198995fab37eSRobert Watson int 199095fab37eSRobert Watson mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 199195fab37eSRobert Watson int attrnamespace, const char *name, struct uio *uio) 199295fab37eSRobert Watson { 199395fab37eSRobert Watson int error; 199495fab37eSRobert Watson 199595fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 199695fab37eSRobert Watson 199795fab37eSRobert Watson if (!mac_enforce_fs) 199895fab37eSRobert Watson return (0); 199995fab37eSRobert Watson 200095fab37eSRobert Watson MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 200195fab37eSRobert Watson attrnamespace, name, uio); 200295fab37eSRobert Watson return (error); 200395fab37eSRobert Watson } 200495fab37eSRobert Watson 200595fab37eSRobert Watson int 20060a694196SRobert Watson mac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 20070a694196SRobert Watson struct vnode *vp, struct componentname *cnp) 20080a694196SRobert Watson { 20090a694196SRobert Watson int error; 20100a694196SRobert Watson 20110a694196SRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link"); 20120a694196SRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link"); 20130a694196SRobert Watson 20140a694196SRobert Watson if (!mac_enforce_fs) 20150a694196SRobert Watson return (0); 20160a694196SRobert Watson 20170a694196SRobert Watson MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp, 20180a694196SRobert Watson &vp->v_label, cnp); 20190a694196SRobert Watson return (error); 20200a694196SRobert Watson } 20210a694196SRobert Watson 20220a694196SRobert Watson int 202395fab37eSRobert Watson mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 202495fab37eSRobert Watson struct componentname *cnp) 202595fab37eSRobert Watson { 202695fab37eSRobert Watson int error; 202795fab37eSRobert Watson 202895fab37eSRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 202995fab37eSRobert Watson 203095fab37eSRobert Watson if (!mac_enforce_fs) 203195fab37eSRobert Watson return (0); 203295fab37eSRobert Watson 203395fab37eSRobert Watson MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 203495fab37eSRobert Watson return (error); 203595fab37eSRobert Watson } 203695fab37eSRobert Watson 2037e183f80eSRobert Watson int 2038e183f80eSRobert Watson mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) 203995fab37eSRobert Watson { 2040e183f80eSRobert Watson int error; 204195fab37eSRobert Watson 2042e183f80eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); 2043ca7850c3SRobert Watson 2044e183f80eSRobert Watson if (!mac_enforce_fs || !mac_enforce_vm) 2045e183f80eSRobert Watson return (0); 2046e183f80eSRobert Watson 2047e183f80eSRobert Watson MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); 2048e183f80eSRobert Watson return (error); 2049e183f80eSRobert Watson } 2050e183f80eSRobert Watson 2051e183f80eSRobert Watson void 2052e183f80eSRobert Watson mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) 2053e183f80eSRobert Watson { 2054e183f80eSRobert Watson int result = *prot; 2055e183f80eSRobert Watson 2056e183f80eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); 2057e183f80eSRobert Watson 2058e183f80eSRobert Watson if (!mac_enforce_fs || !mac_enforce_vm) 2059e183f80eSRobert Watson return; 2060e183f80eSRobert Watson 2061e183f80eSRobert Watson MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, 2062e183f80eSRobert Watson &result); 2063e183f80eSRobert Watson 2064e183f80eSRobert Watson *prot = result; 2065e183f80eSRobert Watson } 2066e183f80eSRobert Watson 2067e183f80eSRobert Watson int 2068e183f80eSRobert Watson mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) 2069e183f80eSRobert Watson { 2070e183f80eSRobert Watson int error; 2071e183f80eSRobert Watson 2072e183f80eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); 2073e183f80eSRobert Watson 2074e183f80eSRobert Watson if (!mac_enforce_fs || !mac_enforce_vm) 2075e183f80eSRobert Watson return (0); 2076e183f80eSRobert Watson 2077e183f80eSRobert Watson MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); 2078e183f80eSRobert Watson return (error); 207995fab37eSRobert Watson } 208095fab37eSRobert Watson 208195fab37eSRobert Watson int 208295fab37eSRobert Watson mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode) 208395fab37eSRobert Watson { 208495fab37eSRobert Watson int error; 208595fab37eSRobert Watson 208695fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 208795fab37eSRobert Watson 208895fab37eSRobert Watson if (!mac_enforce_fs) 208995fab37eSRobert Watson return (0); 209095fab37eSRobert Watson 209195fab37eSRobert Watson MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 209295fab37eSRobert Watson return (error); 209395fab37eSRobert Watson } 209495fab37eSRobert Watson 209595fab37eSRobert Watson int 2096177142e4SRobert Watson mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2097177142e4SRobert Watson struct vnode *vp) 20987f724f8bSRobert Watson { 20997f724f8bSRobert Watson int error; 21007f724f8bSRobert Watson 21017f724f8bSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 21027f724f8bSRobert Watson 21037f724f8bSRobert Watson if (!mac_enforce_fs) 21047f724f8bSRobert Watson return (0); 21057f724f8bSRobert Watson 2106177142e4SRobert Watson MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 2107177142e4SRobert Watson &vp->v_label); 21087f724f8bSRobert Watson 21097f724f8bSRobert Watson return (error); 21107f724f8bSRobert Watson } 21117f724f8bSRobert Watson 21127f724f8bSRobert Watson int 2113177142e4SRobert Watson mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2114177142e4SRobert Watson struct vnode *vp) 21157f724f8bSRobert Watson { 21167f724f8bSRobert Watson int error; 21177f724f8bSRobert Watson 21187f724f8bSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 21197f724f8bSRobert Watson 21207f724f8bSRobert Watson if (!mac_enforce_fs) 21217f724f8bSRobert Watson return (0); 21227f724f8bSRobert Watson 2123177142e4SRobert Watson MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 2124177142e4SRobert Watson &vp->v_label); 21257f724f8bSRobert Watson 21267f724f8bSRobert Watson return (error); 21277f724f8bSRobert Watson } 21287f724f8bSRobert Watson 21297f724f8bSRobert Watson int 213095fab37eSRobert Watson mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 213195fab37eSRobert Watson { 213295fab37eSRobert Watson int error; 213395fab37eSRobert Watson 213495fab37eSRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 213595fab37eSRobert Watson 213695fab37eSRobert Watson if (!mac_enforce_fs) 213795fab37eSRobert Watson return (0); 213895fab37eSRobert Watson 213995fab37eSRobert Watson MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 214095fab37eSRobert Watson return (error); 214195fab37eSRobert Watson } 214295fab37eSRobert Watson 214395fab37eSRobert Watson int 214495fab37eSRobert Watson mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 214595fab37eSRobert Watson { 214695fab37eSRobert Watson int error; 214795fab37eSRobert Watson 214895fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 214995fab37eSRobert Watson 215095fab37eSRobert Watson if (!mac_enforce_fs) 215195fab37eSRobert Watson return (0); 215295fab37eSRobert Watson 215395fab37eSRobert Watson MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 215495fab37eSRobert Watson return (error); 215595fab37eSRobert Watson } 215695fab37eSRobert Watson 215795fab37eSRobert Watson static int 215895fab37eSRobert Watson mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 215995fab37eSRobert Watson struct label *newlabel) 216095fab37eSRobert Watson { 216195fab37eSRobert Watson int error; 216295fab37eSRobert Watson 216395fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 216495fab37eSRobert Watson 216595fab37eSRobert Watson MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 216695fab37eSRobert Watson 216795fab37eSRobert Watson return (error); 216895fab37eSRobert Watson } 216995fab37eSRobert Watson 217095fab37eSRobert Watson int 217195fab37eSRobert Watson mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 217295fab37eSRobert Watson struct vnode *vp, struct componentname *cnp) 217395fab37eSRobert Watson { 217495fab37eSRobert Watson int error; 217595fab37eSRobert Watson 217695fab37eSRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 217795fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 217895fab37eSRobert Watson 217995fab37eSRobert Watson if (!mac_enforce_fs) 218095fab37eSRobert Watson return (0); 218195fab37eSRobert Watson 218295fab37eSRobert Watson MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 218395fab37eSRobert Watson &vp->v_label, cnp); 218495fab37eSRobert Watson return (error); 218595fab37eSRobert Watson } 218695fab37eSRobert Watson 218795fab37eSRobert Watson int 218895fab37eSRobert Watson mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 218995fab37eSRobert Watson struct vnode *vp, int samedir, struct componentname *cnp) 219095fab37eSRobert Watson { 219195fab37eSRobert Watson int error; 219295fab37eSRobert Watson 219395fab37eSRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 219495fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 219595fab37eSRobert Watson 219695fab37eSRobert Watson if (!mac_enforce_fs) 219795fab37eSRobert Watson return (0); 219895fab37eSRobert Watson 219995fab37eSRobert Watson MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 220095fab37eSRobert Watson vp != NULL ? &vp->v_label : NULL, samedir, cnp); 220195fab37eSRobert Watson return (error); 220295fab37eSRobert Watson } 220395fab37eSRobert Watson 220495fab37eSRobert Watson int 220595fab37eSRobert Watson mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 220695fab37eSRobert Watson { 220795fab37eSRobert Watson int error; 220895fab37eSRobert Watson 220995fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 221095fab37eSRobert Watson 221195fab37eSRobert Watson if (!mac_enforce_fs) 221295fab37eSRobert Watson return (0); 221395fab37eSRobert Watson 221495fab37eSRobert Watson MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 221595fab37eSRobert Watson return (error); 221695fab37eSRobert Watson } 221795fab37eSRobert Watson 221895fab37eSRobert Watson int 221995fab37eSRobert Watson mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 222095fab37eSRobert Watson struct acl *acl) 222195fab37eSRobert Watson { 222295fab37eSRobert Watson int error; 222395fab37eSRobert Watson 222495fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 222595fab37eSRobert Watson 222695fab37eSRobert Watson if (!mac_enforce_fs) 222795fab37eSRobert Watson return (0); 222895fab37eSRobert Watson 222995fab37eSRobert Watson MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 223095fab37eSRobert Watson return (error); 223195fab37eSRobert Watson } 223295fab37eSRobert Watson 223395fab37eSRobert Watson int 223495fab37eSRobert Watson mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 223595fab37eSRobert Watson int attrnamespace, const char *name, struct uio *uio) 223695fab37eSRobert Watson { 223795fab37eSRobert Watson int error; 223895fab37eSRobert Watson 223995fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 224095fab37eSRobert Watson 224195fab37eSRobert Watson if (!mac_enforce_fs) 224295fab37eSRobert Watson return (0); 224395fab37eSRobert Watson 224495fab37eSRobert Watson MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 224595fab37eSRobert Watson attrnamespace, name, uio); 224695fab37eSRobert Watson return (error); 224795fab37eSRobert Watson } 224895fab37eSRobert Watson 224995fab37eSRobert Watson int 225095fab37eSRobert Watson mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 225195fab37eSRobert Watson { 225295fab37eSRobert Watson int error; 225395fab37eSRobert Watson 225495fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 225595fab37eSRobert Watson 225695fab37eSRobert Watson if (!mac_enforce_fs) 225795fab37eSRobert Watson return (0); 225895fab37eSRobert Watson 225995fab37eSRobert Watson MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 226095fab37eSRobert Watson return (error); 226195fab37eSRobert Watson } 226295fab37eSRobert Watson 226395fab37eSRobert Watson int 226495fab37eSRobert Watson mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 226595fab37eSRobert Watson { 226695fab37eSRobert Watson int error; 226795fab37eSRobert Watson 226895fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 226995fab37eSRobert Watson 227095fab37eSRobert Watson if (!mac_enforce_fs) 227195fab37eSRobert Watson return (0); 227295fab37eSRobert Watson 227395fab37eSRobert Watson MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 227495fab37eSRobert Watson return (error); 227595fab37eSRobert Watson } 227695fab37eSRobert Watson 227795fab37eSRobert Watson int 227895fab37eSRobert Watson mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 227995fab37eSRobert Watson gid_t gid) 228095fab37eSRobert Watson { 228195fab37eSRobert Watson int error; 228295fab37eSRobert Watson 228395fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 228495fab37eSRobert Watson 228595fab37eSRobert Watson if (!mac_enforce_fs) 228695fab37eSRobert Watson return (0); 228795fab37eSRobert Watson 228895fab37eSRobert Watson MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 228995fab37eSRobert Watson return (error); 229095fab37eSRobert Watson } 229195fab37eSRobert Watson 229295fab37eSRobert Watson int 229395fab37eSRobert Watson mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 229495fab37eSRobert Watson struct timespec atime, struct timespec mtime) 229595fab37eSRobert Watson { 229695fab37eSRobert Watson int error; 229795fab37eSRobert Watson 229895fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 229995fab37eSRobert Watson 230095fab37eSRobert Watson if (!mac_enforce_fs) 230195fab37eSRobert Watson return (0); 230295fab37eSRobert Watson 230395fab37eSRobert Watson MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 230495fab37eSRobert Watson mtime); 230595fab37eSRobert Watson return (error); 230695fab37eSRobert Watson } 230795fab37eSRobert Watson 230895fab37eSRobert Watson int 2309177142e4SRobert Watson mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2310177142e4SRobert Watson struct vnode *vp) 231195fab37eSRobert Watson { 231295fab37eSRobert Watson int error; 231395fab37eSRobert Watson 231495fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 231595fab37eSRobert Watson 231695fab37eSRobert Watson if (!mac_enforce_fs) 231795fab37eSRobert Watson return (0); 231895fab37eSRobert Watson 2319177142e4SRobert Watson MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 2320177142e4SRobert Watson &vp->v_label); 232195fab37eSRobert Watson return (error); 232295fab37eSRobert Watson } 232395fab37eSRobert Watson 23247f724f8bSRobert Watson int 2325177142e4SRobert Watson mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 2326177142e4SRobert Watson struct vnode *vp) 23277f724f8bSRobert Watson { 23287f724f8bSRobert Watson int error; 23297f724f8bSRobert Watson 23307f724f8bSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 23317f724f8bSRobert Watson 23327f724f8bSRobert Watson if (!mac_enforce_fs) 23337f724f8bSRobert Watson return (0); 23347f724f8bSRobert Watson 2335177142e4SRobert Watson MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 2336177142e4SRobert Watson &vp->v_label); 23377f724f8bSRobert Watson 23387f724f8bSRobert Watson return (error); 23397f724f8bSRobert Watson } 23407f724f8bSRobert Watson 234195fab37eSRobert Watson /* 234295fab37eSRobert Watson * When relabeling a process, call out to the policies for the maximum 234395fab37eSRobert Watson * permission allowed for each object type we know about in its 234495fab37eSRobert Watson * memory space, and revoke access (in the least surprising ways we 234595fab37eSRobert Watson * know) when necessary. The process lock is not held here. 234695fab37eSRobert Watson */ 234795fab37eSRobert Watson static void 234895fab37eSRobert Watson mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 234995fab37eSRobert Watson { 235095fab37eSRobert Watson 235195fab37eSRobert Watson /* XXX freeze all other threads */ 235295fab37eSRobert Watson mac_cred_mmapped_drop_perms_recurse(td, cred, 235395fab37eSRobert Watson &td->td_proc->p_vmspace->vm_map); 235495fab37eSRobert Watson /* XXX allow other threads to continue */ 235595fab37eSRobert Watson } 235695fab37eSRobert Watson 235795fab37eSRobert Watson static __inline const char * 235895fab37eSRobert Watson prot2str(vm_prot_t prot) 235995fab37eSRobert Watson { 236095fab37eSRobert Watson 236195fab37eSRobert Watson switch (prot & VM_PROT_ALL) { 236295fab37eSRobert Watson case VM_PROT_READ: 236395fab37eSRobert Watson return ("r--"); 236495fab37eSRobert Watson case VM_PROT_READ | VM_PROT_WRITE: 236595fab37eSRobert Watson return ("rw-"); 236695fab37eSRobert Watson case VM_PROT_READ | VM_PROT_EXECUTE: 236795fab37eSRobert Watson return ("r-x"); 236895fab37eSRobert Watson case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 236995fab37eSRobert Watson return ("rwx"); 237095fab37eSRobert Watson case VM_PROT_WRITE: 237195fab37eSRobert Watson return ("-w-"); 237295fab37eSRobert Watson case VM_PROT_EXECUTE: 237395fab37eSRobert Watson return ("--x"); 237495fab37eSRobert Watson case VM_PROT_WRITE | VM_PROT_EXECUTE: 237595fab37eSRobert Watson return ("-wx"); 237695fab37eSRobert Watson default: 237795fab37eSRobert Watson return ("---"); 237895fab37eSRobert Watson } 237995fab37eSRobert Watson } 238095fab37eSRobert Watson 238195fab37eSRobert Watson static void 238295fab37eSRobert Watson mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 238395fab37eSRobert Watson struct vm_map *map) 238495fab37eSRobert Watson { 238595fab37eSRobert Watson struct vm_map_entry *vme; 2386e183f80eSRobert Watson int result; 2387e183f80eSRobert Watson vm_prot_t revokeperms; 238895fab37eSRobert Watson vm_object_t object; 238995fab37eSRobert Watson vm_ooffset_t offset; 239095fab37eSRobert Watson struct vnode *vp; 239195fab37eSRobert Watson 2392c0f39905SRobert Watson if (!mac_mmap_revocation) 2393c0f39905SRobert Watson return; 2394c0f39905SRobert Watson 239595fab37eSRobert Watson vm_map_lock_read(map); 239695fab37eSRobert Watson for (vme = map->header.next; vme != &map->header; vme = vme->next) { 239795fab37eSRobert Watson if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 239895fab37eSRobert Watson mac_cred_mmapped_drop_perms_recurse(td, cred, 239995fab37eSRobert Watson vme->object.sub_map); 240095fab37eSRobert Watson continue; 240195fab37eSRobert Watson } 240295fab37eSRobert Watson /* 240395fab37eSRobert Watson * Skip over entries that obviously are not shared. 240495fab37eSRobert Watson */ 240595fab37eSRobert Watson if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 240695fab37eSRobert Watson !vme->max_protection) 240795fab37eSRobert Watson continue; 240895fab37eSRobert Watson /* 240995fab37eSRobert Watson * Drill down to the deepest backing object. 241095fab37eSRobert Watson */ 241195fab37eSRobert Watson offset = vme->offset; 241295fab37eSRobert Watson object = vme->object.vm_object; 241395fab37eSRobert Watson if (object == NULL) 241495fab37eSRobert Watson continue; 241595fab37eSRobert Watson while (object->backing_object != NULL) { 241695fab37eSRobert Watson object = object->backing_object; 241795fab37eSRobert Watson offset += object->backing_object_offset; 241895fab37eSRobert Watson } 241995fab37eSRobert Watson /* 242095fab37eSRobert Watson * At the moment, vm_maps and objects aren't considered 242195fab37eSRobert Watson * by the MAC system, so only things with backing by a 242295fab37eSRobert Watson * normal object (read: vnodes) are checked. 242395fab37eSRobert Watson */ 242495fab37eSRobert Watson if (object->type != OBJT_VNODE) 242595fab37eSRobert Watson continue; 242695fab37eSRobert Watson vp = (struct vnode *)object->handle; 242795fab37eSRobert Watson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2428e183f80eSRobert Watson result = vme->max_protection; 2429e183f80eSRobert Watson mac_check_vnode_mmap_downgrade(cred, vp, &result); 243095fab37eSRobert Watson VOP_UNLOCK(vp, 0, td); 243195fab37eSRobert Watson /* 243295fab37eSRobert Watson * Find out what maximum protection we may be allowing 243395fab37eSRobert Watson * now but a policy needs to get removed. 243495fab37eSRobert Watson */ 243595fab37eSRobert Watson revokeperms = vme->max_protection & ~result; 243695fab37eSRobert Watson if (!revokeperms) 243795fab37eSRobert Watson continue; 2438b656366bSBruce Evans printf("pid %ld: revoking %s perms from %#lx:%ld " 2439b656366bSBruce Evans "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 2440b656366bSBruce Evans prot2str(revokeperms), (u_long)vme->start, 2441b656366bSBruce Evans (long)(vme->end - vme->start), 244295fab37eSRobert Watson prot2str(vme->max_protection), prot2str(vme->protection)); 244395fab37eSRobert Watson vm_map_lock_upgrade(map); 244495fab37eSRobert Watson /* 244595fab37eSRobert Watson * This is the really simple case: if a map has more 244695fab37eSRobert Watson * max_protection than is allowed, but it's not being 244795fab37eSRobert Watson * actually used (that is, the current protection is 244895fab37eSRobert Watson * still allowed), we can just wipe it out and do 244995fab37eSRobert Watson * nothing more. 245095fab37eSRobert Watson */ 245195fab37eSRobert Watson if ((vme->protection & revokeperms) == 0) { 245295fab37eSRobert Watson vme->max_protection -= revokeperms; 245395fab37eSRobert Watson } else { 245495fab37eSRobert Watson if (revokeperms & VM_PROT_WRITE) { 245595fab37eSRobert Watson /* 245695fab37eSRobert Watson * In the more complicated case, flush out all 245795fab37eSRobert Watson * pending changes to the object then turn it 245895fab37eSRobert Watson * copy-on-write. 245995fab37eSRobert Watson */ 246095fab37eSRobert Watson vm_object_reference(object); 246195fab37eSRobert Watson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 246295fab37eSRobert Watson vm_object_page_clean(object, 246395fab37eSRobert Watson OFF_TO_IDX(offset), 246495fab37eSRobert Watson OFF_TO_IDX(offset + vme->end - vme->start + 246595fab37eSRobert Watson PAGE_MASK), 246695fab37eSRobert Watson OBJPC_SYNC); 246795fab37eSRobert Watson VOP_UNLOCK(vp, 0, td); 246895fab37eSRobert Watson vm_object_deallocate(object); 246995fab37eSRobert Watson /* 247095fab37eSRobert Watson * Why bother if there's no read permissions 247195fab37eSRobert Watson * anymore? For the rest, we need to leave 247295fab37eSRobert Watson * the write permissions on for COW, or 247395fab37eSRobert Watson * remove them entirely if configured to. 247495fab37eSRobert Watson */ 247595fab37eSRobert Watson if (!mac_mmap_revocation_via_cow) { 247695fab37eSRobert Watson vme->max_protection &= ~VM_PROT_WRITE; 247795fab37eSRobert Watson vme->protection &= ~VM_PROT_WRITE; 247895fab37eSRobert Watson } if ((revokeperms & VM_PROT_READ) == 0) 247995fab37eSRobert Watson vme->eflags |= MAP_ENTRY_COW | 248095fab37eSRobert Watson MAP_ENTRY_NEEDS_COPY; 248195fab37eSRobert Watson } 248295fab37eSRobert Watson if (revokeperms & VM_PROT_EXECUTE) { 248395fab37eSRobert Watson vme->max_protection &= ~VM_PROT_EXECUTE; 248495fab37eSRobert Watson vme->protection &= ~VM_PROT_EXECUTE; 248595fab37eSRobert Watson } 248695fab37eSRobert Watson if (revokeperms & VM_PROT_READ) { 248795fab37eSRobert Watson vme->max_protection = 0; 248895fab37eSRobert Watson vme->protection = 0; 248995fab37eSRobert Watson } 249095fab37eSRobert Watson pmap_protect(map->pmap, vme->start, vme->end, 249195fab37eSRobert Watson vme->protection & ~revokeperms); 249295fab37eSRobert Watson vm_map_simplify_entry(map, vme); 249395fab37eSRobert Watson } 249495fab37eSRobert Watson vm_map_lock_downgrade(map); 249595fab37eSRobert Watson } 249695fab37eSRobert Watson vm_map_unlock_read(map); 249795fab37eSRobert Watson } 249895fab37eSRobert Watson 249995fab37eSRobert Watson /* 250095fab37eSRobert Watson * When the subject's label changes, it may require revocation of privilege 250195fab37eSRobert Watson * to mapped objects. This can't be done on-the-fly later with a unified 250295fab37eSRobert Watson * buffer cache. 250395fab37eSRobert Watson */ 250495fab37eSRobert Watson static void 250595fab37eSRobert Watson mac_relabel_cred(struct ucred *cred, struct label *newlabel) 250695fab37eSRobert Watson { 250795fab37eSRobert Watson 250895fab37eSRobert Watson MAC_PERFORM(relabel_cred, cred, newlabel); 250995fab37eSRobert Watson } 251095fab37eSRobert Watson 251195fab37eSRobert Watson void 251295fab37eSRobert Watson mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 251395fab37eSRobert Watson { 251495fab37eSRobert Watson 251595fab37eSRobert Watson MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 251695fab37eSRobert Watson } 251795fab37eSRobert Watson 251895fab37eSRobert Watson void 251995fab37eSRobert Watson mac_create_ifnet(struct ifnet *ifnet) 252095fab37eSRobert Watson { 252195fab37eSRobert Watson 252295fab37eSRobert Watson MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 252395fab37eSRobert Watson } 252495fab37eSRobert Watson 252595fab37eSRobert Watson void 252695fab37eSRobert Watson mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 252795fab37eSRobert Watson { 252895fab37eSRobert Watson 252995fab37eSRobert Watson MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 253095fab37eSRobert Watson } 253195fab37eSRobert Watson 253295fab37eSRobert Watson void 253395fab37eSRobert Watson mac_create_socket(struct ucred *cred, struct socket *socket) 253495fab37eSRobert Watson { 253595fab37eSRobert Watson 253695fab37eSRobert Watson MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 253795fab37eSRobert Watson } 253895fab37eSRobert Watson 253995fab37eSRobert Watson void 254095fab37eSRobert Watson mac_create_pipe(struct ucred *cred, struct pipe *pipe) 254195fab37eSRobert Watson { 254295fab37eSRobert Watson 254395fab37eSRobert Watson MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 254495fab37eSRobert Watson } 254595fab37eSRobert Watson 254695fab37eSRobert Watson void 254795fab37eSRobert Watson mac_create_socket_from_socket(struct socket *oldsocket, 254895fab37eSRobert Watson struct socket *newsocket) 254995fab37eSRobert Watson { 255095fab37eSRobert Watson 255195fab37eSRobert Watson MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 255295fab37eSRobert Watson newsocket, &newsocket->so_label); 255395fab37eSRobert Watson } 255495fab37eSRobert Watson 255595fab37eSRobert Watson static void 255695fab37eSRobert Watson mac_relabel_socket(struct ucred *cred, struct socket *socket, 255795fab37eSRobert Watson struct label *newlabel) 255895fab37eSRobert Watson { 255995fab37eSRobert Watson 256095fab37eSRobert Watson MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 256195fab37eSRobert Watson } 256295fab37eSRobert Watson 256395fab37eSRobert Watson static void 256495fab37eSRobert Watson mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 256595fab37eSRobert Watson { 256695fab37eSRobert Watson 256795fab37eSRobert Watson MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 256895fab37eSRobert Watson } 256995fab37eSRobert Watson 257095fab37eSRobert Watson void 257195fab37eSRobert Watson mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 257295fab37eSRobert Watson { 257395fab37eSRobert Watson 257495fab37eSRobert Watson MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label, 257595fab37eSRobert Watson socket, &socket->so_peerlabel); 257695fab37eSRobert Watson } 257795fab37eSRobert Watson 257895fab37eSRobert Watson void 257995fab37eSRobert Watson mac_set_socket_peer_from_socket(struct socket *oldsocket, 258095fab37eSRobert Watson struct socket *newsocket) 258195fab37eSRobert Watson { 258295fab37eSRobert Watson 258395fab37eSRobert Watson MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 258495fab37eSRobert Watson &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 258595fab37eSRobert Watson } 258695fab37eSRobert Watson 258795fab37eSRobert Watson void 258895fab37eSRobert Watson mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 258995fab37eSRobert Watson { 259095fab37eSRobert Watson 259195fab37eSRobert Watson MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 259295fab37eSRobert Watson datagram, &datagram->m_pkthdr.label); 259395fab37eSRobert Watson } 259495fab37eSRobert Watson 259595fab37eSRobert Watson void 259695fab37eSRobert Watson mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 259795fab37eSRobert Watson { 259895fab37eSRobert Watson 259995fab37eSRobert Watson MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label, 260095fab37eSRobert Watson fragment, &fragment->m_pkthdr.label); 260195fab37eSRobert Watson } 260295fab37eSRobert Watson 260395fab37eSRobert Watson void 260495fab37eSRobert Watson mac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 260595fab37eSRobert Watson { 260695fab37eSRobert Watson 260795fab37eSRobert Watson MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq, 260895fab37eSRobert Watson &ipq->ipq_label); 260995fab37eSRobert Watson } 261095fab37eSRobert Watson 261195fab37eSRobert Watson void 261295fab37eSRobert Watson mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 261395fab37eSRobert Watson { 261495fab37eSRobert Watson 261595fab37eSRobert Watson MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label, 261695fab37eSRobert Watson newmbuf, &newmbuf->m_pkthdr.label); 261795fab37eSRobert Watson } 261895fab37eSRobert Watson 261995fab37eSRobert Watson void 262095fab37eSRobert Watson mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 262195fab37eSRobert Watson { 262295fab37eSRobert Watson 262395fab37eSRobert Watson MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 262495fab37eSRobert Watson &mbuf->m_pkthdr.label); 262595fab37eSRobert Watson } 262695fab37eSRobert Watson 262795fab37eSRobert Watson void 262895fab37eSRobert Watson mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 262995fab37eSRobert Watson { 263095fab37eSRobert Watson 263195fab37eSRobert Watson MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 263295fab37eSRobert Watson &mbuf->m_pkthdr.label); 263395fab37eSRobert Watson } 263495fab37eSRobert Watson 263595fab37eSRobert Watson void 263695fab37eSRobert Watson mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 263795fab37eSRobert Watson { 263895fab37eSRobert Watson 263995fab37eSRobert Watson MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 264095fab37eSRobert Watson &mbuf->m_pkthdr.label); 264195fab37eSRobert Watson } 264295fab37eSRobert Watson 264395fab37eSRobert Watson void 264495fab37eSRobert Watson mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 264595fab37eSRobert Watson struct mbuf *newmbuf) 264695fab37eSRobert Watson { 264795fab37eSRobert Watson 264895fab37eSRobert Watson MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, 264995fab37eSRobert Watson &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf, 265095fab37eSRobert Watson &newmbuf->m_pkthdr.label); 265195fab37eSRobert Watson } 265295fab37eSRobert Watson 265395fab37eSRobert Watson void 265495fab37eSRobert Watson mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 265595fab37eSRobert Watson { 265695fab37eSRobert Watson 265795fab37eSRobert Watson MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label, 265895fab37eSRobert Watson newmbuf, &newmbuf->m_pkthdr.label); 265995fab37eSRobert Watson } 266095fab37eSRobert Watson 266195fab37eSRobert Watson int 266295fab37eSRobert Watson mac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 266395fab37eSRobert Watson { 266495fab37eSRobert Watson int result; 266595fab37eSRobert Watson 266695fab37eSRobert Watson result = 1; 266795fab37eSRobert Watson MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label, 266895fab37eSRobert Watson ipq, &ipq->ipq_label); 266995fab37eSRobert Watson 267095fab37eSRobert Watson return (result); 267195fab37eSRobert Watson } 267295fab37eSRobert Watson 267395fab37eSRobert Watson void 267495fab37eSRobert Watson mac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 267595fab37eSRobert Watson { 267695fab37eSRobert Watson 267795fab37eSRobert Watson MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq, 267895fab37eSRobert Watson &ipq->ipq_label); 267995fab37eSRobert Watson } 268095fab37eSRobert Watson 268195fab37eSRobert Watson void 268295fab37eSRobert Watson mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 268395fab37eSRobert Watson { 268495fab37eSRobert Watson 268595fab37eSRobert Watson MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 268695fab37eSRobert Watson &mbuf->m_pkthdr.label); 268795fab37eSRobert Watson } 268895fab37eSRobert Watson 268995fab37eSRobert Watson void 269095fab37eSRobert Watson mac_create_mount(struct ucred *cred, struct mount *mp) 269195fab37eSRobert Watson { 269295fab37eSRobert Watson 269395fab37eSRobert Watson MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 269495fab37eSRobert Watson &mp->mnt_fslabel); 269595fab37eSRobert Watson } 269695fab37eSRobert Watson 269795fab37eSRobert Watson void 269895fab37eSRobert Watson mac_create_root_mount(struct ucred *cred, struct mount *mp) 269995fab37eSRobert Watson { 270095fab37eSRobert Watson 270195fab37eSRobert Watson MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 270295fab37eSRobert Watson &mp->mnt_fslabel); 270395fab37eSRobert Watson } 270495fab37eSRobert Watson 270595fab37eSRobert Watson int 270695fab37eSRobert Watson mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 270795fab37eSRobert Watson { 270895fab37eSRobert Watson int error; 270995fab37eSRobert Watson 271095fab37eSRobert Watson if (!mac_enforce_network) 271195fab37eSRobert Watson return (0); 271295fab37eSRobert Watson 271395fab37eSRobert Watson MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 271495fab37eSRobert Watson &ifnet->if_label); 271595fab37eSRobert Watson 271695fab37eSRobert Watson return (error); 271795fab37eSRobert Watson } 271895fab37eSRobert Watson 271995fab37eSRobert Watson static int 272095fab37eSRobert Watson mac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 272195fab37eSRobert Watson { 272295fab37eSRobert Watson int error; 272395fab37eSRobert Watson 272495fab37eSRobert Watson MAC_CHECK(check_cred_relabel, cred, newlabel); 272595fab37eSRobert Watson 272695fab37eSRobert Watson return (error); 272795fab37eSRobert Watson } 272895fab37eSRobert Watson 272995fab37eSRobert Watson int 273095fab37eSRobert Watson mac_check_cred_visible(struct ucred *u1, struct ucred *u2) 273195fab37eSRobert Watson { 273295fab37eSRobert Watson int error; 273395fab37eSRobert Watson 273495fab37eSRobert Watson if (!mac_enforce_process) 273595fab37eSRobert Watson return (0); 273695fab37eSRobert Watson 273795fab37eSRobert Watson MAC_CHECK(check_cred_visible, u1, u2); 273895fab37eSRobert Watson 273995fab37eSRobert Watson return (error); 274095fab37eSRobert Watson } 274195fab37eSRobert Watson 274295fab37eSRobert Watson int 274395fab37eSRobert Watson mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 274495fab37eSRobert Watson { 274595fab37eSRobert Watson int error; 274695fab37eSRobert Watson 274795fab37eSRobert Watson if (!mac_enforce_network) 274895fab37eSRobert Watson return (0); 274995fab37eSRobert Watson 275095fab37eSRobert Watson KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr")); 275195fab37eSRobert Watson if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED)) 275229e1b85fSBrooks Davis if_printf(ifnet, "not initialized\n"); 275395fab37eSRobert Watson 275495fab37eSRobert Watson MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 275595fab37eSRobert Watson &mbuf->m_pkthdr.label); 275695fab37eSRobert Watson 275795fab37eSRobert Watson return (error); 275895fab37eSRobert Watson } 275995fab37eSRobert Watson 276095fab37eSRobert Watson int 276195fab37eSRobert Watson mac_check_mount_stat(struct ucred *cred, struct mount *mount) 276295fab37eSRobert Watson { 276395fab37eSRobert Watson int error; 276495fab37eSRobert Watson 276595fab37eSRobert Watson if (!mac_enforce_fs) 276695fab37eSRobert Watson return (0); 276795fab37eSRobert Watson 276895fab37eSRobert Watson MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 276995fab37eSRobert Watson 277095fab37eSRobert Watson return (error); 277195fab37eSRobert Watson } 277295fab37eSRobert Watson 277395fab37eSRobert Watson int 277495fab37eSRobert Watson mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 277595fab37eSRobert Watson void *data) 277695fab37eSRobert Watson { 277795fab37eSRobert Watson int error; 277895fab37eSRobert Watson 27791aa37f53SRobert Watson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 27801aa37f53SRobert Watson 27811aa37f53SRobert Watson if (!mac_enforce_pipe) 27821aa37f53SRobert Watson return (0); 27831aa37f53SRobert Watson 278495fab37eSRobert Watson MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 278595fab37eSRobert Watson 278695fab37eSRobert Watson return (error); 278795fab37eSRobert Watson } 278895fab37eSRobert Watson 278995fab37eSRobert Watson int 2790c024c3eeSRobert Watson mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 279195fab37eSRobert Watson { 279295fab37eSRobert Watson int error; 279395fab37eSRobert Watson 27941aa37f53SRobert Watson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 27951aa37f53SRobert Watson 27961aa37f53SRobert Watson if (!mac_enforce_pipe) 27971aa37f53SRobert Watson return (0); 27981aa37f53SRobert Watson 2799c024c3eeSRobert Watson MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2800c024c3eeSRobert Watson 2801c024c3eeSRobert Watson return (error); 2802c024c3eeSRobert Watson } 2803c024c3eeSRobert Watson 2804c024c3eeSRobert Watson int 2805c024c3eeSRobert Watson mac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2806c024c3eeSRobert Watson { 2807c024c3eeSRobert Watson int error; 2808c024c3eeSRobert Watson 28091aa37f53SRobert Watson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 28101aa37f53SRobert Watson 28111aa37f53SRobert Watson if (!mac_enforce_pipe) 28121aa37f53SRobert Watson return (0); 28131aa37f53SRobert Watson 2814c024c3eeSRobert Watson MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 281595fab37eSRobert Watson 281695fab37eSRobert Watson return (error); 281795fab37eSRobert Watson } 281895fab37eSRobert Watson 281995fab37eSRobert Watson static int 282095fab37eSRobert Watson mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 282195fab37eSRobert Watson struct label *newlabel) 282295fab37eSRobert Watson { 282395fab37eSRobert Watson int error; 282495fab37eSRobert Watson 28251aa37f53SRobert Watson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 28261aa37f53SRobert Watson 28271aa37f53SRobert Watson if (!mac_enforce_pipe) 28281aa37f53SRobert Watson return (0); 28291aa37f53SRobert Watson 283095fab37eSRobert Watson MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 283195fab37eSRobert Watson 283295fab37eSRobert Watson return (error); 283395fab37eSRobert Watson } 283495fab37eSRobert Watson 283595fab37eSRobert Watson int 2836c024c3eeSRobert Watson mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2837c024c3eeSRobert Watson { 2838c024c3eeSRobert Watson int error; 2839c024c3eeSRobert Watson 28401aa37f53SRobert Watson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 28411aa37f53SRobert Watson 28421aa37f53SRobert Watson if (!mac_enforce_pipe) 28431aa37f53SRobert Watson return (0); 28441aa37f53SRobert Watson 2845c024c3eeSRobert Watson MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2846c024c3eeSRobert Watson 2847c024c3eeSRobert Watson return (error); 2848c024c3eeSRobert Watson } 2849c024c3eeSRobert Watson 2850c024c3eeSRobert Watson int 2851c024c3eeSRobert Watson mac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2852c024c3eeSRobert Watson { 2853c024c3eeSRobert Watson int error; 2854c024c3eeSRobert Watson 28551aa37f53SRobert Watson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 28561aa37f53SRobert Watson 28571aa37f53SRobert Watson if (!mac_enforce_pipe) 28581aa37f53SRobert Watson return (0); 28591aa37f53SRobert Watson 2860c024c3eeSRobert Watson MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2861c024c3eeSRobert Watson 2862c024c3eeSRobert Watson return (error); 2863c024c3eeSRobert Watson } 2864c024c3eeSRobert Watson 2865c024c3eeSRobert Watson int 286695fab37eSRobert Watson mac_check_proc_debug(struct ucred *cred, struct proc *proc) 286795fab37eSRobert Watson { 286895fab37eSRobert Watson int error; 286995fab37eSRobert Watson 2870b12baf55SRobert Watson PROC_LOCK_ASSERT(proc, MA_OWNED); 2871b12baf55SRobert Watson 287295fab37eSRobert Watson if (!mac_enforce_process) 287395fab37eSRobert Watson return (0); 287495fab37eSRobert Watson 287595fab37eSRobert Watson MAC_CHECK(check_proc_debug, cred, proc); 287695fab37eSRobert Watson 287795fab37eSRobert Watson return (error); 287895fab37eSRobert Watson } 287995fab37eSRobert Watson 288095fab37eSRobert Watson int 288195fab37eSRobert Watson mac_check_proc_sched(struct ucred *cred, struct proc *proc) 288295fab37eSRobert Watson { 288395fab37eSRobert Watson int error; 288495fab37eSRobert Watson 2885b12baf55SRobert Watson PROC_LOCK_ASSERT(proc, MA_OWNED); 2886b12baf55SRobert Watson 288795fab37eSRobert Watson if (!mac_enforce_process) 288895fab37eSRobert Watson return (0); 288995fab37eSRobert Watson 289095fab37eSRobert Watson MAC_CHECK(check_proc_sched, cred, proc); 289195fab37eSRobert Watson 289295fab37eSRobert Watson return (error); 289395fab37eSRobert Watson } 289495fab37eSRobert Watson 289595fab37eSRobert Watson int 289695fab37eSRobert Watson mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 289795fab37eSRobert Watson { 289895fab37eSRobert Watson int error; 289995fab37eSRobert Watson 2900b12baf55SRobert Watson PROC_LOCK_ASSERT(proc, MA_OWNED); 2901b12baf55SRobert Watson 290295fab37eSRobert Watson if (!mac_enforce_process) 290395fab37eSRobert Watson return (0); 290495fab37eSRobert Watson 290595fab37eSRobert Watson MAC_CHECK(check_proc_signal, cred, proc, signum); 290695fab37eSRobert Watson 290795fab37eSRobert Watson return (error); 290895fab37eSRobert Watson } 290995fab37eSRobert Watson 291095fab37eSRobert Watson int 291195fab37eSRobert Watson mac_check_socket_bind(struct ucred *ucred, struct socket *socket, 291295fab37eSRobert Watson struct sockaddr *sockaddr) 291395fab37eSRobert Watson { 291495fab37eSRobert Watson int error; 291595fab37eSRobert Watson 291695fab37eSRobert Watson if (!mac_enforce_socket) 291795fab37eSRobert Watson return (0); 291895fab37eSRobert Watson 291995fab37eSRobert Watson MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 292095fab37eSRobert Watson sockaddr); 292195fab37eSRobert Watson 292295fab37eSRobert Watson return (error); 292395fab37eSRobert Watson } 292495fab37eSRobert Watson 292595fab37eSRobert Watson int 292695fab37eSRobert Watson mac_check_socket_connect(struct ucred *cred, struct socket *socket, 292795fab37eSRobert Watson struct sockaddr *sockaddr) 292895fab37eSRobert Watson { 292995fab37eSRobert Watson int error; 293095fab37eSRobert Watson 293195fab37eSRobert Watson if (!mac_enforce_socket) 293295fab37eSRobert Watson return (0); 293395fab37eSRobert Watson 293495fab37eSRobert Watson MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 293595fab37eSRobert Watson sockaddr); 293695fab37eSRobert Watson 293795fab37eSRobert Watson return (error); 293895fab37eSRobert Watson } 293995fab37eSRobert Watson 294095fab37eSRobert Watson int 2941d61198e4SRobert Watson mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2942d61198e4SRobert Watson { 2943d61198e4SRobert Watson int error; 2944d61198e4SRobert Watson 2945d61198e4SRobert Watson if (!mac_enforce_socket) 2946d61198e4SRobert Watson return (0); 2947d61198e4SRobert Watson 2948d61198e4SRobert Watson MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2949d61198e4SRobert Watson &mbuf->m_pkthdr.label); 2950d61198e4SRobert Watson 2951d61198e4SRobert Watson return (error); 2952d61198e4SRobert Watson } 2953d61198e4SRobert Watson 2954d61198e4SRobert Watson int 295595fab37eSRobert Watson mac_check_socket_listen(struct ucred *cred, struct socket *socket) 295695fab37eSRobert Watson { 295795fab37eSRobert Watson int error; 295895fab37eSRobert Watson 295995fab37eSRobert Watson if (!mac_enforce_socket) 296095fab37eSRobert Watson return (0); 296195fab37eSRobert Watson 296295fab37eSRobert Watson MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 296395fab37eSRobert Watson return (error); 296495fab37eSRobert Watson } 296595fab37eSRobert Watson 2966b371c939SRobert Watson int 2967b371c939SRobert Watson mac_check_socket_receive(struct ucred *cred, struct socket *so) 2968b371c939SRobert Watson { 2969b371c939SRobert Watson int error; 2970b371c939SRobert Watson 2971b371c939SRobert Watson if (!mac_enforce_socket) 2972b371c939SRobert Watson return (0); 2973b371c939SRobert Watson 2974b371c939SRobert Watson MAC_CHECK(check_socket_receive, cred, so, &so->so_label); 2975b371c939SRobert Watson 2976b371c939SRobert Watson return (error); 2977b371c939SRobert Watson } 2978b371c939SRobert Watson 297995fab37eSRobert Watson static int 298095fab37eSRobert Watson mac_check_socket_relabel(struct ucred *cred, struct socket *socket, 298195fab37eSRobert Watson struct label *newlabel) 298295fab37eSRobert Watson { 298395fab37eSRobert Watson int error; 298495fab37eSRobert Watson 298595fab37eSRobert Watson MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 298695fab37eSRobert Watson newlabel); 298795fab37eSRobert Watson 298895fab37eSRobert Watson return (error); 298995fab37eSRobert Watson } 299095fab37eSRobert Watson 299195fab37eSRobert Watson int 2992b371c939SRobert Watson mac_check_socket_send(struct ucred *cred, struct socket *so) 2993b371c939SRobert Watson { 2994b371c939SRobert Watson int error; 2995b371c939SRobert Watson 2996b371c939SRobert Watson if (!mac_enforce_socket) 2997b371c939SRobert Watson return (0); 2998b371c939SRobert Watson 2999b371c939SRobert Watson MAC_CHECK(check_socket_send, cred, so, &so->so_label); 3000b371c939SRobert Watson 3001b371c939SRobert Watson return (error); 3002b371c939SRobert Watson } 3003b371c939SRobert Watson 3004b371c939SRobert Watson int 300595fab37eSRobert Watson mac_check_socket_visible(struct ucred *cred, struct socket *socket) 300695fab37eSRobert Watson { 300795fab37eSRobert Watson int error; 300895fab37eSRobert Watson 300995fab37eSRobert Watson if (!mac_enforce_socket) 301095fab37eSRobert Watson return (0); 301195fab37eSRobert Watson 301295fab37eSRobert Watson MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 301395fab37eSRobert Watson 301495fab37eSRobert Watson return (error); 301595fab37eSRobert Watson } 301695fab37eSRobert Watson 301795fab37eSRobert Watson int 3018a2ecb9b7SRobert Watson mac_check_system_reboot(struct ucred *cred, int howto) 3019a2ecb9b7SRobert Watson { 3020a2ecb9b7SRobert Watson int error; 3021a2ecb9b7SRobert Watson 3022a2ecb9b7SRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_system_reboot"); 3023a2ecb9b7SRobert Watson 3024a2ecb9b7SRobert Watson if (!mac_enforce_reboot) 3025a2ecb9b7SRobert Watson return (0); 3026a2ecb9b7SRobert Watson 3027a2ecb9b7SRobert Watson MAC_CHECK(check_system_reboot, cred, howto); 3028a2ecb9b7SRobert Watson return (error); 3029a2ecb9b7SRobert Watson } 3030a2ecb9b7SRobert Watson 3031a2ecb9b7SRobert Watson int 303203ce2c0cSRobert Watson mac_check_system_swapon(struct ucred *cred, struct vnode *vp) 303303ce2c0cSRobert Watson { 303403ce2c0cSRobert Watson int error; 303503ce2c0cSRobert Watson 303603ce2c0cSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon"); 303703ce2c0cSRobert Watson 303803ce2c0cSRobert Watson if (!mac_enforce_fs) 303903ce2c0cSRobert Watson return (0); 304003ce2c0cSRobert Watson 304103ce2c0cSRobert Watson MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label); 304203ce2c0cSRobert Watson return (error); 304303ce2c0cSRobert Watson } 304403ce2c0cSRobert Watson 304503ce2c0cSRobert Watson int 3046d3fc69eeSRobert Watson mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 3047d3fc69eeSRobert Watson void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 3048d3fc69eeSRobert Watson { 3049d3fc69eeSRobert Watson int error; 3050d3fc69eeSRobert Watson 3051d3fc69eeSRobert Watson /* 3052d3fc69eeSRobert Watson * XXXMAC: We're very much like to assert the SYSCTL_LOCK here, 3053d3fc69eeSRobert Watson * but since it's not exported from kern_sysctl.c, we can't. 3054d3fc69eeSRobert Watson */ 3055d3fc69eeSRobert Watson if (!mac_enforce_sysctl) 3056d3fc69eeSRobert Watson return (0); 3057d3fc69eeSRobert Watson 3058d3fc69eeSRobert Watson MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp, 3059d3fc69eeSRobert Watson inkernel, new, newlen); 3060d3fc69eeSRobert Watson 3061d3fc69eeSRobert Watson return (error); 3062d3fc69eeSRobert Watson } 3063d3fc69eeSRobert Watson 3064d3fc69eeSRobert Watson int 306595fab37eSRobert Watson mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 306695fab37eSRobert Watson struct ifnet *ifnet) 306795fab37eSRobert Watson { 3068f7b951a8SRobert Watson char *elements, *buffer; 3069f7b951a8SRobert Watson struct mac mac; 307095fab37eSRobert Watson int error; 307195fab37eSRobert Watson 3072f7b951a8SRobert Watson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 307395fab37eSRobert Watson if (error) 307495fab37eSRobert Watson return (error); 307595fab37eSRobert Watson 3076f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 3077f7b951a8SRobert Watson if (error) 3078f7b951a8SRobert Watson return (error); 3079f7b951a8SRobert Watson 3080f7b951a8SRobert Watson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3081f7b951a8SRobert Watson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3082f7b951a8SRobert Watson if (error) { 3083f7b951a8SRobert Watson free(elements, M_MACTEMP); 3084f7b951a8SRobert Watson return (error); 3085f7b951a8SRobert Watson } 3086f7b951a8SRobert Watson 3087f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3088f7b951a8SRobert Watson error = mac_externalize_ifnet_label(&ifnet->if_label, elements, 3089f7b951a8SRobert Watson buffer, mac.m_buflen, M_WAITOK); 3090f7b951a8SRobert Watson if (error == 0) 3091f7b951a8SRobert Watson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3092f7b951a8SRobert Watson 3093f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3094f7b951a8SRobert Watson free(elements, M_MACTEMP); 3095f7b951a8SRobert Watson 3096f7b951a8SRobert Watson return (error); 309795fab37eSRobert Watson } 309895fab37eSRobert Watson 309995fab37eSRobert Watson int 310095fab37eSRobert Watson mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 310195fab37eSRobert Watson struct ifnet *ifnet) 310295fab37eSRobert Watson { 310395fab37eSRobert Watson struct label intlabel; 3104f7b951a8SRobert Watson struct mac mac; 3105f7b951a8SRobert Watson char *buffer; 310695fab37eSRobert Watson int error; 310795fab37eSRobert Watson 3108f7b951a8SRobert Watson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 310995fab37eSRobert Watson if (error) 311095fab37eSRobert Watson return (error); 311195fab37eSRobert Watson 3112f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 311395fab37eSRobert Watson if (error) 311495fab37eSRobert Watson return (error); 311595fab37eSRobert Watson 3116f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3117f7b951a8SRobert Watson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3118f7b951a8SRobert Watson if (error) { 3119f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3120f7b951a8SRobert Watson return (error); 3121f7b951a8SRobert Watson } 3122f7b951a8SRobert Watson 3123f7b951a8SRobert Watson mac_init_ifnet_label(&intlabel); 3124f7b951a8SRobert Watson error = mac_internalize_ifnet_label(&intlabel, buffer); 3125f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3126f7b951a8SRobert Watson if (error) { 3127f7b951a8SRobert Watson mac_destroy_ifnet_label(&intlabel); 3128f7b951a8SRobert Watson return (error); 3129f7b951a8SRobert Watson } 3130f7b951a8SRobert Watson 313195fab37eSRobert Watson /* 313295fab37eSRobert Watson * XXX: Note that this is a redundant privilege check, since 313395fab37eSRobert Watson * policies impose this check themselves if required by the 313495fab37eSRobert Watson * policy. Eventually, this should go away. 313595fab37eSRobert Watson */ 313695fab37eSRobert Watson error = suser_cred(cred, 0); 3137f7b951a8SRobert Watson if (error) { 3138f7b951a8SRobert Watson mac_destroy_ifnet_label(&intlabel); 3139f7b951a8SRobert Watson return (error); 3140f7b951a8SRobert Watson } 314195fab37eSRobert Watson 314295fab37eSRobert Watson MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 314395fab37eSRobert Watson &intlabel); 3144f7b951a8SRobert Watson if (error) { 3145f7b951a8SRobert Watson mac_destroy_ifnet_label(&intlabel); 3146f7b951a8SRobert Watson return (error); 3147f7b951a8SRobert Watson } 314895fab37eSRobert Watson 314995fab37eSRobert Watson MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 315095fab37eSRobert Watson 3151f7b951a8SRobert Watson mac_destroy_ifnet_label(&intlabel); 3152f7b951a8SRobert Watson return (0); 315395fab37eSRobert Watson } 315495fab37eSRobert Watson 315595fab37eSRobert Watson void 315695fab37eSRobert Watson mac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp) 315795fab37eSRobert Watson { 315895fab37eSRobert Watson 315995fab37eSRobert Watson MAC_PERFORM(create_devfs_vnode, de, &de->de_label, vp, &vp->v_label); 316095fab37eSRobert Watson } 316195fab37eSRobert Watson 316295fab37eSRobert Watson void 316395fab37eSRobert Watson mac_create_devfs_device(dev_t dev, struct devfs_dirent *de) 316495fab37eSRobert Watson { 316595fab37eSRobert Watson 316695fab37eSRobert Watson MAC_PERFORM(create_devfs_device, dev, de, &de->de_label); 316795fab37eSRobert Watson } 316895fab37eSRobert Watson 316974e62b1bSRobert Watson void 317074e62b1bSRobert Watson mac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd, 317174e62b1bSRobert Watson struct devfs_dirent *de) 317274e62b1bSRobert Watson { 317374e62b1bSRobert Watson 317474e62b1bSRobert Watson MAC_PERFORM(create_devfs_symlink, cred, dd, &dd->de_label, de, 317574e62b1bSRobert Watson &de->de_label); 317674e62b1bSRobert Watson } 317774e62b1bSRobert Watson 317895fab37eSRobert Watson void 317995fab37eSRobert Watson mac_create_devfs_directory(char *dirname, int dirnamelen, 318095fab37eSRobert Watson struct devfs_dirent *de) 318195fab37eSRobert Watson { 318295fab37eSRobert Watson 318395fab37eSRobert Watson MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de, 318495fab37eSRobert Watson &de->de_label); 318595fab37eSRobert Watson } 318695fab37eSRobert Watson 318795fab37eSRobert Watson int 318895fab37eSRobert Watson mac_setsockopt_label_set(struct ucred *cred, struct socket *so, 3189f7b951a8SRobert Watson struct mac *mac) 319095fab37eSRobert Watson { 319195fab37eSRobert Watson struct label intlabel; 3192f7b951a8SRobert Watson char *buffer; 319395fab37eSRobert Watson int error; 319495fab37eSRobert Watson 3195f7b951a8SRobert Watson error = mac_check_structmac_consistent(mac); 319695fab37eSRobert Watson if (error) 319795fab37eSRobert Watson return (error); 319895fab37eSRobert Watson 3199f7b951a8SRobert Watson buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3200f7b951a8SRobert Watson error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); 3201f7b951a8SRobert Watson if (error) { 3202f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3203f7b951a8SRobert Watson return (error); 3204f7b951a8SRobert Watson } 3205f7b951a8SRobert Watson 3206f7b951a8SRobert Watson mac_init_socket_label(&intlabel, M_WAITOK); 3207f7b951a8SRobert Watson error = mac_internalize_socket_label(&intlabel, buffer); 3208f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3209f7b951a8SRobert Watson if (error) { 3210f7b951a8SRobert Watson mac_destroy_socket_label(&intlabel); 3211f7b951a8SRobert Watson return (error); 3212f7b951a8SRobert Watson } 3213f7b951a8SRobert Watson 321495fab37eSRobert Watson mac_check_socket_relabel(cred, so, &intlabel); 321595fab37eSRobert Watson if (error) { 3216f7b951a8SRobert Watson mac_destroy_socket_label(&intlabel); 321795fab37eSRobert Watson return (error); 321895fab37eSRobert Watson } 321995fab37eSRobert Watson 322095fab37eSRobert Watson mac_relabel_socket(cred, so, &intlabel); 322195fab37eSRobert Watson 3222f7b951a8SRobert Watson mac_destroy_socket_label(&intlabel); 322395fab37eSRobert Watson return (0); 322495fab37eSRobert Watson } 322595fab37eSRobert Watson 322695fab37eSRobert Watson int 322795fab37eSRobert Watson mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 322895fab37eSRobert Watson { 322995fab37eSRobert Watson int error; 323095fab37eSRobert Watson 32311aa37f53SRobert Watson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 32321aa37f53SRobert Watson 323395fab37eSRobert Watson error = mac_check_pipe_relabel(cred, pipe, label); 323495fab37eSRobert Watson if (error) 323595fab37eSRobert Watson return (error); 323695fab37eSRobert Watson 323795fab37eSRobert Watson mac_relabel_pipe(cred, pipe, label); 323895fab37eSRobert Watson 323995fab37eSRobert Watson return (0); 324095fab37eSRobert Watson } 324195fab37eSRobert Watson 324295fab37eSRobert Watson int 324395fab37eSRobert Watson mac_getsockopt_label_get(struct ucred *cred, struct socket *so, 3244f7b951a8SRobert Watson struct mac *mac) 324595fab37eSRobert Watson { 3246f7b951a8SRobert Watson char *buffer, *elements; 3247f7b951a8SRobert Watson int error; 324895fab37eSRobert Watson 3249f7b951a8SRobert Watson error = mac_check_structmac_consistent(mac); 3250f7b951a8SRobert Watson if (error) 3251f7b951a8SRobert Watson return (error); 3252f7b951a8SRobert Watson 3253f7b951a8SRobert Watson elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3254f7b951a8SRobert Watson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3255f7b951a8SRobert Watson if (error) { 3256f7b951a8SRobert Watson free(elements, M_MACTEMP); 3257f7b951a8SRobert Watson return (error); 3258f7b951a8SRobert Watson } 3259f7b951a8SRobert Watson 3260f7b951a8SRobert Watson buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3261f7b951a8SRobert Watson error = mac_externalize_socket_label(&so->so_label, elements, 3262f7b951a8SRobert Watson buffer, mac->m_buflen, M_WAITOK); 3263f7b951a8SRobert Watson if (error == 0) 3264f7b951a8SRobert Watson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3265f7b951a8SRobert Watson 3266f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3267f7b951a8SRobert Watson free(elements, M_MACTEMP); 3268f7b951a8SRobert Watson 3269f7b951a8SRobert Watson return (error); 327095fab37eSRobert Watson } 327195fab37eSRobert Watson 327295fab37eSRobert Watson int 327395fab37eSRobert Watson mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 3274f7b951a8SRobert Watson struct mac *mac) 327595fab37eSRobert Watson { 3276f7b951a8SRobert Watson char *elements, *buffer; 3277f7b951a8SRobert Watson int error; 327895fab37eSRobert Watson 3279f7b951a8SRobert Watson error = mac_check_structmac_consistent(mac); 3280f7b951a8SRobert Watson if (error) 3281f7b951a8SRobert Watson return (error); 3282f7b951a8SRobert Watson 3283f7b951a8SRobert Watson elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3284f7b951a8SRobert Watson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3285f7b951a8SRobert Watson if (error) { 3286f7b951a8SRobert Watson free(elements, M_MACTEMP); 3287f7b951a8SRobert Watson return (error); 3288f7b951a8SRobert Watson } 3289f7b951a8SRobert Watson 3290f7b951a8SRobert Watson buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3291f7b951a8SRobert Watson error = mac_externalize_socket_peer_label(&so->so_peerlabel, 3292f7b951a8SRobert Watson elements, buffer, mac->m_buflen, M_WAITOK); 3293f7b951a8SRobert Watson if (error == 0) 3294f7b951a8SRobert Watson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3295f7b951a8SRobert Watson 3296f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3297f7b951a8SRobert Watson free(elements, M_MACTEMP); 3298f7b951a8SRobert Watson 3299f7b951a8SRobert Watson return (error); 330095fab37eSRobert Watson } 330195fab37eSRobert Watson 330295fab37eSRobert Watson /* 330395fab37eSRobert Watson * Implementation of VOP_SETLABEL() that relies on extended attributes 330495fab37eSRobert Watson * to store label data. Can be referenced by filesystems supporting 330595fab37eSRobert Watson * extended attributes. 330695fab37eSRobert Watson */ 330795fab37eSRobert Watson int 330895fab37eSRobert Watson vop_stdsetlabel_ea(struct vop_setlabel_args *ap) 330995fab37eSRobert Watson { 331095fab37eSRobert Watson struct vnode *vp = ap->a_vp; 331195fab37eSRobert Watson struct label *intlabel = ap->a_label; 331295fab37eSRobert Watson int error; 331395fab37eSRobert Watson 331495fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 331595fab37eSRobert Watson 3316763bbd2fSRobert Watson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3317763bbd2fSRobert Watson return (EOPNOTSUPP); 331895fab37eSRobert Watson 3319763bbd2fSRobert Watson error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel); 332095fab37eSRobert Watson if (error) 332195fab37eSRobert Watson return (error); 332295fab37eSRobert Watson 332395fab37eSRobert Watson mac_relabel_vnode(ap->a_cred, vp, intlabel); 332495fab37eSRobert Watson 332595fab37eSRobert Watson return (0); 332695fab37eSRobert Watson } 332795fab37eSRobert Watson 332895fab37eSRobert Watson static int 332995fab37eSRobert Watson vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 333095fab37eSRobert Watson { 333195fab37eSRobert Watson int error; 333295fab37eSRobert Watson 333395fab37eSRobert Watson if (vp->v_mount == NULL) { 333495fab37eSRobert Watson /* printf("vn_setlabel: null v_mount\n"); */ 333506be2aaaSNate Lawson if (vp->v_type != VNON) 333606be2aaaSNate Lawson printf("vn_setlabel: null v_mount with non-VNON\n"); 333795fab37eSRobert Watson return (EBADF); 333895fab37eSRobert Watson } 333995fab37eSRobert Watson 334095fab37eSRobert Watson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 334195fab37eSRobert Watson return (EOPNOTSUPP); 334295fab37eSRobert Watson 334395fab37eSRobert Watson /* 334495fab37eSRobert Watson * Multi-phase commit. First check the policies to confirm the 334595fab37eSRobert Watson * change is OK. Then commit via the filesystem. Finally, 334695fab37eSRobert Watson * update the actual vnode label. Question: maybe the filesystem 334795fab37eSRobert Watson * should update the vnode at the end as part of VOP_SETLABEL()? 334895fab37eSRobert Watson */ 334995fab37eSRobert Watson error = mac_check_vnode_relabel(cred, vp, intlabel); 335095fab37eSRobert Watson if (error) 335195fab37eSRobert Watson return (error); 335295fab37eSRobert Watson 335395fab37eSRobert Watson /* 335495fab37eSRobert Watson * VADMIN provides the opportunity for the filesystem to make 335595fab37eSRobert Watson * decisions about who is and is not able to modify labels 335695fab37eSRobert Watson * and protections on files. This might not be right. We can't 335795fab37eSRobert Watson * assume VOP_SETLABEL() will do it, because we might implement 335895fab37eSRobert Watson * that as part of vop_stdsetlabel_ea(). 335995fab37eSRobert Watson */ 336095fab37eSRobert Watson error = VOP_ACCESS(vp, VADMIN, cred, curthread); 336195fab37eSRobert Watson if (error) 336295fab37eSRobert Watson return (error); 336395fab37eSRobert Watson 336495fab37eSRobert Watson error = VOP_SETLABEL(vp, intlabel, cred, curthread); 336595fab37eSRobert Watson if (error) 336695fab37eSRobert Watson return (error); 336795fab37eSRobert Watson 336895fab37eSRobert Watson return (0); 336995fab37eSRobert Watson } 337095fab37eSRobert Watson 3371f7b951a8SRobert Watson int 3372f7b951a8SRobert Watson __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3373f7b951a8SRobert Watson { 3374f7b951a8SRobert Watson char *elements, *buffer; 3375f7b951a8SRobert Watson struct mac mac; 3376f7b951a8SRobert Watson struct proc *tproc; 3377f7b951a8SRobert Watson struct ucred *tcred; 3378f7b951a8SRobert Watson int error; 3379f7b951a8SRobert Watson 3380f7b951a8SRobert Watson error = copyin(SCARG(uap, mac_p), &mac, sizeof(mac)); 3381f7b951a8SRobert Watson if (error) 3382f7b951a8SRobert Watson return (error); 3383f7b951a8SRobert Watson 3384f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 3385f7b951a8SRobert Watson if (error) 3386f7b951a8SRobert Watson return (error); 3387f7b951a8SRobert Watson 3388f7b951a8SRobert Watson tproc = pfind(uap->pid); 3389f7b951a8SRobert Watson if (tproc == NULL) 3390f7b951a8SRobert Watson return (ESRCH); 3391f7b951a8SRobert Watson 3392f7b951a8SRobert Watson tcred = NULL; /* Satisfy gcc. */ 3393f7b951a8SRobert Watson error = p_cansee(td, tproc); 3394f7b951a8SRobert Watson if (error == 0) 3395f7b951a8SRobert Watson tcred = crhold(tproc->p_ucred); 3396f7b951a8SRobert Watson PROC_UNLOCK(tproc); 3397f7b951a8SRobert Watson if (error) 3398f7b951a8SRobert Watson return (error); 3399f7b951a8SRobert Watson 3400f7b951a8SRobert Watson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3401f7b951a8SRobert Watson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3402f7b951a8SRobert Watson if (error) { 3403f7b951a8SRobert Watson free(elements, M_MACTEMP); 3404f7b951a8SRobert Watson crfree(tcred); 3405f7b951a8SRobert Watson return (error); 3406f7b951a8SRobert Watson } 3407f7b951a8SRobert Watson 3408f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3409f7b951a8SRobert Watson error = mac_externalize_cred_label(&tcred->cr_label, elements, 3410f7b951a8SRobert Watson buffer, mac.m_buflen, M_WAITOK); 3411f7b951a8SRobert Watson if (error == 0) 3412f7b951a8SRobert Watson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3413f7b951a8SRobert Watson 3414f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3415f7b951a8SRobert Watson free(elements, M_MACTEMP); 3416f7b951a8SRobert Watson crfree(tcred); 3417f7b951a8SRobert Watson return (error); 3418f7b951a8SRobert Watson } 3419f7b951a8SRobert Watson 342095fab37eSRobert Watson /* 342195fab37eSRobert Watson * MPSAFE 342295fab37eSRobert Watson */ 342395fab37eSRobert Watson int 342495fab37eSRobert Watson __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 342595fab37eSRobert Watson { 3426f7b951a8SRobert Watson char *elements, *buffer; 3427f7b951a8SRobert Watson struct mac mac; 342895fab37eSRobert Watson int error; 342995fab37eSRobert Watson 3430f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3431f7b951a8SRobert Watson if (error) 3432f7b951a8SRobert Watson return (error); 343395fab37eSRobert Watson 3434f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 3435f7b951a8SRobert Watson if (error) 3436f7b951a8SRobert Watson return (error); 3437f7b951a8SRobert Watson 3438f7b951a8SRobert Watson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3439f7b951a8SRobert Watson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3440f7b951a8SRobert Watson if (error) { 3441f7b951a8SRobert Watson free(elements, M_MACTEMP); 3442f7b951a8SRobert Watson return (error); 3443f7b951a8SRobert Watson } 3444f7b951a8SRobert Watson 3445f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3446f7b951a8SRobert Watson error = mac_externalize_cred_label(&td->td_ucred->cr_label, 3447f7b951a8SRobert Watson elements, buffer, mac.m_buflen, M_WAITOK); 3448f7b951a8SRobert Watson if (error == 0) 3449f7b951a8SRobert Watson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3450f7b951a8SRobert Watson 3451f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3452f7b951a8SRobert Watson free(elements, M_MACTEMP); 345395fab37eSRobert Watson return (error); 345495fab37eSRobert Watson } 345595fab37eSRobert Watson 345695fab37eSRobert Watson /* 345795fab37eSRobert Watson * MPSAFE 345895fab37eSRobert Watson */ 345995fab37eSRobert Watson int 346095fab37eSRobert Watson __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 346195fab37eSRobert Watson { 346295fab37eSRobert Watson struct ucred *newcred, *oldcred; 346395fab37eSRobert Watson struct label intlabel; 3464f7b951a8SRobert Watson struct proc *p; 3465f7b951a8SRobert Watson struct mac mac; 3466f7b951a8SRobert Watson char *buffer; 346795fab37eSRobert Watson int error; 346895fab37eSRobert Watson 3469f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 347095fab37eSRobert Watson if (error) 347195fab37eSRobert Watson return (error); 347295fab37eSRobert Watson 3473f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 347495fab37eSRobert Watson if (error) 347595fab37eSRobert Watson return (error); 347695fab37eSRobert Watson 3477f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3478f7b951a8SRobert Watson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3479f7b951a8SRobert Watson if (error) { 3480f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3481f7b951a8SRobert Watson return (error); 3482f7b951a8SRobert Watson } 3483f7b951a8SRobert Watson 3484f7b951a8SRobert Watson mac_init_cred_label(&intlabel); 3485f7b951a8SRobert Watson error = mac_internalize_cred_label(&intlabel, buffer); 3486f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3487f7b951a8SRobert Watson if (error) { 3488f7b951a8SRobert Watson mac_destroy_cred_label(&intlabel); 3489f7b951a8SRobert Watson return (error); 3490f7b951a8SRobert Watson } 3491f7b951a8SRobert Watson 349295fab37eSRobert Watson newcred = crget(); 349395fab37eSRobert Watson 349495fab37eSRobert Watson p = td->td_proc; 349595fab37eSRobert Watson PROC_LOCK(p); 349695fab37eSRobert Watson oldcred = p->p_ucred; 349795fab37eSRobert Watson 349895fab37eSRobert Watson error = mac_check_cred_relabel(oldcred, &intlabel); 349995fab37eSRobert Watson if (error) { 350095fab37eSRobert Watson PROC_UNLOCK(p); 350195fab37eSRobert Watson crfree(newcred); 3502f7b951a8SRobert Watson goto out; 350395fab37eSRobert Watson } 350495fab37eSRobert Watson 350595fab37eSRobert Watson setsugid(p); 350695fab37eSRobert Watson crcopy(newcred, oldcred); 350795fab37eSRobert Watson mac_relabel_cred(newcred, &intlabel); 350895fab37eSRobert Watson p->p_ucred = newcred; 3509e5cb5e37SRobert Watson 3510e5cb5e37SRobert Watson /* 3511e5cb5e37SRobert Watson * Grab additional reference for use while revoking mmaps, prior 3512e5cb5e37SRobert Watson * to releasing the proc lock and sharing the cred. 3513e5cb5e37SRobert Watson */ 3514e5cb5e37SRobert Watson crhold(newcred); 351595fab37eSRobert Watson PROC_UNLOCK(p); 3516e5cb5e37SRobert Watson 3517f7b951a8SRobert Watson if (mac_enforce_vm) { 351816140035SRobert Watson mtx_lock(&Giant); 3519e5cb5e37SRobert Watson mac_cred_mmapped_drop_perms(td, newcred); 352016140035SRobert Watson mtx_unlock(&Giant); 3521f7b951a8SRobert Watson } 3522e5cb5e37SRobert Watson 3523e5cb5e37SRobert Watson crfree(newcred); /* Free revocation reference. */ 352495fab37eSRobert Watson crfree(oldcred); 3525f7b951a8SRobert Watson 3526f7b951a8SRobert Watson out: 3527f7b951a8SRobert Watson mac_destroy_cred_label(&intlabel); 3528f7b951a8SRobert Watson return (error); 352995fab37eSRobert Watson } 353095fab37eSRobert Watson 353195fab37eSRobert Watson /* 353295fab37eSRobert Watson * MPSAFE 353395fab37eSRobert Watson */ 353495fab37eSRobert Watson int 353595fab37eSRobert Watson __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 353695fab37eSRobert Watson { 3537f7b951a8SRobert Watson char *elements, *buffer; 3538f7b951a8SRobert Watson struct label intlabel; 353995fab37eSRobert Watson struct file *fp; 3540f7b951a8SRobert Watson struct mac mac; 354195fab37eSRobert Watson struct vnode *vp; 354295fab37eSRobert Watson struct pipe *pipe; 3543f7b951a8SRobert Watson short label_type; 354495fab37eSRobert Watson int error; 354595fab37eSRobert Watson 3546f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3547f7b951a8SRobert Watson if (error) 3548f7b951a8SRobert Watson return (error); 354995fab37eSRobert Watson 3550f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 3551f7b951a8SRobert Watson if (error) 3552f7b951a8SRobert Watson return (error); 3553f7b951a8SRobert Watson 3554f7b951a8SRobert Watson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3555f7b951a8SRobert Watson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3556f7b951a8SRobert Watson if (error) { 3557f7b951a8SRobert Watson free(elements, M_MACTEMP); 3558f7b951a8SRobert Watson return (error); 3559f7b951a8SRobert Watson } 3560f7b951a8SRobert Watson 3561f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3562f7b951a8SRobert Watson mtx_lock(&Giant); /* VFS */ 356395fab37eSRobert Watson error = fget(td, SCARG(uap, fd), &fp); 356495fab37eSRobert Watson if (error) 356595fab37eSRobert Watson goto out; 356695fab37eSRobert Watson 3567f7b951a8SRobert Watson label_type = fp->f_type; 356895fab37eSRobert Watson switch (fp->f_type) { 356995fab37eSRobert Watson case DTYPE_FIFO: 357095fab37eSRobert Watson case DTYPE_VNODE: 357195fab37eSRobert Watson vp = (struct vnode *)fp->f_data; 357295fab37eSRobert Watson 3573f7b951a8SRobert Watson mac_init_vnode_label(&intlabel); 3574f7b951a8SRobert Watson 357595fab37eSRobert Watson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3576f7b951a8SRobert Watson mac_copy_vnode_label(&vp->v_label, &intlabel); 357795fab37eSRobert Watson VOP_UNLOCK(vp, 0, td); 3578f7b951a8SRobert Watson 357995fab37eSRobert Watson break; 358095fab37eSRobert Watson case DTYPE_PIPE: 358195fab37eSRobert Watson pipe = (struct pipe *)fp->f_data; 3582f7b951a8SRobert Watson 3583f7b951a8SRobert Watson mac_init_pipe_label(&intlabel); 3584f7b951a8SRobert Watson 3585f7b951a8SRobert Watson PIPE_LOCK(pipe); 3586f7b951a8SRobert Watson mac_copy_pipe_label(pipe->pipe_label, &intlabel); 3587f7b951a8SRobert Watson PIPE_UNLOCK(pipe); 358895fab37eSRobert Watson break; 358995fab37eSRobert Watson default: 359095fab37eSRobert Watson error = EINVAL; 3591f7b951a8SRobert Watson fdrop(fp, td); 3592f7b951a8SRobert Watson goto out; 3593f7b951a8SRobert Watson } 3594f7b951a8SRobert Watson fdrop(fp, td); 3595f7b951a8SRobert Watson 3596f7b951a8SRobert Watson switch (label_type) { 3597f7b951a8SRobert Watson case DTYPE_FIFO: 3598f7b951a8SRobert Watson case DTYPE_VNODE: 3599f7b951a8SRobert Watson if (error == 0) 3600f7b951a8SRobert Watson error = mac_externalize_vnode_label(&intlabel, 3601f7b951a8SRobert Watson elements, buffer, mac.m_buflen, M_WAITOK); 3602f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 3603f7b951a8SRobert Watson break; 3604f7b951a8SRobert Watson case DTYPE_PIPE: 3605f7b951a8SRobert Watson error = mac_externalize_pipe_label(&intlabel, elements, 3606f7b951a8SRobert Watson buffer, mac.m_buflen, M_WAITOK); 3607f7b951a8SRobert Watson mac_destroy_pipe_label(&intlabel); 3608f7b951a8SRobert Watson break; 3609f7b951a8SRobert Watson default: 3610f7b951a8SRobert Watson panic("__mac_get_fd: corrupted label_type"); 361195fab37eSRobert Watson } 361295fab37eSRobert Watson 361395fab37eSRobert Watson if (error == 0) 3614f7b951a8SRobert Watson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 361595fab37eSRobert Watson 361695fab37eSRobert Watson out: 3617f7b951a8SRobert Watson mtx_unlock(&Giant); /* VFS */ 3618f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3619f7b951a8SRobert Watson free(elements, M_MACTEMP); 3620f7b951a8SRobert Watson 362195fab37eSRobert Watson return (error); 362295fab37eSRobert Watson } 362395fab37eSRobert Watson 362495fab37eSRobert Watson /* 362595fab37eSRobert Watson * MPSAFE 362695fab37eSRobert Watson */ 362795fab37eSRobert Watson int 362895fab37eSRobert Watson __mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 362995fab37eSRobert Watson { 3630f7b951a8SRobert Watson char *elements, *buffer; 363195fab37eSRobert Watson struct nameidata nd; 3632f7b951a8SRobert Watson struct label intlabel; 3633f7b951a8SRobert Watson struct mac mac; 363495fab37eSRobert Watson int error; 363595fab37eSRobert Watson 3636f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3637f7b951a8SRobert Watson if (error) 3638f7b951a8SRobert Watson return (error); 3639f7b951a8SRobert Watson 3640f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 3641f7b951a8SRobert Watson if (error) 3642f7b951a8SRobert Watson return (error); 3643f7b951a8SRobert Watson 3644f7b951a8SRobert Watson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3645f7b951a8SRobert Watson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3646f7b951a8SRobert Watson if (error) { 3647f7b951a8SRobert Watson free(elements, M_MACTEMP); 3648f7b951a8SRobert Watson return (error); 3649f7b951a8SRobert Watson } 3650f7b951a8SRobert Watson 3651f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3652f7b951a8SRobert Watson mtx_lock(&Giant); /* VFS */ 3653f7b951a8SRobert Watson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3654f7b951a8SRobert Watson td); 365595fab37eSRobert Watson error = namei(&nd); 365695fab37eSRobert Watson if (error) 365795fab37eSRobert Watson goto out; 365895fab37eSRobert Watson 3659f7b951a8SRobert Watson mac_init_vnode_label(&intlabel); 3660f7b951a8SRobert Watson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3661763bbd2fSRobert Watson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3662763bbd2fSRobert Watson mac.m_buflen, M_WAITOK); 3663f7b951a8SRobert Watson 366495fab37eSRobert Watson NDFREE(&nd, 0); 3665f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 3666f7b951a8SRobert Watson 3667f7b951a8SRobert Watson if (error == 0) 3668f7b951a8SRobert Watson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3669f7b951a8SRobert Watson 3670f7b951a8SRobert Watson out: 3671f7b951a8SRobert Watson mtx_unlock(&Giant); /* VFS */ 3672f7b951a8SRobert Watson 3673f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3674f7b951a8SRobert Watson free(elements, M_MACTEMP); 3675f7b951a8SRobert Watson 3676f7b951a8SRobert Watson return (error); 3677f7b951a8SRobert Watson } 3678f7b951a8SRobert Watson 3679f7b951a8SRobert Watson /* 3680f7b951a8SRobert Watson * MPSAFE 3681f7b951a8SRobert Watson */ 3682f7b951a8SRobert Watson int 3683f7b951a8SRobert Watson __mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3684f7b951a8SRobert Watson { 3685f7b951a8SRobert Watson char *elements, *buffer; 3686f7b951a8SRobert Watson struct nameidata nd; 3687f7b951a8SRobert Watson struct label intlabel; 3688f7b951a8SRobert Watson struct mac mac; 3689f7b951a8SRobert Watson int error; 3690f7b951a8SRobert Watson 3691f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3692f7b951a8SRobert Watson if (error) 3693f7b951a8SRobert Watson return (error); 3694f7b951a8SRobert Watson 3695f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 3696f7b951a8SRobert Watson if (error) 3697f7b951a8SRobert Watson return (error); 3698f7b951a8SRobert Watson 3699f7b951a8SRobert Watson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3700f7b951a8SRobert Watson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3701f7b951a8SRobert Watson if (error) { 3702f7b951a8SRobert Watson free(elements, M_MACTEMP); 3703f7b951a8SRobert Watson return (error); 3704f7b951a8SRobert Watson } 3705f7b951a8SRobert Watson 3706f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3707f7b951a8SRobert Watson mtx_lock(&Giant); /* VFS */ 3708f7b951a8SRobert Watson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3709f7b951a8SRobert Watson td); 3710f7b951a8SRobert Watson error = namei(&nd); 371195fab37eSRobert Watson if (error) 371295fab37eSRobert Watson goto out; 371395fab37eSRobert Watson 3714f7b951a8SRobert Watson mac_init_vnode_label(&intlabel); 3715f7b951a8SRobert Watson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3716763bbd2fSRobert Watson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3717763bbd2fSRobert Watson mac.m_buflen, M_WAITOK); 3718f7b951a8SRobert Watson NDFREE(&nd, 0); 3719f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 3720f7b951a8SRobert Watson 3721f7b951a8SRobert Watson if (error == 0) 3722f7b951a8SRobert Watson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 372395fab37eSRobert Watson 372495fab37eSRobert Watson out: 3725f7b951a8SRobert Watson mtx_unlock(&Giant); /* VFS */ 3726f7b951a8SRobert Watson 3727f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3728f7b951a8SRobert Watson free(elements, M_MACTEMP); 3729f7b951a8SRobert Watson 373095fab37eSRobert Watson return (error); 373195fab37eSRobert Watson } 373295fab37eSRobert Watson 373395fab37eSRobert Watson /* 373495fab37eSRobert Watson * MPSAFE 373595fab37eSRobert Watson */ 373695fab37eSRobert Watson int 373795fab37eSRobert Watson __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 373895fab37eSRobert Watson { 373995fab37eSRobert Watson struct label intlabel; 3740f7b951a8SRobert Watson struct pipe *pipe; 3741f7b951a8SRobert Watson struct file *fp; 374295fab37eSRobert Watson struct mount *mp; 374395fab37eSRobert Watson struct vnode *vp; 3744f7b951a8SRobert Watson struct mac mac; 3745f7b951a8SRobert Watson char *buffer; 374695fab37eSRobert Watson int error; 374795fab37eSRobert Watson 3748f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3749f7b951a8SRobert Watson if (error) 3750f7b951a8SRobert Watson return (error); 3751f7b951a8SRobert Watson 3752f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 3753f7b951a8SRobert Watson if (error) 3754f7b951a8SRobert Watson return (error); 3755f7b951a8SRobert Watson 3756f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3757f7b951a8SRobert Watson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3758f7b951a8SRobert Watson if (error) { 3759f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3760f7b951a8SRobert Watson return (error); 3761f7b951a8SRobert Watson } 3762f7b951a8SRobert Watson 3763f7b951a8SRobert Watson mtx_lock(&Giant); /* VFS */ 3764f7b951a8SRobert Watson 376595fab37eSRobert Watson error = fget(td, SCARG(uap, fd), &fp); 376695fab37eSRobert Watson if (error) 3767f7b951a8SRobert Watson goto out; 376895fab37eSRobert Watson 376995fab37eSRobert Watson switch (fp->f_type) { 377095fab37eSRobert Watson case DTYPE_FIFO: 377195fab37eSRobert Watson case DTYPE_VNODE: 3772f7b951a8SRobert Watson mac_init_vnode_label(&intlabel); 3773f7b951a8SRobert Watson error = mac_internalize_vnode_label(&intlabel, buffer); 3774f7b951a8SRobert Watson if (error) { 3775f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 3776f7b951a8SRobert Watson break; 3777f7b951a8SRobert Watson } 3778f7b951a8SRobert Watson 377995fab37eSRobert Watson vp = (struct vnode *)fp->f_data; 378095fab37eSRobert Watson error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3781f7b951a8SRobert Watson if (error != 0) { 3782f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 378395fab37eSRobert Watson break; 3784f7b951a8SRobert Watson } 378595fab37eSRobert Watson 378695fab37eSRobert Watson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 378795fab37eSRobert Watson error = vn_setlabel(vp, &intlabel, td->td_ucred); 378895fab37eSRobert Watson VOP_UNLOCK(vp, 0, td); 378995fab37eSRobert Watson vn_finished_write(mp); 3790f7b951a8SRobert Watson 3791f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 379295fab37eSRobert Watson break; 3793f7b951a8SRobert Watson 379495fab37eSRobert Watson case DTYPE_PIPE: 3795f7b951a8SRobert Watson mac_init_pipe_label(&intlabel); 3796f7b951a8SRobert Watson error = mac_internalize_pipe_label(&intlabel, buffer); 3797f7b951a8SRobert Watson if (error == 0) { 379895fab37eSRobert Watson pipe = (struct pipe *)fp->f_data; 37991aa37f53SRobert Watson PIPE_LOCK(pipe); 3800f7b951a8SRobert Watson error = mac_pipe_label_set(td->td_ucred, pipe, 3801f7b951a8SRobert Watson &intlabel); 38021aa37f53SRobert Watson PIPE_UNLOCK(pipe); 3803f7b951a8SRobert Watson } 3804f7b951a8SRobert Watson 3805f7b951a8SRobert Watson mac_destroy_pipe_label(&intlabel); 380695fab37eSRobert Watson break; 3807f7b951a8SRobert Watson 380895fab37eSRobert Watson default: 380995fab37eSRobert Watson error = EINVAL; 381095fab37eSRobert Watson } 381195fab37eSRobert Watson 381295fab37eSRobert Watson fdrop(fp, td); 3813f7b951a8SRobert Watson out: 3814f7b951a8SRobert Watson mtx_unlock(&Giant); /* VFS */ 3815f7b951a8SRobert Watson 3816f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3817f7b951a8SRobert Watson 381895fab37eSRobert Watson return (error); 381995fab37eSRobert Watson } 382095fab37eSRobert Watson 382195fab37eSRobert Watson /* 382295fab37eSRobert Watson * MPSAFE 382395fab37eSRobert Watson */ 382495fab37eSRobert Watson int 382595fab37eSRobert Watson __mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 382695fab37eSRobert Watson { 382795fab37eSRobert Watson struct label intlabel; 3828f7b951a8SRobert Watson struct nameidata nd; 382995fab37eSRobert Watson struct mount *mp; 3830f7b951a8SRobert Watson struct mac mac; 3831f7b951a8SRobert Watson char *buffer; 383295fab37eSRobert Watson int error; 383395fab37eSRobert Watson 3834f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 383595fab37eSRobert Watson if (error) 3836f7b951a8SRobert Watson return (error); 383795fab37eSRobert Watson 3838f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 383995fab37eSRobert Watson if (error) 3840f7b951a8SRobert Watson return (error); 384195fab37eSRobert Watson 3842f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3843f7b951a8SRobert Watson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3844f7b951a8SRobert Watson if (error) { 3845f7b951a8SRobert Watson free(buffer, M_MACTEMP); 384695fab37eSRobert Watson return (error); 384795fab37eSRobert Watson } 384895fab37eSRobert Watson 3849f7b951a8SRobert Watson mac_init_vnode_label(&intlabel); 3850f7b951a8SRobert Watson error = mac_internalize_vnode_label(&intlabel, buffer); 3851f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3852f7b951a8SRobert Watson if (error) { 3853f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 3854f7b951a8SRobert Watson return (error); 3855f7b951a8SRobert Watson } 3856f7b951a8SRobert Watson 3857f7b951a8SRobert Watson mtx_lock(&Giant); /* VFS */ 3858f7b951a8SRobert Watson 3859f7b951a8SRobert Watson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3860f7b951a8SRobert Watson td); 3861f7b951a8SRobert Watson error = namei(&nd); 3862f7b951a8SRobert Watson if (error == 0) { 3863f7b951a8SRobert Watson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3864f7b951a8SRobert Watson if (error == 0) 3865f7b951a8SRobert Watson error = vn_setlabel(nd.ni_vp, &intlabel, 3866f7b951a8SRobert Watson td->td_ucred); 3867f7b951a8SRobert Watson vn_finished_write(mp); 3868f7b951a8SRobert Watson } 3869f7b951a8SRobert Watson 3870f7b951a8SRobert Watson NDFREE(&nd, 0); 3871f7b951a8SRobert Watson mtx_unlock(&Giant); /* VFS */ 3872f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 3873f7b951a8SRobert Watson 3874f7b951a8SRobert Watson return (error); 3875f7b951a8SRobert Watson } 3876f7b951a8SRobert Watson 3877f7b951a8SRobert Watson /* 3878f7b951a8SRobert Watson * MPSAFE 3879f7b951a8SRobert Watson */ 3880f7b951a8SRobert Watson int 3881f7b951a8SRobert Watson __mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3882f7b951a8SRobert Watson { 3883f7b951a8SRobert Watson struct label intlabel; 3884f7b951a8SRobert Watson struct nameidata nd; 3885f7b951a8SRobert Watson struct mount *mp; 3886f7b951a8SRobert Watson struct mac mac; 3887f7b951a8SRobert Watson char *buffer; 3888f7b951a8SRobert Watson int error; 3889f7b951a8SRobert Watson 3890f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3891f7b951a8SRobert Watson if (error) 3892f7b951a8SRobert Watson return (error); 3893f7b951a8SRobert Watson 3894f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 3895f7b951a8SRobert Watson if (error) 3896f7b951a8SRobert Watson return (error); 3897f7b951a8SRobert Watson 3898f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3899f7b951a8SRobert Watson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3900f7b951a8SRobert Watson if (error) { 3901f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3902f7b951a8SRobert Watson return (error); 3903f7b951a8SRobert Watson } 3904f7b951a8SRobert Watson 3905f7b951a8SRobert Watson mac_init_vnode_label(&intlabel); 3906f7b951a8SRobert Watson error = mac_internalize_vnode_label(&intlabel, buffer); 3907f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3908f7b951a8SRobert Watson if (error) { 3909f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 3910f7b951a8SRobert Watson return (error); 3911f7b951a8SRobert Watson } 3912f7b951a8SRobert Watson 3913f7b951a8SRobert Watson mtx_lock(&Giant); /* VFS */ 3914f7b951a8SRobert Watson 3915f7b951a8SRobert Watson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3916f7b951a8SRobert Watson td); 3917f7b951a8SRobert Watson error = namei(&nd); 3918f7b951a8SRobert Watson if (error == 0) { 3919f7b951a8SRobert Watson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3920f7b951a8SRobert Watson if (error == 0) 3921f7b951a8SRobert Watson error = vn_setlabel(nd.ni_vp, &intlabel, 3922f7b951a8SRobert Watson td->td_ucred); 3923f7b951a8SRobert Watson vn_finished_write(mp); 3924f7b951a8SRobert Watson } 3925f7b951a8SRobert Watson 3926f7b951a8SRobert Watson NDFREE(&nd, 0); 3927f7b951a8SRobert Watson mtx_unlock(&Giant); /* VFS */ 3928f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 3929f7b951a8SRobert Watson 3930f7b951a8SRobert Watson return (error); 3931f7b951a8SRobert Watson } 3932f7b951a8SRobert Watson 3933f7b951a8SRobert Watson /* 3934f7b951a8SRobert Watson * MPSAFE 3935f7b951a8SRobert Watson */ 393627f2eac7SRobert Watson int 393727f2eac7SRobert Watson mac_syscall(struct thread *td, struct mac_syscall_args *uap) 393827f2eac7SRobert Watson { 393927f2eac7SRobert Watson struct mac_policy_conf *mpc; 394027f2eac7SRobert Watson char target[MAC_MAX_POLICY_NAME]; 394127f2eac7SRobert Watson int error; 394227f2eac7SRobert Watson 394327f2eac7SRobert Watson error = copyinstr(SCARG(uap, policy), target, sizeof(target), NULL); 394427f2eac7SRobert Watson if (error) 394527f2eac7SRobert Watson return (error); 394627f2eac7SRobert Watson 394727f2eac7SRobert Watson error = ENOSYS; 394827f2eac7SRobert Watson MAC_POLICY_LIST_BUSY(); 394927f2eac7SRobert Watson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 395027f2eac7SRobert Watson if (strcmp(mpc->mpc_name, target) == 0 && 395127f2eac7SRobert Watson mpc->mpc_ops->mpo_syscall != NULL) { 395227f2eac7SRobert Watson error = mpc->mpc_ops->mpo_syscall(td, 395327f2eac7SRobert Watson SCARG(uap, call), SCARG(uap, arg)); 395427f2eac7SRobert Watson goto out; 395527f2eac7SRobert Watson } 395627f2eac7SRobert Watson } 395727f2eac7SRobert Watson 395827f2eac7SRobert Watson out: 395927f2eac7SRobert Watson MAC_POLICY_LIST_UNBUSY(); 396027f2eac7SRobert Watson return (error); 396127f2eac7SRobert Watson } 396227f2eac7SRobert Watson 396395fab37eSRobert Watson SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 396495fab37eSRobert Watson SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 396595fab37eSRobert Watson 396695fab37eSRobert Watson #else /* !MAC */ 39677bc82500SRobert Watson 39687bc82500SRobert Watson int 3969f7b951a8SRobert Watson __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3970f7b951a8SRobert Watson { 3971f7b951a8SRobert Watson 3972f7b951a8SRobert Watson return (ENOSYS); 3973f7b951a8SRobert Watson } 3974f7b951a8SRobert Watson 3975f7b951a8SRobert Watson int 39767bc82500SRobert Watson __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 39777bc82500SRobert Watson { 39787bc82500SRobert Watson 39797bc82500SRobert Watson return (ENOSYS); 39807bc82500SRobert Watson } 39817bc82500SRobert Watson 39827bc82500SRobert Watson int 39837bc82500SRobert Watson __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 39847bc82500SRobert Watson { 39857bc82500SRobert Watson 39867bc82500SRobert Watson return (ENOSYS); 39877bc82500SRobert Watson } 39887bc82500SRobert Watson 39897bc82500SRobert Watson int 39907bc82500SRobert Watson __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 39917bc82500SRobert Watson { 39927bc82500SRobert Watson 39937bc82500SRobert Watson return (ENOSYS); 39947bc82500SRobert Watson } 39957bc82500SRobert Watson 39967bc82500SRobert Watson int 39977bc82500SRobert Watson __mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 39987bc82500SRobert Watson { 39997bc82500SRobert Watson 40007bc82500SRobert Watson return (ENOSYS); 40017bc82500SRobert Watson } 40027bc82500SRobert Watson 40037bc82500SRobert Watson int 4004f7b951a8SRobert Watson __mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 4005f7b951a8SRobert Watson { 4006f7b951a8SRobert Watson 4007f7b951a8SRobert Watson return (ENOSYS); 4008f7b951a8SRobert Watson } 4009f7b951a8SRobert Watson 4010f7b951a8SRobert Watson int 40117bc82500SRobert Watson __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 40127bc82500SRobert Watson { 40137bc82500SRobert Watson 40147bc82500SRobert Watson return (ENOSYS); 40157bc82500SRobert Watson } 40167bc82500SRobert Watson 40177bc82500SRobert Watson int 40187bc82500SRobert Watson __mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 40197bc82500SRobert Watson { 40207bc82500SRobert Watson 40217bc82500SRobert Watson return (ENOSYS); 40227bc82500SRobert Watson } 402395fab37eSRobert Watson 402427f2eac7SRobert Watson int 4025f7b951a8SRobert Watson __mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 4026f7b951a8SRobert Watson { 4027f7b951a8SRobert Watson 4028f7b951a8SRobert Watson return (ENOSYS); 4029f7b951a8SRobert Watson } 4030f7b951a8SRobert Watson 4031f7b951a8SRobert Watson int 403227f2eac7SRobert Watson mac_syscall(struct thread *td, struct mac_syscall_args *uap) 403327f2eac7SRobert Watson { 403427f2eac7SRobert Watson 403527f2eac7SRobert Watson return (ENOSYS); 403627f2eac7SRobert Watson } 403727f2eac7SRobert Watson 4038f7b951a8SRobert Watson #endif 4039