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 * 106201265bSRobert Watson * This software was developed for the FreeBSD Project in part by Network 116201265bSRobert Watson * Associates Laboratories, the Security Research Division of Network 126201265bSRobert Watson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 136201265bSRobert Watson * as part of the DARPA CHATS research program. 147bc82500SRobert Watson * 157bc82500SRobert Watson * Redistribution and use in source and binary forms, with or without 167bc82500SRobert Watson * modification, are permitted provided that the following conditions 177bc82500SRobert Watson * are met: 187bc82500SRobert Watson * 1. Redistributions of source code must retain the above copyright 197bc82500SRobert Watson * notice, this list of conditions and the following disclaimer. 207bc82500SRobert Watson * 2. Redistributions in binary form must reproduce the above copyright 217bc82500SRobert Watson * notice, this list of conditions and the following disclaimer in the 227bc82500SRobert Watson * documentation and/or other materials provided with the distribution. 237bc82500SRobert Watson * 247bc82500SRobert Watson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 257bc82500SRobert Watson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 267bc82500SRobert Watson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 277bc82500SRobert Watson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 287bc82500SRobert Watson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 297bc82500SRobert Watson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 307bc82500SRobert Watson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 317bc82500SRobert Watson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 327bc82500SRobert Watson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 337bc82500SRobert Watson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 347bc82500SRobert Watson * SUCH DAMAGE. 357bc82500SRobert Watson * 367bc82500SRobert Watson * $FreeBSD$ 377bc82500SRobert Watson */ 387bc82500SRobert Watson /* 397bc82500SRobert Watson * Developed by the TrustedBSD Project. 407bc82500SRobert Watson * 417bc82500SRobert Watson * Framework for extensible kernel access control. Kernel and userland 427bc82500SRobert Watson * interface to the framework, policy registration and composition. 437bc82500SRobert Watson */ 447bc82500SRobert Watson 457bc82500SRobert Watson #include "opt_mac.h" 46328048bcSPoul-Henning Kamp #include "opt_devfs.h" 47f9d0d524SRobert Watson 487bc82500SRobert Watson #include <sys/param.h> 4995fab37eSRobert Watson #include <sys/extattr.h> 5095fab37eSRobert Watson #include <sys/kernel.h> 5195fab37eSRobert Watson #include <sys/lock.h> 52b656366bSBruce Evans #include <sys/malloc.h> 5395fab37eSRobert Watson #include <sys/mutex.h> 5495fab37eSRobert Watson #include <sys/mac.h> 557ba28492SRobert Watson #include <sys/module.h> 5695fab37eSRobert Watson #include <sys/proc.h> 5795fab37eSRobert Watson #include <sys/systm.h> 587bc82500SRobert Watson #include <sys/sysproto.h> 597bc82500SRobert Watson #include <sys/sysent.h> 6095fab37eSRobert Watson #include <sys/vnode.h> 6195fab37eSRobert Watson #include <sys/mount.h> 6295fab37eSRobert Watson #include <sys/file.h> 6395fab37eSRobert Watson #include <sys/namei.h> 6495fab37eSRobert Watson #include <sys/socket.h> 6595fab37eSRobert Watson #include <sys/pipe.h> 6695fab37eSRobert Watson #include <sys/socketvar.h> 6795fab37eSRobert Watson #include <sys/sysctl.h> 6895fab37eSRobert Watson 6995fab37eSRobert Watson #include <vm/vm.h> 7095fab37eSRobert Watson #include <vm/pmap.h> 7195fab37eSRobert Watson #include <vm/vm_map.h> 7295fab37eSRobert Watson #include <vm/vm_object.h> 7395fab37eSRobert Watson 7495fab37eSRobert Watson #include <sys/mac_policy.h> 7595fab37eSRobert Watson 7695fab37eSRobert Watson #include <fs/devfs/devfs.h> 7795fab37eSRobert Watson 7895fab37eSRobert Watson #include <net/bpfdesc.h> 7995fab37eSRobert Watson #include <net/if.h> 8095fab37eSRobert Watson #include <net/if_var.h> 8195fab37eSRobert Watson 8295fab37eSRobert Watson #include <netinet/in.h> 8395fab37eSRobert Watson #include <netinet/ip_var.h> 8495fab37eSRobert Watson 8595fab37eSRobert Watson #ifdef MAC 8695fab37eSRobert Watson 877ba28492SRobert Watson /* 887ba28492SRobert Watson * Declare that the kernel provides MAC support, version 1. This permits 897ba28492SRobert Watson * modules to refuse to be loaded if the necessary support isn't present, 907ba28492SRobert Watson * even if it's pre-boot. 917ba28492SRobert Watson */ 927ba28492SRobert Watson MODULE_VERSION(kernel_mac_support, 1); 937ba28492SRobert Watson 9495fab37eSRobert Watson SYSCTL_DECL(_security); 9595fab37eSRobert Watson 9695fab37eSRobert Watson SYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0, 9795fab37eSRobert Watson "TrustedBSD MAC policy controls"); 98b2f0927aSRobert Watson 9995fab37eSRobert Watson #if MAC_MAX_POLICIES > 32 10095fab37eSRobert Watson #error "MAC_MAX_POLICIES too large" 10195fab37eSRobert Watson #endif 102a13c67daSRobert Watson 10395fab37eSRobert Watson static unsigned int mac_max_policies = MAC_MAX_POLICIES; 10495fab37eSRobert Watson static unsigned int mac_policy_offsets_free = (1 << MAC_MAX_POLICIES) - 1; 10595fab37eSRobert Watson SYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD, 10695fab37eSRobert Watson &mac_max_policies, 0, ""); 10795fab37eSRobert Watson 108a67fe518SRobert Watson /* 109a67fe518SRobert Watson * Has the kernel started generating labeled objects yet? All read/write 110a67fe518SRobert Watson * access to this variable is serialized during the boot process. Following 111a67fe518SRobert Watson * the end of serialization, we don't update this flag; no locking. 112a67fe518SRobert Watson */ 11395fab37eSRobert Watson static int mac_late = 0; 11495fab37eSRobert Watson 115763bbd2fSRobert Watson /* 116763bbd2fSRobert Watson * Warn about EA transactions only the first time they happen. 117763bbd2fSRobert Watson * Weak coherency, no locking. 118763bbd2fSRobert Watson */ 119763bbd2fSRobert Watson static int ea_warn_once = 0; 120763bbd2fSRobert Watson 12195fab37eSRobert Watson static int mac_enforce_fs = 1; 12295fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW, 12395fab37eSRobert Watson &mac_enforce_fs, 0, "Enforce MAC policy on file system objects"); 12495fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs); 12595fab37eSRobert Watson 12695fab37eSRobert Watson static int mac_enforce_network = 1; 12795fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, 12895fab37eSRobert Watson &mac_enforce_network, 0, "Enforce MAC policy on network packets"); 12995fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); 13095fab37eSRobert Watson 131b88c98f6SRobert Watson static int mac_enforce_pipe = 1; 132b88c98f6SRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW, 133b88c98f6SRobert Watson &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations"); 134c031391bSRobert Watson TUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe); 135b88c98f6SRobert Watson 13695fab37eSRobert Watson static int mac_enforce_process = 1; 13795fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW, 13895fab37eSRobert Watson &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations"); 13995fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_process", &mac_enforce_process); 14095fab37eSRobert Watson 14195fab37eSRobert Watson static int mac_enforce_socket = 1; 14295fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 14395fab37eSRobert Watson &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 14495fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 14595fab37eSRobert Watson 1469e913ebdSRobert Watson static int mac_enforce_system = 1; 1479e913ebdSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_system, CTLFLAG_RW, 1489e913ebdSRobert Watson &mac_enforce_system, 0, "Enforce MAC policy on system operations"); 1499e913ebdSRobert Watson TUNABLE_INT("security.mac.enforce_system", &mac_enforce_system); 150d3fc69eeSRobert Watson 151ca7850c3SRobert Watson static int mac_enforce_vm = 1; 152ca7850c3SRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW, 153ca7850c3SRobert Watson &mac_enforce_vm, 0, "Enforce MAC policy on vm operations"); 154c031391bSRobert Watson TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm); 155ca7850c3SRobert Watson 15695fab37eSRobert Watson static int mac_cache_fslabel_in_vnode = 1; 15795fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW, 15895fab37eSRobert Watson &mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode"); 15995fab37eSRobert Watson TUNABLE_INT("security.mac.cache_fslabel_in_vnode", 16095fab37eSRobert Watson &mac_cache_fslabel_in_vnode); 16195fab37eSRobert Watson 162c0f39905SRobert Watson static int mac_mmap_revocation = 1; 163c0f39905SRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW, 164c0f39905SRobert Watson &mac_mmap_revocation, 0, "Revoke mmap access to files on subject " 165c0f39905SRobert Watson "relabel"); 16699fa64f8SRobert Watson static int mac_mmap_revocation_via_cow = 0; 16795fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW, 16895fab37eSRobert Watson &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via " 16995fab37eSRobert Watson "copy-on-write semantics, or by removing all write access"); 17095fab37eSRobert Watson 171f050add5SRobert Watson #ifdef MAC_DEBUG 1726be0c25eSRobert Watson SYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0, 1736be0c25eSRobert Watson "TrustedBSD MAC debug info"); 1746be0c25eSRobert Watson 1756be0c25eSRobert Watson static int mac_debug_label_fallback = 0; 1766be0c25eSRobert Watson SYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW, 1776be0c25eSRobert Watson &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label" 1786be0c25eSRobert Watson "when label is corrupted."); 1796be0c25eSRobert Watson TUNABLE_INT("security.mac.debug_label_fallback", 1806be0c25eSRobert Watson &mac_debug_label_fallback); 1816be0c25eSRobert Watson 182b2f0927aSRobert Watson SYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0, 183b2f0927aSRobert Watson "TrustedBSD MAC object counters"); 184b2f0927aSRobert Watson 18595fab37eSRobert Watson static unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs, 18695fab37eSRobert Watson nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents, 18795fab37eSRobert Watson nmacipqs, nmacpipes; 188b2f0927aSRobert Watson 189b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD, 19095fab37eSRobert Watson &nmacmbufs, 0, "number of mbufs in use"); 191b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD, 19295fab37eSRobert Watson &nmaccreds, 0, "number of ucreds in use"); 193b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD, 19495fab37eSRobert Watson &nmacifnets, 0, "number of ifnets in use"); 195b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD, 19695fab37eSRobert Watson &nmacipqs, 0, "number of ipqs in use"); 197b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD, 19895fab37eSRobert Watson &nmacbpfdescs, 0, "number of bpfdescs in use"); 199b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD, 20095fab37eSRobert Watson &nmacsockets, 0, "number of sockets in use"); 201b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, pipes, CTLFLAG_RD, 20295fab37eSRobert Watson &nmacpipes, 0, "number of pipes in use"); 203b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD, 20495fab37eSRobert Watson &nmacmounts, 0, "number of mounts in use"); 205b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD, 20695fab37eSRobert Watson &nmactemp, 0, "number of temporary labels in use"); 207b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD, 20895fab37eSRobert Watson &nmacvnodes, 0, "number of vnodes in use"); 209b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD, 21095fab37eSRobert Watson &nmacdevfsdirents, 0, "number of devfs dirents inuse"); 211f050add5SRobert Watson #endif 21295fab37eSRobert Watson 21395fab37eSRobert Watson static int error_select(int error1, int error2); 21495fab37eSRobert Watson static int mac_policy_register(struct mac_policy_conf *mpc); 21595fab37eSRobert Watson static int mac_policy_unregister(struct mac_policy_conf *mpc); 21695fab37eSRobert Watson 217e183f80eSRobert Watson static void mac_check_vnode_mmap_downgrade(struct ucred *cred, 218e183f80eSRobert Watson struct vnode *vp, int *prot); 21995fab37eSRobert Watson static void mac_cred_mmapped_drop_perms_recurse(struct thread *td, 22095fab37eSRobert Watson struct ucred *cred, struct vm_map *map); 22195fab37eSRobert Watson 22283985c26SRobert Watson static void mac_destroy_socket_label(struct label *label); 22383985c26SRobert Watson 224763bbd2fSRobert Watson static int mac_setlabel_vnode_extattr(struct ucred *cred, 225763bbd2fSRobert Watson struct vnode *vp, struct label *intlabel); 226763bbd2fSRobert Watson 227763bbd2fSRobert Watson 22895fab37eSRobert Watson MALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector"); 22995fab37eSRobert Watson MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes"); 230f7b951a8SRobert Watson MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage"); 23195fab37eSRobert Watson 23295fab37eSRobert Watson /* 23395fab37eSRobert Watson * mac_policy_list_lock protects the consistency of 'mac_policy_list', 23495fab37eSRobert Watson * the linked list of attached policy modules. Read-only consumers of 23595fab37eSRobert Watson * the list must acquire a shared lock for the duration of their use; 23695fab37eSRobert Watson * writers must acquire an exclusive lock. Note that for compound 23795fab37eSRobert Watson * operations, locks should be held for the entire compound operation, 23895fab37eSRobert Watson * and that this is not yet done for relabel requests. 23995fab37eSRobert Watson */ 24095fab37eSRobert Watson static struct mtx mac_policy_list_lock; 24195fab37eSRobert Watson static LIST_HEAD(, mac_policy_conf) mac_policy_list; 24295fab37eSRobert Watson static int mac_policy_list_busy; 24395fab37eSRobert Watson #define MAC_POLICY_LIST_LOCKINIT() mtx_init(&mac_policy_list_lock, \ 24495fab37eSRobert Watson "mac_policy_list_lock", NULL, MTX_DEF); 24595fab37eSRobert Watson #define MAC_POLICY_LIST_LOCK() mtx_lock(&mac_policy_list_lock); 24695fab37eSRobert Watson #define MAC_POLICY_LIST_UNLOCK() mtx_unlock(&mac_policy_list_lock); 24795fab37eSRobert Watson 24895fab37eSRobert Watson #define MAC_POLICY_LIST_BUSY() do { \ 24995fab37eSRobert Watson MAC_POLICY_LIST_LOCK(); \ 25095fab37eSRobert Watson mac_policy_list_busy++; \ 25195fab37eSRobert Watson MAC_POLICY_LIST_UNLOCK(); \ 25295fab37eSRobert Watson } while (0) 25395fab37eSRobert Watson 25495fab37eSRobert Watson #define MAC_POLICY_LIST_UNBUSY() do { \ 25595fab37eSRobert Watson MAC_POLICY_LIST_LOCK(); \ 25695fab37eSRobert Watson mac_policy_list_busy--; \ 25795fab37eSRobert Watson if (mac_policy_list_busy < 0) \ 25895fab37eSRobert Watson panic("Extra mac_policy_list_busy--"); \ 25995fab37eSRobert Watson MAC_POLICY_LIST_UNLOCK(); \ 26095fab37eSRobert Watson } while (0) 26195fab37eSRobert Watson 26295fab37eSRobert Watson /* 26395fab37eSRobert Watson * MAC_CHECK performs the designated check by walking the policy 26495fab37eSRobert Watson * module list and checking with each as to how it feels about the 26595fab37eSRobert Watson * request. Note that it returns its value via 'error' in the scope 26695fab37eSRobert Watson * of the caller. 26795fab37eSRobert Watson */ 26895fab37eSRobert Watson #define MAC_CHECK(check, args...) do { \ 26995fab37eSRobert Watson struct mac_policy_conf *mpc; \ 27095fab37eSRobert Watson \ 27195fab37eSRobert Watson error = 0; \ 27295fab37eSRobert Watson MAC_POLICY_LIST_BUSY(); \ 27395fab37eSRobert Watson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 27495fab37eSRobert Watson if (mpc->mpc_ops->mpo_ ## check != NULL) \ 27595fab37eSRobert Watson error = error_select( \ 27695fab37eSRobert Watson mpc->mpc_ops->mpo_ ## check (args), \ 27795fab37eSRobert Watson error); \ 27895fab37eSRobert Watson } \ 27995fab37eSRobert Watson MAC_POLICY_LIST_UNBUSY(); \ 28095fab37eSRobert Watson } while (0) 28195fab37eSRobert Watson 28295fab37eSRobert Watson /* 28395fab37eSRobert Watson * MAC_BOOLEAN performs the designated boolean composition by walking 28495fab37eSRobert Watson * the module list, invoking each instance of the operation, and 28595fab37eSRobert Watson * combining the results using the passed C operator. Note that it 28695fab37eSRobert Watson * returns its value via 'result' in the scope of the caller, which 28795fab37eSRobert Watson * should be initialized by the caller in a meaningful way to get 28895fab37eSRobert Watson * a meaningful result. 28995fab37eSRobert Watson */ 29095fab37eSRobert Watson #define MAC_BOOLEAN(operation, composition, args...) do { \ 29195fab37eSRobert Watson struct mac_policy_conf *mpc; \ 29295fab37eSRobert Watson \ 29395fab37eSRobert Watson MAC_POLICY_LIST_BUSY(); \ 29495fab37eSRobert Watson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 29595fab37eSRobert Watson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 29695fab37eSRobert Watson result = result composition \ 29795fab37eSRobert Watson mpc->mpc_ops->mpo_ ## operation (args); \ 29895fab37eSRobert Watson } \ 29995fab37eSRobert Watson MAC_POLICY_LIST_UNBUSY(); \ 30095fab37eSRobert Watson } while (0) 30195fab37eSRobert Watson 302f7b951a8SRobert Watson #define MAC_EXTERNALIZE(type, label, elementlist, outbuf, \ 303f7b951a8SRobert Watson outbuflen) do { \ 304f7b951a8SRobert Watson char *curptr, *curptr_start, *element_name, *element_temp; \ 305f7b951a8SRobert Watson size_t left, left_start, len; \ 306f7b951a8SRobert Watson int claimed, first, first_start, ignorenotfound; \ 307f7b951a8SRobert Watson \ 308f7b951a8SRobert Watson error = 0; \ 309f7b951a8SRobert Watson element_temp = elementlist; \ 310f7b951a8SRobert Watson curptr = outbuf; \ 311f7b951a8SRobert Watson curptr[0] = '\0'; \ 312f7b951a8SRobert Watson left = outbuflen; \ 313f7b951a8SRobert Watson first = 1; \ 314f7b951a8SRobert Watson while ((element_name = strsep(&element_temp, ",")) != NULL) { \ 315f7b951a8SRobert Watson curptr_start = curptr; \ 316f7b951a8SRobert Watson left_start = left; \ 317f7b951a8SRobert Watson first_start = first; \ 318f7b951a8SRobert Watson if (element_name[0] == '?') { \ 319f7b951a8SRobert Watson element_name++; \ 320f7b951a8SRobert Watson ignorenotfound = 1; \ 321f7b951a8SRobert Watson } else \ 322f7b951a8SRobert Watson ignorenotfound = 0; \ 323f7b951a8SRobert Watson claimed = 0; \ 324f7b951a8SRobert Watson if (first) { \ 325f7b951a8SRobert Watson len = snprintf(curptr, left, "%s/", \ 326f7b951a8SRobert Watson element_name); \ 327f7b951a8SRobert Watson first = 0; \ 328f7b951a8SRobert Watson } else \ 329f7b951a8SRobert Watson len = snprintf(curptr, left, ",%s/", \ 330f7b951a8SRobert Watson element_name); \ 331f7b951a8SRobert Watson if (len >= left) { \ 332f7b951a8SRobert Watson error = EINVAL; /* XXXMAC: E2BIG */ \ 333f7b951a8SRobert Watson break; \ 334f7b951a8SRobert Watson } \ 335f7b951a8SRobert Watson curptr += len; \ 336f7b951a8SRobert Watson left -= len; \ 337f7b951a8SRobert Watson \ 338f7b951a8SRobert Watson MAC_CHECK(externalize_ ## type, label, element_name, \ 339f7b951a8SRobert Watson curptr, left, &len, &claimed); \ 340f7b951a8SRobert Watson if (error) \ 341f7b951a8SRobert Watson break; \ 342f7b951a8SRobert Watson if (claimed == 1) { \ 343f7b951a8SRobert Watson if (len >= outbuflen) { \ 344f7b951a8SRobert Watson error = EINVAL; /* XXXMAC: E2BIG */ \ 345f7b951a8SRobert Watson break; \ 346f7b951a8SRobert Watson } \ 347f7b951a8SRobert Watson curptr += len; \ 348f7b951a8SRobert Watson left -= len; \ 349f7b951a8SRobert Watson } else if (claimed == 0 && ignorenotfound) { \ 350f7b951a8SRobert Watson /* \ 351f7b951a8SRobert Watson * Revert addition of the label element \ 352f7b951a8SRobert Watson * name. \ 353f7b951a8SRobert Watson */ \ 354f7b951a8SRobert Watson curptr = curptr_start; \ 355f7b951a8SRobert Watson *curptr = '\0'; \ 356f7b951a8SRobert Watson left = left_start; \ 357f7b951a8SRobert Watson first = first_start; \ 358f7b951a8SRobert Watson } else { \ 359f7b951a8SRobert Watson error = EINVAL; /* XXXMAC: ENOLABEL */ \ 360f7b951a8SRobert Watson break; \ 361f7b951a8SRobert Watson } \ 362f7b951a8SRobert Watson } \ 363f7b951a8SRobert Watson } while (0) 364f7b951a8SRobert Watson 365f7b951a8SRobert Watson #define MAC_INTERNALIZE(type, label, instring) do { \ 366f7b951a8SRobert Watson char *element, *element_name, *element_data; \ 367f7b951a8SRobert Watson int claimed; \ 368f7b951a8SRobert Watson \ 369f7b951a8SRobert Watson error = 0; \ 370f7b951a8SRobert Watson element = instring; \ 371f7b951a8SRobert Watson while ((element_name = strsep(&element, ",")) != NULL) { \ 372f7b951a8SRobert Watson element_data = element_name; \ 373f7b951a8SRobert Watson element_name = strsep(&element_data, "/"); \ 374f7b951a8SRobert Watson if (element_data == NULL) { \ 375f7b951a8SRobert Watson error = EINVAL; \ 376f7b951a8SRobert Watson break; \ 377f7b951a8SRobert Watson } \ 378f7b951a8SRobert Watson claimed = 0; \ 379f7b951a8SRobert Watson MAC_CHECK(internalize_ ## type, label, element_name, \ 380f7b951a8SRobert Watson element_data, &claimed); \ 381f7b951a8SRobert Watson if (error) \ 382f7b951a8SRobert Watson break; \ 383f7b951a8SRobert Watson if (claimed != 1) { \ 384f7b951a8SRobert Watson /* XXXMAC: Another error here? */ \ 385f7b951a8SRobert Watson error = EINVAL; \ 386f7b951a8SRobert Watson break; \ 387f7b951a8SRobert Watson } \ 388f7b951a8SRobert Watson } \ 389f7b951a8SRobert Watson } while (0) 390f7b951a8SRobert Watson 39195fab37eSRobert Watson /* 39295fab37eSRobert Watson * MAC_PERFORM performs the designated operation by walking the policy 39395fab37eSRobert Watson * module list and invoking that operation for each policy. 39495fab37eSRobert Watson */ 39595fab37eSRobert Watson #define MAC_PERFORM(operation, args...) do { \ 39695fab37eSRobert Watson struct mac_policy_conf *mpc; \ 39795fab37eSRobert Watson \ 39895fab37eSRobert Watson MAC_POLICY_LIST_BUSY(); \ 39995fab37eSRobert Watson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 40095fab37eSRobert Watson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 40195fab37eSRobert Watson mpc->mpc_ops->mpo_ ## operation (args); \ 40295fab37eSRobert Watson } \ 40395fab37eSRobert Watson MAC_POLICY_LIST_UNBUSY(); \ 40495fab37eSRobert Watson } while (0) 40595fab37eSRobert Watson 40695fab37eSRobert Watson /* 40795fab37eSRobert Watson * Initialize the MAC subsystem, including appropriate SMP locks. 40895fab37eSRobert Watson */ 40995fab37eSRobert Watson static void 41095fab37eSRobert Watson mac_init(void) 41195fab37eSRobert Watson { 41295fab37eSRobert Watson 41395fab37eSRobert Watson LIST_INIT(&mac_policy_list); 41495fab37eSRobert Watson MAC_POLICY_LIST_LOCKINIT(); 41595fab37eSRobert Watson } 41695fab37eSRobert Watson 41795fab37eSRobert Watson /* 41895fab37eSRobert Watson * For the purposes of modules that want to know if they were loaded 41995fab37eSRobert Watson * "early", set the mac_late flag once we've processed modules either 42095fab37eSRobert Watson * linked into the kernel, or loaded before the kernel startup. 42195fab37eSRobert Watson */ 42295fab37eSRobert Watson static void 42395fab37eSRobert Watson mac_late_init(void) 42495fab37eSRobert Watson { 42595fab37eSRobert Watson 42695fab37eSRobert Watson mac_late = 1; 42795fab37eSRobert Watson } 42895fab37eSRobert Watson 42995fab37eSRobert Watson /* 43095fab37eSRobert Watson * Allow MAC policy modules to register during boot, etc. 43195fab37eSRobert Watson */ 43295fab37eSRobert Watson int 43395fab37eSRobert Watson mac_policy_modevent(module_t mod, int type, void *data) 43495fab37eSRobert Watson { 43595fab37eSRobert Watson struct mac_policy_conf *mpc; 43695fab37eSRobert Watson int error; 43795fab37eSRobert Watson 43895fab37eSRobert Watson error = 0; 43995fab37eSRobert Watson mpc = (struct mac_policy_conf *) data; 44095fab37eSRobert Watson 44195fab37eSRobert Watson switch (type) { 44295fab37eSRobert Watson case MOD_LOAD: 44395fab37eSRobert Watson if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && 44495fab37eSRobert Watson mac_late) { 44595fab37eSRobert Watson printf("mac_policy_modevent: can't load %s policy " 44695fab37eSRobert Watson "after booting\n", mpc->mpc_name); 44795fab37eSRobert Watson error = EBUSY; 44895fab37eSRobert Watson break; 44995fab37eSRobert Watson } 45095fab37eSRobert Watson error = mac_policy_register(mpc); 45195fab37eSRobert Watson break; 45295fab37eSRobert Watson case MOD_UNLOAD: 45395fab37eSRobert Watson /* Don't unregister the module if it was never registered. */ 45495fab37eSRobert Watson if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) 45595fab37eSRobert Watson != 0) 45695fab37eSRobert Watson error = mac_policy_unregister(mpc); 45795fab37eSRobert Watson else 45895fab37eSRobert Watson error = 0; 45995fab37eSRobert Watson break; 46095fab37eSRobert Watson default: 46195fab37eSRobert Watson break; 46295fab37eSRobert Watson } 46395fab37eSRobert Watson 46495fab37eSRobert Watson return (error); 46595fab37eSRobert Watson } 46695fab37eSRobert Watson 46795fab37eSRobert Watson static int 46895fab37eSRobert Watson mac_policy_register(struct mac_policy_conf *mpc) 46995fab37eSRobert Watson { 47095fab37eSRobert Watson struct mac_policy_conf *tmpc; 47195fab37eSRobert Watson int slot; 47295fab37eSRobert Watson 47395fab37eSRobert Watson MAC_POLICY_LIST_LOCK(); 47495fab37eSRobert Watson if (mac_policy_list_busy > 0) { 47595fab37eSRobert Watson MAC_POLICY_LIST_UNLOCK(); 47695fab37eSRobert Watson return (EBUSY); 47795fab37eSRobert Watson } 47895fab37eSRobert Watson LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 47995fab37eSRobert Watson if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 48095fab37eSRobert Watson MAC_POLICY_LIST_UNLOCK(); 48195fab37eSRobert Watson return (EEXIST); 48295fab37eSRobert Watson } 48395fab37eSRobert Watson } 48495fab37eSRobert Watson if (mpc->mpc_field_off != NULL) { 48595fab37eSRobert Watson slot = ffs(mac_policy_offsets_free); 48695fab37eSRobert Watson if (slot == 0) { 48795fab37eSRobert Watson MAC_POLICY_LIST_UNLOCK(); 48895fab37eSRobert Watson return (ENOMEM); 48995fab37eSRobert Watson } 49095fab37eSRobert Watson slot--; 49195fab37eSRobert Watson mac_policy_offsets_free &= ~(1 << slot); 49295fab37eSRobert Watson *mpc->mpc_field_off = slot; 49395fab37eSRobert Watson } 49495fab37eSRobert Watson mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; 49595fab37eSRobert Watson LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); 49695fab37eSRobert Watson 49795fab37eSRobert Watson /* Per-policy initialization. */ 49895fab37eSRobert Watson if (mpc->mpc_ops->mpo_init != NULL) 49995fab37eSRobert Watson (*(mpc->mpc_ops->mpo_init))(mpc); 50095fab37eSRobert Watson MAC_POLICY_LIST_UNLOCK(); 50195fab37eSRobert Watson 50295fab37eSRobert Watson printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, 50395fab37eSRobert Watson mpc->mpc_name); 50495fab37eSRobert Watson 50595fab37eSRobert Watson return (0); 50695fab37eSRobert Watson } 50795fab37eSRobert Watson 50895fab37eSRobert Watson static int 50995fab37eSRobert Watson mac_policy_unregister(struct mac_policy_conf *mpc) 51095fab37eSRobert Watson { 51195fab37eSRobert Watson 512ea599aa0SRobert Watson /* 513ea599aa0SRobert Watson * If we fail the load, we may get a request to unload. Check 514ea599aa0SRobert Watson * to see if we did the run-time registration, and if not, 515ea599aa0SRobert Watson * silently succeed. 516ea599aa0SRobert Watson */ 517ea599aa0SRobert Watson MAC_POLICY_LIST_LOCK(); 518ea599aa0SRobert Watson if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) { 519ea599aa0SRobert Watson MAC_POLICY_LIST_UNLOCK(); 520ea599aa0SRobert Watson return (0); 521ea599aa0SRobert Watson } 52295fab37eSRobert Watson #if 0 52395fab37eSRobert Watson /* 52495fab37eSRobert Watson * Don't allow unloading modules with private data. 52595fab37eSRobert Watson */ 526ea599aa0SRobert Watson if (mpc->mpc_field_off != NULL) { 527ea599aa0SRobert Watson MAC_POLICY_LIST_UNLOCK(); 52895fab37eSRobert Watson return (EBUSY); 529ea599aa0SRobert Watson } 53095fab37eSRobert Watson #endif 531ea599aa0SRobert Watson /* 532ea599aa0SRobert Watson * Only allow the unload to proceed if the module is unloadable 533ea599aa0SRobert Watson * by its own definition. 534ea599aa0SRobert Watson */ 535ea599aa0SRobert Watson if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) { 536ea599aa0SRobert Watson MAC_POLICY_LIST_UNLOCK(); 53795fab37eSRobert Watson return (EBUSY); 538ea599aa0SRobert Watson } 539ea599aa0SRobert Watson /* 540ea599aa0SRobert Watson * Right now, we EBUSY if the list is in use. In the future, 541ea599aa0SRobert Watson * for reliability reasons, we might want to sleep and wakeup 542ea599aa0SRobert Watson * later to try again. 543ea599aa0SRobert Watson */ 54495fab37eSRobert Watson if (mac_policy_list_busy > 0) { 54595fab37eSRobert Watson MAC_POLICY_LIST_UNLOCK(); 54695fab37eSRobert Watson return (EBUSY); 54795fab37eSRobert Watson } 54895fab37eSRobert Watson if (mpc->mpc_ops->mpo_destroy != NULL) 54995fab37eSRobert Watson (*(mpc->mpc_ops->mpo_destroy))(mpc); 55095fab37eSRobert Watson 55195fab37eSRobert Watson LIST_REMOVE(mpc, mpc_list); 55295fab37eSRobert Watson MAC_POLICY_LIST_UNLOCK(); 55395fab37eSRobert Watson 5549aeffb2bSRobert Watson mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED; 55595fab37eSRobert Watson 55695fab37eSRobert Watson printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, 55795fab37eSRobert Watson mpc->mpc_name); 55895fab37eSRobert Watson 55995fab37eSRobert Watson return (0); 56095fab37eSRobert Watson } 56195fab37eSRobert Watson 56295fab37eSRobert Watson /* 56395fab37eSRobert Watson * Define an error value precedence, and given two arguments, selects the 56495fab37eSRobert Watson * value with the higher precedence. 56595fab37eSRobert Watson */ 56695fab37eSRobert Watson static int 56795fab37eSRobert Watson error_select(int error1, int error2) 56895fab37eSRobert Watson { 56995fab37eSRobert Watson 57095fab37eSRobert Watson /* Certain decision-making errors take top priority. */ 57195fab37eSRobert Watson if (error1 == EDEADLK || error2 == EDEADLK) 57295fab37eSRobert Watson return (EDEADLK); 57395fab37eSRobert Watson 57495fab37eSRobert Watson /* Invalid arguments should be reported where possible. */ 57595fab37eSRobert Watson if (error1 == EINVAL || error2 == EINVAL) 57695fab37eSRobert Watson return (EINVAL); 57795fab37eSRobert Watson 57895fab37eSRobert Watson /* Precedence goes to "visibility", with both process and file. */ 57995fab37eSRobert Watson if (error1 == ESRCH || error2 == ESRCH) 58095fab37eSRobert Watson return (ESRCH); 58195fab37eSRobert Watson 58295fab37eSRobert Watson if (error1 == ENOENT || error2 == ENOENT) 58395fab37eSRobert Watson return (ENOENT); 58495fab37eSRobert Watson 58595fab37eSRobert Watson /* Precedence goes to DAC/MAC protections. */ 58695fab37eSRobert Watson if (error1 == EACCES || error2 == EACCES) 58795fab37eSRobert Watson return (EACCES); 58895fab37eSRobert Watson 58995fab37eSRobert Watson /* Precedence goes to privilege. */ 59095fab37eSRobert Watson if (error1 == EPERM || error2 == EPERM) 59195fab37eSRobert Watson return (EPERM); 59295fab37eSRobert Watson 59395fab37eSRobert Watson /* Precedence goes to error over success; otherwise, arbitrary. */ 59495fab37eSRobert Watson if (error1 != 0) 59595fab37eSRobert Watson return (error1); 59695fab37eSRobert Watson return (error2); 59795fab37eSRobert Watson } 59895fab37eSRobert Watson 59908bcdc58SRobert Watson static void 60008bcdc58SRobert Watson mac_init_label(struct label *label) 60108bcdc58SRobert Watson { 60208bcdc58SRobert Watson 60308bcdc58SRobert Watson bzero(label, sizeof(*label)); 60408bcdc58SRobert Watson label->l_flags = MAC_FLAG_INITIALIZED; 60508bcdc58SRobert Watson } 60608bcdc58SRobert Watson 60708bcdc58SRobert Watson static void 60808bcdc58SRobert Watson mac_destroy_label(struct label *label) 60908bcdc58SRobert Watson { 61008bcdc58SRobert Watson 61108bcdc58SRobert Watson KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 61208bcdc58SRobert Watson ("destroying uninitialized label")); 61308bcdc58SRobert Watson 61408bcdc58SRobert Watson bzero(label, sizeof(*label)); 61508bcdc58SRobert Watson /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 61608bcdc58SRobert Watson } 61708bcdc58SRobert Watson 61808bcdc58SRobert Watson void 61987807196SRobert Watson mac_init_bpfdesc(struct bpf_d *bpf_d) 62008bcdc58SRobert Watson { 62108bcdc58SRobert Watson 62287807196SRobert Watson mac_init_label(&bpf_d->bd_label); 62387807196SRobert Watson MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label); 62408bcdc58SRobert Watson #ifdef MAC_DEBUG 62587807196SRobert Watson atomic_add_int(&nmacbpfdescs, 1); 62608bcdc58SRobert Watson #endif 62708bcdc58SRobert Watson } 62808bcdc58SRobert Watson 629f7b951a8SRobert Watson static void 630f7b951a8SRobert Watson mac_init_cred_label(struct label *label) 63108bcdc58SRobert Watson { 63208bcdc58SRobert Watson 633f7b951a8SRobert Watson mac_init_label(label); 634f7b951a8SRobert Watson MAC_PERFORM(init_cred_label, label); 63508bcdc58SRobert Watson #ifdef MAC_DEBUG 63608bcdc58SRobert Watson atomic_add_int(&nmaccreds, 1); 63708bcdc58SRobert Watson #endif 63808bcdc58SRobert Watson } 63908bcdc58SRobert Watson 64008bcdc58SRobert Watson void 641f7b951a8SRobert Watson mac_init_cred(struct ucred *cred) 642f7b951a8SRobert Watson { 643f7b951a8SRobert Watson 644f7b951a8SRobert Watson mac_init_cred_label(&cred->cr_label); 645f7b951a8SRobert Watson } 646f7b951a8SRobert Watson 647f7b951a8SRobert Watson void 64887807196SRobert Watson mac_init_devfsdirent(struct devfs_dirent *de) 64908bcdc58SRobert Watson { 65008bcdc58SRobert Watson 65187807196SRobert Watson mac_init_label(&de->de_label); 65287807196SRobert Watson MAC_PERFORM(init_devfsdirent_label, &de->de_label); 65308bcdc58SRobert Watson #ifdef MAC_DEBUG 65487807196SRobert Watson atomic_add_int(&nmacdevfsdirents, 1); 65508bcdc58SRobert Watson #endif 65608bcdc58SRobert Watson } 65708bcdc58SRobert Watson 658f7b951a8SRobert Watson static void 659f7b951a8SRobert Watson mac_init_ifnet_label(struct label *label) 660f7b951a8SRobert Watson { 661f7b951a8SRobert Watson 662f7b951a8SRobert Watson mac_init_label(label); 663f7b951a8SRobert Watson MAC_PERFORM(init_ifnet_label, label); 664f7b951a8SRobert Watson #ifdef MAC_DEBUG 665f7b951a8SRobert Watson atomic_add_int(&nmacifnets, 1); 666f7b951a8SRobert Watson #endif 667f7b951a8SRobert Watson } 668f7b951a8SRobert Watson 66908bcdc58SRobert Watson void 67008bcdc58SRobert Watson mac_init_ifnet(struct ifnet *ifp) 67108bcdc58SRobert Watson { 67208bcdc58SRobert Watson 673f7b951a8SRobert Watson mac_init_ifnet_label(&ifp->if_label); 67408bcdc58SRobert Watson } 67508bcdc58SRobert Watson 67608bcdc58SRobert Watson void 67708bcdc58SRobert Watson mac_init_ipq(struct ipq *ipq) 67808bcdc58SRobert Watson { 67908bcdc58SRobert Watson 68008bcdc58SRobert Watson mac_init_label(&ipq->ipq_label); 68108bcdc58SRobert Watson MAC_PERFORM(init_ipq_label, &ipq->ipq_label); 68208bcdc58SRobert Watson #ifdef MAC_DEBUG 68308bcdc58SRobert Watson atomic_add_int(&nmacipqs, 1); 68408bcdc58SRobert Watson #endif 68508bcdc58SRobert Watson } 68608bcdc58SRobert Watson 68787807196SRobert Watson int 68887807196SRobert Watson mac_init_mbuf(struct mbuf *m, int flag) 68908bcdc58SRobert Watson { 69056c15412SRobert Watson int error; 69156c15412SRobert Watson 69287807196SRobert Watson KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf")); 69308bcdc58SRobert Watson 69487807196SRobert Watson mac_init_label(&m->m_pkthdr.label); 69587807196SRobert Watson 69656c15412SRobert Watson MAC_CHECK(init_mbuf_label, &m->m_pkthdr.label, flag); 69756c15412SRobert Watson if (error) { 69856c15412SRobert Watson MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 69956c15412SRobert Watson mac_destroy_label(&m->m_pkthdr.label); 70056c15412SRobert Watson } 70156c15412SRobert Watson 70208bcdc58SRobert Watson #ifdef MAC_DEBUG 70356c15412SRobert Watson if (error == 0) 70487807196SRobert Watson atomic_add_int(&nmacmbufs, 1); 70508bcdc58SRobert Watson #endif 70656c15412SRobert Watson return (error); 70708bcdc58SRobert Watson } 70808bcdc58SRobert Watson 70908bcdc58SRobert Watson void 71087807196SRobert Watson mac_init_mount(struct mount *mp) 71108bcdc58SRobert Watson { 71208bcdc58SRobert Watson 71387807196SRobert Watson mac_init_label(&mp->mnt_mntlabel); 71487807196SRobert Watson mac_init_label(&mp->mnt_fslabel); 71587807196SRobert Watson MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel); 71687807196SRobert Watson MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel); 71708bcdc58SRobert Watson #ifdef MAC_DEBUG 71887807196SRobert Watson atomic_add_int(&nmacmounts, 1); 71908bcdc58SRobert Watson #endif 72008bcdc58SRobert Watson } 72108bcdc58SRobert Watson 722f7b951a8SRobert Watson static void 723f7b951a8SRobert Watson mac_init_pipe_label(struct label *label) 724f7b951a8SRobert Watson { 725f7b951a8SRobert Watson 726f7b951a8SRobert Watson mac_init_label(label); 727f7b951a8SRobert Watson MAC_PERFORM(init_pipe_label, label); 728f7b951a8SRobert Watson #ifdef MAC_DEBUG 729f7b951a8SRobert Watson atomic_add_int(&nmacpipes, 1); 730f7b951a8SRobert Watson #endif 731f7b951a8SRobert Watson } 732f7b951a8SRobert Watson 73308bcdc58SRobert Watson void 73408bcdc58SRobert Watson mac_init_pipe(struct pipe *pipe) 73508bcdc58SRobert Watson { 73608bcdc58SRobert Watson struct label *label; 73708bcdc58SRobert Watson 73808bcdc58SRobert Watson label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 73908bcdc58SRobert Watson pipe->pipe_label = label; 74008bcdc58SRobert Watson pipe->pipe_peer->pipe_label = label; 741f7b951a8SRobert Watson mac_init_pipe_label(label); 74208bcdc58SRobert Watson } 74308bcdc58SRobert Watson 74483985c26SRobert Watson static int 74583985c26SRobert Watson mac_init_socket_label(struct label *label, int flag) 74608bcdc58SRobert Watson { 74783985c26SRobert Watson int error; 74808bcdc58SRobert Watson 74983985c26SRobert Watson mac_init_label(label); 75083985c26SRobert Watson 75183985c26SRobert Watson MAC_CHECK(init_socket_label, label, flag); 75283985c26SRobert Watson if (error) { 75383985c26SRobert Watson MAC_PERFORM(destroy_socket_label, label); 75483985c26SRobert Watson mac_destroy_label(label); 75583985c26SRobert Watson } 75683985c26SRobert Watson 75708bcdc58SRobert Watson #ifdef MAC_DEBUG 75883985c26SRobert Watson if (error == 0) 75987807196SRobert Watson atomic_add_int(&nmacsockets, 1); 76087807196SRobert Watson #endif 76183985c26SRobert Watson 76283985c26SRobert Watson return (error); 76383985c26SRobert Watson } 76483985c26SRobert Watson 76583985c26SRobert Watson static int 76683985c26SRobert Watson mac_init_socket_peer_label(struct label *label, int flag) 76783985c26SRobert Watson { 76883985c26SRobert Watson int error; 76983985c26SRobert Watson 77083985c26SRobert Watson mac_init_label(label); 77183985c26SRobert Watson 77283985c26SRobert Watson MAC_CHECK(init_socket_peer_label, label, flag); 77383985c26SRobert Watson if (error) { 77483985c26SRobert Watson MAC_PERFORM(destroy_socket_label, label); 77583985c26SRobert Watson mac_destroy_label(label); 77683985c26SRobert Watson } 77783985c26SRobert Watson 77883985c26SRobert Watson return (error); 77983985c26SRobert Watson } 78083985c26SRobert Watson 78183985c26SRobert Watson int 78283985c26SRobert Watson mac_init_socket(struct socket *socket, int flag) 78383985c26SRobert Watson { 78483985c26SRobert Watson int error; 78583985c26SRobert Watson 78683985c26SRobert Watson error = mac_init_socket_label(&socket->so_label, flag); 78783985c26SRobert Watson if (error) 78883985c26SRobert Watson return (error); 78983985c26SRobert Watson 79083985c26SRobert Watson error = mac_init_socket_peer_label(&socket->so_peerlabel, flag); 79183985c26SRobert Watson if (error) 79283985c26SRobert Watson mac_destroy_socket_label(&socket->so_label); 79383985c26SRobert Watson 79483985c26SRobert Watson return (error); 79587807196SRobert Watson } 79687807196SRobert Watson 797763bbd2fSRobert Watson void 798f7b951a8SRobert Watson mac_init_vnode_label(struct label *label) 79987807196SRobert Watson { 80087807196SRobert Watson 80187807196SRobert Watson mac_init_label(label); 802f7b951a8SRobert Watson MAC_PERFORM(init_vnode_label, label); 80387807196SRobert Watson #ifdef MAC_DEBUG 804f7b951a8SRobert Watson atomic_add_int(&nmacvnodes, 1); 80508bcdc58SRobert Watson #endif 80608bcdc58SRobert Watson } 80708bcdc58SRobert Watson 80808bcdc58SRobert Watson void 80987807196SRobert Watson mac_init_vnode(struct vnode *vp) 81008bcdc58SRobert Watson { 81108bcdc58SRobert Watson 812f7b951a8SRobert Watson mac_init_vnode_label(&vp->v_label); 81308bcdc58SRobert Watson } 81408bcdc58SRobert Watson 81508bcdc58SRobert Watson void 81608bcdc58SRobert Watson mac_destroy_bpfdesc(struct bpf_d *bpf_d) 81708bcdc58SRobert Watson { 81808bcdc58SRobert Watson 81908bcdc58SRobert Watson MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label); 82008bcdc58SRobert Watson mac_destroy_label(&bpf_d->bd_label); 82108bcdc58SRobert Watson #ifdef MAC_DEBUG 82208bcdc58SRobert Watson atomic_subtract_int(&nmacbpfdescs, 1); 82308bcdc58SRobert Watson #endif 82408bcdc58SRobert Watson } 82508bcdc58SRobert Watson 826f7b951a8SRobert Watson static void 827f7b951a8SRobert Watson mac_destroy_cred_label(struct label *label) 82808bcdc58SRobert Watson { 82908bcdc58SRobert Watson 830f7b951a8SRobert Watson MAC_PERFORM(destroy_cred_label, label); 831f7b951a8SRobert Watson mac_destroy_label(label); 83208bcdc58SRobert Watson #ifdef MAC_DEBUG 83387807196SRobert Watson atomic_subtract_int(&nmaccreds, 1); 83487807196SRobert Watson #endif 83587807196SRobert Watson } 83687807196SRobert Watson 83787807196SRobert Watson void 838f7b951a8SRobert Watson mac_destroy_cred(struct ucred *cred) 839f7b951a8SRobert Watson { 840f7b951a8SRobert Watson 841f7b951a8SRobert Watson mac_destroy_cred_label(&cred->cr_label); 842f7b951a8SRobert Watson } 843f7b951a8SRobert Watson 844f7b951a8SRobert Watson void 84587807196SRobert Watson mac_destroy_devfsdirent(struct devfs_dirent *de) 84687807196SRobert Watson { 84787807196SRobert Watson 84887807196SRobert Watson MAC_PERFORM(destroy_devfsdirent_label, &de->de_label); 84987807196SRobert Watson mac_destroy_label(&de->de_label); 85087807196SRobert Watson #ifdef MAC_DEBUG 85187807196SRobert Watson atomic_subtract_int(&nmacdevfsdirents, 1); 85287807196SRobert Watson #endif 85387807196SRobert Watson } 85487807196SRobert Watson 855f7b951a8SRobert Watson static void 856f7b951a8SRobert Watson mac_destroy_ifnet_label(struct label *label) 857f7b951a8SRobert Watson { 858f7b951a8SRobert Watson 859f7b951a8SRobert Watson MAC_PERFORM(destroy_ifnet_label, label); 860f7b951a8SRobert Watson mac_destroy_label(label); 861f7b951a8SRobert Watson #ifdef MAC_DEBUG 862f7b951a8SRobert Watson atomic_subtract_int(&nmacifnets, 1); 863f7b951a8SRobert Watson #endif 864f7b951a8SRobert Watson } 865f7b951a8SRobert Watson 86687807196SRobert Watson void 86787807196SRobert Watson mac_destroy_ifnet(struct ifnet *ifp) 86887807196SRobert Watson { 86987807196SRobert Watson 870f7b951a8SRobert Watson mac_destroy_ifnet_label(&ifp->if_label); 87187807196SRobert Watson } 87287807196SRobert Watson 87387807196SRobert Watson void 87487807196SRobert Watson mac_destroy_ipq(struct ipq *ipq) 87587807196SRobert Watson { 87687807196SRobert Watson 87787807196SRobert Watson MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 87887807196SRobert Watson mac_destroy_label(&ipq->ipq_label); 87987807196SRobert Watson #ifdef MAC_DEBUG 88087807196SRobert Watson atomic_subtract_int(&nmacipqs, 1); 88187807196SRobert Watson #endif 88287807196SRobert Watson } 88387807196SRobert Watson 88487807196SRobert Watson void 88587807196SRobert Watson mac_destroy_mbuf(struct mbuf *m) 88687807196SRobert Watson { 88787807196SRobert Watson 88887807196SRobert Watson MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 88987807196SRobert Watson mac_destroy_label(&m->m_pkthdr.label); 89087807196SRobert Watson #ifdef MAC_DEBUG 89187807196SRobert Watson atomic_subtract_int(&nmacmbufs, 1); 89208bcdc58SRobert Watson #endif 89308bcdc58SRobert Watson } 89408bcdc58SRobert Watson 89508bcdc58SRobert Watson void 89608bcdc58SRobert Watson mac_destroy_mount(struct mount *mp) 89708bcdc58SRobert Watson { 89808bcdc58SRobert Watson 89908bcdc58SRobert Watson MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel); 90008bcdc58SRobert Watson MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel); 90108bcdc58SRobert Watson mac_destroy_label(&mp->mnt_fslabel); 90208bcdc58SRobert Watson mac_destroy_label(&mp->mnt_mntlabel); 90308bcdc58SRobert Watson #ifdef MAC_DEBUG 90408bcdc58SRobert Watson atomic_subtract_int(&nmacmounts, 1); 90508bcdc58SRobert Watson #endif 90608bcdc58SRobert Watson } 90708bcdc58SRobert Watson 908f7b951a8SRobert Watson static void 909f7b951a8SRobert Watson mac_destroy_pipe_label(struct label *label) 910f7b951a8SRobert Watson { 911f7b951a8SRobert Watson 912f7b951a8SRobert Watson MAC_PERFORM(destroy_pipe_label, label); 913f7b951a8SRobert Watson mac_destroy_label(label); 914f7b951a8SRobert Watson #ifdef MAC_DEBUG 915f7b951a8SRobert Watson atomic_subtract_int(&nmacpipes, 1); 916f7b951a8SRobert Watson #endif 917f7b951a8SRobert Watson } 918f7b951a8SRobert Watson 91987807196SRobert Watson void 92087807196SRobert Watson mac_destroy_pipe(struct pipe *pipe) 92108bcdc58SRobert Watson { 92208bcdc58SRobert Watson 923f7b951a8SRobert Watson mac_destroy_pipe_label(pipe->pipe_label); 92487807196SRobert Watson free(pipe->pipe_label, M_MACPIPELABEL); 92587807196SRobert Watson } 92687807196SRobert Watson 92783985c26SRobert Watson static void 92883985c26SRobert Watson mac_destroy_socket_label(struct label *label) 92983985c26SRobert Watson { 93083985c26SRobert Watson 93183985c26SRobert Watson MAC_PERFORM(destroy_socket_label, label); 93283985c26SRobert Watson mac_destroy_label(label); 93383985c26SRobert Watson #ifdef MAC_DEBUG 93483985c26SRobert Watson atomic_subtract_int(&nmacsockets, 1); 93583985c26SRobert Watson #endif 93683985c26SRobert Watson } 93783985c26SRobert Watson 93883985c26SRobert Watson static void 93983985c26SRobert Watson mac_destroy_socket_peer_label(struct label *label) 94083985c26SRobert Watson { 94183985c26SRobert Watson 94283985c26SRobert Watson MAC_PERFORM(destroy_socket_peer_label, label); 94383985c26SRobert Watson mac_destroy_label(label); 94483985c26SRobert Watson } 94583985c26SRobert Watson 94687807196SRobert Watson void 94787807196SRobert Watson mac_destroy_socket(struct socket *socket) 94887807196SRobert Watson { 94987807196SRobert Watson 95083985c26SRobert Watson mac_destroy_socket_label(&socket->so_label); 95183985c26SRobert Watson mac_destroy_socket_peer_label(&socket->so_peerlabel); 95208bcdc58SRobert Watson } 95308bcdc58SRobert Watson 954763bbd2fSRobert Watson void 955f7b951a8SRobert Watson mac_destroy_vnode_label(struct label *label) 95608bcdc58SRobert Watson { 95708bcdc58SRobert Watson 958f7b951a8SRobert Watson MAC_PERFORM(destroy_vnode_label, label); 95908bcdc58SRobert Watson mac_destroy_label(label); 96008bcdc58SRobert Watson #ifdef MAC_DEBUG 961f7b951a8SRobert Watson atomic_subtract_int(&nmacvnodes, 1); 96208bcdc58SRobert Watson #endif 96308bcdc58SRobert Watson } 96408bcdc58SRobert Watson 96508bcdc58SRobert Watson void 96608bcdc58SRobert Watson mac_destroy_vnode(struct vnode *vp) 96708bcdc58SRobert Watson { 96808bcdc58SRobert Watson 969f7b951a8SRobert Watson mac_destroy_vnode_label(&vp->v_label); 970f7b951a8SRobert Watson } 971f7b951a8SRobert Watson 972f7b951a8SRobert Watson static void 973f7b951a8SRobert Watson mac_copy_pipe_label(struct label *src, struct label *dest) 974f7b951a8SRobert Watson { 975f7b951a8SRobert Watson 976f7b951a8SRobert Watson MAC_PERFORM(copy_pipe_label, src, dest); 977f7b951a8SRobert Watson } 978f7b951a8SRobert Watson 979763bbd2fSRobert Watson void 980f7b951a8SRobert Watson mac_copy_vnode_label(struct label *src, struct label *dest) 981f7b951a8SRobert Watson { 982f7b951a8SRobert Watson 983f7b951a8SRobert Watson MAC_PERFORM(copy_vnode_label, src, dest); 98408bcdc58SRobert Watson } 98508bcdc58SRobert Watson 98669bbb5b1SRobert Watson static int 987f7b951a8SRobert Watson mac_check_structmac_consistent(struct mac *mac) 988f7b951a8SRobert Watson { 989f7b951a8SRobert Watson 990f7b951a8SRobert Watson if (mac->m_buflen > MAC_MAX_LABEL_BUF_LEN) 991f7b951a8SRobert Watson return (EINVAL); 992f7b951a8SRobert Watson 993f7b951a8SRobert Watson return (0); 994f7b951a8SRobert Watson } 995f7b951a8SRobert Watson 996f7b951a8SRobert Watson static int 997f7b951a8SRobert Watson mac_externalize_cred_label(struct label *label, char *elements, 998f7b951a8SRobert Watson char *outbuf, size_t outbuflen, int flags) 99969bbb5b1SRobert Watson { 100069bbb5b1SRobert Watson int error; 100169bbb5b1SRobert Watson 1002f7b951a8SRobert Watson MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen); 100369bbb5b1SRobert Watson 100469bbb5b1SRobert Watson return (error); 100569bbb5b1SRobert Watson } 100669bbb5b1SRobert Watson 100769bbb5b1SRobert Watson static int 1008f7b951a8SRobert Watson mac_externalize_ifnet_label(struct label *label, char *elements, 1009f7b951a8SRobert Watson char *outbuf, size_t outbuflen, int flags) 101069bbb5b1SRobert Watson { 101169bbb5b1SRobert Watson int error; 101269bbb5b1SRobert Watson 1013f7b951a8SRobert Watson MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen); 1014f7b951a8SRobert Watson 1015f7b951a8SRobert Watson return (error); 1016f7b951a8SRobert Watson } 1017f7b951a8SRobert Watson 1018f7b951a8SRobert Watson static int 1019f7b951a8SRobert Watson mac_externalize_pipe_label(struct label *label, char *elements, 1020f7b951a8SRobert Watson char *outbuf, size_t outbuflen, int flags) 1021f7b951a8SRobert Watson { 1022f7b951a8SRobert Watson int error; 1023f7b951a8SRobert Watson 1024f7b951a8SRobert Watson MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen); 1025f7b951a8SRobert Watson 1026f7b951a8SRobert Watson return (error); 1027f7b951a8SRobert Watson } 1028f7b951a8SRobert Watson 1029f7b951a8SRobert Watson static int 1030f7b951a8SRobert Watson mac_externalize_socket_label(struct label *label, char *elements, 1031f7b951a8SRobert Watson char *outbuf, size_t outbuflen, int flags) 1032f7b951a8SRobert Watson { 1033f7b951a8SRobert Watson int error; 1034f7b951a8SRobert Watson 1035f7b951a8SRobert Watson MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen); 1036f7b951a8SRobert Watson 1037f7b951a8SRobert Watson return (error); 1038f7b951a8SRobert Watson } 1039f7b951a8SRobert Watson 1040f7b951a8SRobert Watson static int 1041f7b951a8SRobert Watson mac_externalize_socket_peer_label(struct label *label, char *elements, 1042f7b951a8SRobert Watson char *outbuf, size_t outbuflen, int flags) 1043f7b951a8SRobert Watson { 1044f7b951a8SRobert Watson int error; 1045f7b951a8SRobert Watson 1046f7b951a8SRobert Watson MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen); 1047f7b951a8SRobert Watson 1048f7b951a8SRobert Watson return (error); 1049f7b951a8SRobert Watson } 1050f7b951a8SRobert Watson 1051f7b951a8SRobert Watson static int 1052f7b951a8SRobert Watson mac_externalize_vnode_label(struct label *label, char *elements, 1053f7b951a8SRobert Watson char *outbuf, size_t outbuflen, int flags) 1054f7b951a8SRobert Watson { 1055f7b951a8SRobert Watson int error; 1056f7b951a8SRobert Watson 1057f7b951a8SRobert Watson MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen); 1058f7b951a8SRobert Watson 1059f7b951a8SRobert Watson return (error); 1060f7b951a8SRobert Watson } 1061f7b951a8SRobert Watson 1062f7b951a8SRobert Watson static int 1063f7b951a8SRobert Watson mac_internalize_cred_label(struct label *label, char *string) 1064f7b951a8SRobert Watson { 1065f7b951a8SRobert Watson int error; 1066f7b951a8SRobert Watson 1067f7b951a8SRobert Watson MAC_INTERNALIZE(cred_label, label, string); 1068f7b951a8SRobert Watson 1069f7b951a8SRobert Watson return (error); 1070f7b951a8SRobert Watson } 1071f7b951a8SRobert Watson 1072f7b951a8SRobert Watson static int 1073f7b951a8SRobert Watson mac_internalize_ifnet_label(struct label *label, char *string) 1074f7b951a8SRobert Watson { 1075f7b951a8SRobert Watson int error; 1076f7b951a8SRobert Watson 1077f7b951a8SRobert Watson MAC_INTERNALIZE(ifnet_label, label, string); 1078f7b951a8SRobert Watson 1079f7b951a8SRobert Watson return (error); 1080f7b951a8SRobert Watson } 1081f7b951a8SRobert Watson 1082f7b951a8SRobert Watson static int 1083f7b951a8SRobert Watson mac_internalize_pipe_label(struct label *label, char *string) 1084f7b951a8SRobert Watson { 1085f7b951a8SRobert Watson int error; 1086f7b951a8SRobert Watson 1087f7b951a8SRobert Watson MAC_INTERNALIZE(pipe_label, label, string); 1088f7b951a8SRobert Watson 1089f7b951a8SRobert Watson return (error); 1090f7b951a8SRobert Watson } 1091f7b951a8SRobert Watson 1092f7b951a8SRobert Watson static int 1093f7b951a8SRobert Watson mac_internalize_socket_label(struct label *label, char *string) 1094f7b951a8SRobert Watson { 1095f7b951a8SRobert Watson int error; 1096f7b951a8SRobert Watson 1097f7b951a8SRobert Watson MAC_INTERNALIZE(socket_label, label, string); 1098f7b951a8SRobert Watson 1099f7b951a8SRobert Watson return (error); 1100f7b951a8SRobert Watson } 1101f7b951a8SRobert Watson 1102f7b951a8SRobert Watson static int 1103f7b951a8SRobert Watson mac_internalize_vnode_label(struct label *label, char *string) 1104f7b951a8SRobert Watson { 1105f7b951a8SRobert Watson int error; 1106f7b951a8SRobert Watson 1107f7b951a8SRobert Watson MAC_INTERNALIZE(vnode_label, label, string); 110869bbb5b1SRobert Watson 110969bbb5b1SRobert Watson return (error); 111069bbb5b1SRobert Watson } 111169bbb5b1SRobert Watson 111269bbb5b1SRobert Watson /* 111369bbb5b1SRobert Watson * Initialize MAC label for the first kernel process, from which other 111469bbb5b1SRobert Watson * kernel processes and threads are spawned. 111569bbb5b1SRobert Watson */ 111669bbb5b1SRobert Watson void 111769bbb5b1SRobert Watson mac_create_proc0(struct ucred *cred) 111869bbb5b1SRobert Watson { 111969bbb5b1SRobert Watson 112069bbb5b1SRobert Watson MAC_PERFORM(create_proc0, cred); 112169bbb5b1SRobert Watson } 112269bbb5b1SRobert Watson 112369bbb5b1SRobert Watson /* 112469bbb5b1SRobert Watson * Initialize MAC label for the first userland process, from which other 112569bbb5b1SRobert Watson * userland processes and threads are spawned. 112669bbb5b1SRobert Watson */ 112769bbb5b1SRobert Watson void 112869bbb5b1SRobert Watson mac_create_proc1(struct ucred *cred) 112969bbb5b1SRobert Watson { 113069bbb5b1SRobert Watson 113169bbb5b1SRobert Watson MAC_PERFORM(create_proc1, cred); 113269bbb5b1SRobert Watson } 113369bbb5b1SRobert Watson 113469bbb5b1SRobert Watson void 113569bbb5b1SRobert Watson mac_thread_userret(struct thread *td) 113669bbb5b1SRobert Watson { 113769bbb5b1SRobert Watson 113869bbb5b1SRobert Watson MAC_PERFORM(thread_userret, td); 113969bbb5b1SRobert Watson } 114069bbb5b1SRobert Watson 114169bbb5b1SRobert Watson /* 114269bbb5b1SRobert Watson * When a new process is created, its label must be initialized. Generally, 114369bbb5b1SRobert Watson * this involves inheritence from the parent process, modulo possible 114469bbb5b1SRobert Watson * deltas. This function allows that processing to take place. 114569bbb5b1SRobert Watson */ 114669bbb5b1SRobert Watson void 114769bbb5b1SRobert Watson mac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 114869bbb5b1SRobert Watson { 114969bbb5b1SRobert Watson 115069bbb5b1SRobert Watson MAC_PERFORM(create_cred, parent_cred, child_cred); 115169bbb5b1SRobert Watson } 115269bbb5b1SRobert Watson 115395fab37eSRobert Watson void 115495fab37eSRobert Watson mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp) 115595fab37eSRobert Watson { 115695fab37eSRobert Watson 115795fab37eSRobert Watson MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label); 115895fab37eSRobert Watson } 115995fab37eSRobert Watson 116095fab37eSRobert Watson void 1161763bbd2fSRobert Watson mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, 1162763bbd2fSRobert Watson struct vnode *vp) 116395fab37eSRobert Watson { 116495fab37eSRobert Watson 1165763bbd2fSRobert Watson MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de, 1166763bbd2fSRobert Watson &de->de_label, vp, &vp->v_label); 116795fab37eSRobert Watson } 116895fab37eSRobert Watson 1169763bbd2fSRobert Watson int 1170763bbd2fSRobert Watson mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp) 117195fab37eSRobert Watson { 117295fab37eSRobert Watson int error; 117395fab37eSRobert Watson 1174763bbd2fSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr"); 1175763bbd2fSRobert Watson 1176763bbd2fSRobert Watson MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp, 1177763bbd2fSRobert Watson &vp->v_label); 117895fab37eSRobert Watson 117995fab37eSRobert Watson return (error); 118095fab37eSRobert Watson } 118195fab37eSRobert Watson 118295fab37eSRobert Watson void 1183763bbd2fSRobert Watson mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp) 118495fab37eSRobert Watson { 118595fab37eSRobert Watson 1186763bbd2fSRobert Watson MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp, 1187763bbd2fSRobert Watson &vp->v_label); 118895fab37eSRobert Watson } 118995fab37eSRobert Watson 119095fab37eSRobert Watson int 1191763bbd2fSRobert Watson mac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1192763bbd2fSRobert Watson struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 119395fab37eSRobert Watson { 1194763bbd2fSRobert Watson int error; 119595fab37eSRobert Watson 1196763bbd2fSRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr"); 1197763bbd2fSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr"); 119895fab37eSRobert Watson 1199763bbd2fSRobert Watson error = VOP_OPENEXTATTR(vp, cred, curthread); 1200763bbd2fSRobert Watson if (error == EOPNOTSUPP) { 1201763bbd2fSRobert Watson /* XXX: Optionally abort if transactions not supported. */ 1202763bbd2fSRobert Watson if (ea_warn_once == 0) { 1203763bbd2fSRobert Watson printf("Warning: transactions not supported " 1204763bbd2fSRobert Watson "in EA write.\n"); 1205763bbd2fSRobert Watson ea_warn_once = 1; 1206763bbd2fSRobert Watson } 1207763bbd2fSRobert Watson } else if (error) 120895fab37eSRobert Watson return (error); 120995fab37eSRobert Watson 1210763bbd2fSRobert Watson MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel, 1211763bbd2fSRobert Watson dvp, &dvp->v_label, vp, &vp->v_label, cnp); 121295fab37eSRobert Watson 1213763bbd2fSRobert Watson if (error) { 1214763bbd2fSRobert Watson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 121595fab37eSRobert Watson return (error); 121695fab37eSRobert Watson } 121795fab37eSRobert Watson 1218763bbd2fSRobert Watson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 121995fab37eSRobert Watson 1220763bbd2fSRobert Watson if (error == EOPNOTSUPP) 1221763bbd2fSRobert Watson error = 0; /* XXX */ 122295fab37eSRobert Watson 122395fab37eSRobert Watson return (error); 122495fab37eSRobert Watson } 122595fab37eSRobert Watson 122695fab37eSRobert Watson static int 1227763bbd2fSRobert Watson mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1228763bbd2fSRobert Watson struct label *intlabel) 122995fab37eSRobert Watson { 123095fab37eSRobert Watson int error; 123195fab37eSRobert Watson 1232763bbd2fSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr"); 123395fab37eSRobert Watson 1234763bbd2fSRobert Watson error = VOP_OPENEXTATTR(vp, cred, curthread); 1235763bbd2fSRobert Watson if (error == EOPNOTSUPP) { 1236763bbd2fSRobert Watson /* XXX: Optionally abort if transactions not supported. */ 1237763bbd2fSRobert Watson if (ea_warn_once == 0) { 1238763bbd2fSRobert Watson printf("Warning: transactions not supported " 1239763bbd2fSRobert Watson "in EA write.\n"); 1240763bbd2fSRobert Watson ea_warn_once = 1; 124195fab37eSRobert Watson } 1242763bbd2fSRobert Watson } else if (error) 124395fab37eSRobert Watson return (error); 124495fab37eSRobert Watson 1245763bbd2fSRobert Watson MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel); 124695fab37eSRobert Watson 1247763bbd2fSRobert Watson if (error) { 1248763bbd2fSRobert Watson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 124995fab37eSRobert Watson return (error); 125095fab37eSRobert Watson } 125195fab37eSRobert Watson 1252763bbd2fSRobert Watson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1253763bbd2fSRobert Watson 1254763bbd2fSRobert Watson if (error == EOPNOTSUPP) 1255763bbd2fSRobert Watson error = 0; /* XXX */ 1256763bbd2fSRobert Watson 1257763bbd2fSRobert Watson return (error); 125895fab37eSRobert Watson } 125995fab37eSRobert Watson 126095fab37eSRobert Watson void 126195fab37eSRobert Watson mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp) 126295fab37eSRobert Watson { 126395fab37eSRobert Watson 126495fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 126595fab37eSRobert Watson 126695fab37eSRobert Watson MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label); 126795fab37eSRobert Watson } 126895fab37eSRobert Watson 126995fab37eSRobert Watson int 127095fab37eSRobert Watson mac_execve_will_transition(struct ucred *old, struct vnode *vp) 127195fab37eSRobert Watson { 1272763bbd2fSRobert Watson int result; 127395fab37eSRobert Watson 127495fab37eSRobert Watson result = 0; 127595fab37eSRobert Watson MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label); 127695fab37eSRobert Watson 127795fab37eSRobert Watson return (result); 127895fab37eSRobert Watson } 127995fab37eSRobert Watson 128095fab37eSRobert Watson int 1281b914de36SRobert Watson mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode) 128295fab37eSRobert Watson { 128395fab37eSRobert Watson int error; 128495fab37eSRobert Watson 128595fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 128695fab37eSRobert Watson 128795fab37eSRobert Watson if (!mac_enforce_fs) 128895fab37eSRobert Watson return (0); 128995fab37eSRobert Watson 1290b914de36SRobert Watson MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, acc_mode); 129195fab37eSRobert Watson return (error); 129295fab37eSRobert Watson } 129395fab37eSRobert Watson 129495fab37eSRobert Watson int 129595fab37eSRobert Watson mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 129695fab37eSRobert Watson { 129795fab37eSRobert Watson int error; 129895fab37eSRobert Watson 129995fab37eSRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 130095fab37eSRobert Watson 130195fab37eSRobert Watson if (!mac_enforce_fs) 130295fab37eSRobert Watson return (0); 130395fab37eSRobert Watson 130495fab37eSRobert Watson MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 130595fab37eSRobert Watson return (error); 130695fab37eSRobert Watson } 130795fab37eSRobert Watson 130895fab37eSRobert Watson int 130995fab37eSRobert Watson mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 131095fab37eSRobert Watson { 131195fab37eSRobert Watson int error; 131295fab37eSRobert Watson 131395fab37eSRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 131495fab37eSRobert Watson 131595fab37eSRobert Watson if (!mac_enforce_fs) 131695fab37eSRobert Watson return (0); 131795fab37eSRobert Watson 131895fab37eSRobert Watson MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 131995fab37eSRobert Watson return (error); 132095fab37eSRobert Watson } 132195fab37eSRobert Watson 132295fab37eSRobert Watson int 132395fab37eSRobert Watson mac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 132495fab37eSRobert Watson struct componentname *cnp, struct vattr *vap) 132595fab37eSRobert Watson { 132695fab37eSRobert Watson int error; 132795fab37eSRobert Watson 132895fab37eSRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 132995fab37eSRobert Watson 133095fab37eSRobert Watson if (!mac_enforce_fs) 133195fab37eSRobert Watson return (0); 133295fab37eSRobert Watson 133395fab37eSRobert Watson MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 133495fab37eSRobert Watson return (error); 133595fab37eSRobert Watson } 133695fab37eSRobert Watson 133795fab37eSRobert Watson int 133895fab37eSRobert Watson mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 133995fab37eSRobert Watson struct componentname *cnp) 134095fab37eSRobert Watson { 134195fab37eSRobert Watson int error; 134295fab37eSRobert Watson 134395fab37eSRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 134495fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 134595fab37eSRobert Watson 134695fab37eSRobert Watson if (!mac_enforce_fs) 134795fab37eSRobert Watson return (0); 134895fab37eSRobert Watson 134995fab37eSRobert Watson MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 135095fab37eSRobert Watson &vp->v_label, cnp); 135195fab37eSRobert Watson return (error); 135295fab37eSRobert Watson } 135395fab37eSRobert Watson 135495fab37eSRobert Watson int 135595fab37eSRobert Watson mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 135695fab37eSRobert Watson acl_type_t type) 135795fab37eSRobert Watson { 135895fab37eSRobert Watson int error; 135995fab37eSRobert Watson 136095fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 136195fab37eSRobert Watson 136295fab37eSRobert Watson if (!mac_enforce_fs) 136395fab37eSRobert Watson return (0); 136495fab37eSRobert Watson 136595fab37eSRobert Watson MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 136695fab37eSRobert Watson return (error); 136795fab37eSRobert Watson } 136895fab37eSRobert Watson 136995fab37eSRobert Watson int 137095fab37eSRobert Watson mac_check_vnode_exec(struct ucred *cred, struct vnode *vp) 137195fab37eSRobert Watson { 137295fab37eSRobert Watson int error; 137395fab37eSRobert Watson 1374851704bbSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1375851704bbSRobert Watson 137695fab37eSRobert Watson if (!mac_enforce_process && !mac_enforce_fs) 137795fab37eSRobert Watson return (0); 137895fab37eSRobert Watson 137995fab37eSRobert Watson MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label); 138095fab37eSRobert Watson 138195fab37eSRobert Watson return (error); 138295fab37eSRobert Watson } 138395fab37eSRobert Watson 138495fab37eSRobert Watson int 138595fab37eSRobert Watson mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 138695fab37eSRobert Watson { 138795fab37eSRobert Watson int error; 138895fab37eSRobert Watson 138995fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 139095fab37eSRobert Watson 139195fab37eSRobert Watson if (!mac_enforce_fs) 139295fab37eSRobert Watson return (0); 139395fab37eSRobert Watson 139495fab37eSRobert Watson MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 139595fab37eSRobert Watson return (error); 139695fab37eSRobert Watson } 139795fab37eSRobert Watson 139895fab37eSRobert Watson int 139995fab37eSRobert Watson mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 140095fab37eSRobert Watson int attrnamespace, const char *name, struct uio *uio) 140195fab37eSRobert Watson { 140295fab37eSRobert Watson int error; 140395fab37eSRobert Watson 140495fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 140595fab37eSRobert Watson 140695fab37eSRobert Watson if (!mac_enforce_fs) 140795fab37eSRobert Watson return (0); 140895fab37eSRobert Watson 140995fab37eSRobert Watson MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 141095fab37eSRobert Watson attrnamespace, name, uio); 141195fab37eSRobert Watson return (error); 141295fab37eSRobert Watson } 141395fab37eSRobert Watson 141495fab37eSRobert Watson int 14150a694196SRobert Watson mac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 14160a694196SRobert Watson struct vnode *vp, struct componentname *cnp) 14170a694196SRobert Watson { 14180a694196SRobert Watson int error; 14190a694196SRobert Watson 14200a694196SRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link"); 14210a694196SRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link"); 14220a694196SRobert Watson 14230a694196SRobert Watson if (!mac_enforce_fs) 14240a694196SRobert Watson return (0); 14250a694196SRobert Watson 14260a694196SRobert Watson MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp, 14270a694196SRobert Watson &vp->v_label, cnp); 14280a694196SRobert Watson return (error); 14290a694196SRobert Watson } 14300a694196SRobert Watson 14310a694196SRobert Watson int 143295fab37eSRobert Watson mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 143395fab37eSRobert Watson struct componentname *cnp) 143495fab37eSRobert Watson { 143595fab37eSRobert Watson int error; 143695fab37eSRobert Watson 143795fab37eSRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 143895fab37eSRobert Watson 143995fab37eSRobert Watson if (!mac_enforce_fs) 144095fab37eSRobert Watson return (0); 144195fab37eSRobert Watson 144295fab37eSRobert Watson MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 144395fab37eSRobert Watson return (error); 144495fab37eSRobert Watson } 144595fab37eSRobert Watson 1446e183f80eSRobert Watson int 1447e183f80eSRobert Watson mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) 144895fab37eSRobert Watson { 1449e183f80eSRobert Watson int error; 145095fab37eSRobert Watson 1451e183f80eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); 1452ca7850c3SRobert Watson 1453e183f80eSRobert Watson if (!mac_enforce_fs || !mac_enforce_vm) 1454e183f80eSRobert Watson return (0); 1455e183f80eSRobert Watson 1456e183f80eSRobert Watson MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); 1457e183f80eSRobert Watson return (error); 1458e183f80eSRobert Watson } 1459e183f80eSRobert Watson 1460e183f80eSRobert Watson void 1461e183f80eSRobert Watson mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) 1462e183f80eSRobert Watson { 1463e183f80eSRobert Watson int result = *prot; 1464e183f80eSRobert Watson 1465e183f80eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); 1466e183f80eSRobert Watson 1467e183f80eSRobert Watson if (!mac_enforce_fs || !mac_enforce_vm) 1468e183f80eSRobert Watson return; 1469e183f80eSRobert Watson 1470e183f80eSRobert Watson MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, 1471e183f80eSRobert Watson &result); 1472e183f80eSRobert Watson 1473e183f80eSRobert Watson *prot = result; 1474e183f80eSRobert Watson } 1475e183f80eSRobert Watson 1476e183f80eSRobert Watson int 1477e183f80eSRobert Watson mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) 1478e183f80eSRobert Watson { 1479e183f80eSRobert Watson int error; 1480e183f80eSRobert Watson 1481e183f80eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); 1482e183f80eSRobert Watson 1483e183f80eSRobert Watson if (!mac_enforce_fs || !mac_enforce_vm) 1484e183f80eSRobert Watson return (0); 1485e183f80eSRobert Watson 1486e183f80eSRobert Watson MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); 1487e183f80eSRobert Watson return (error); 148895fab37eSRobert Watson } 148995fab37eSRobert Watson 149095fab37eSRobert Watson int 1491b914de36SRobert Watson mac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode) 149295fab37eSRobert Watson { 149395fab37eSRobert Watson int error; 149495fab37eSRobert Watson 149595fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 149695fab37eSRobert Watson 149795fab37eSRobert Watson if (!mac_enforce_fs) 149895fab37eSRobert Watson return (0); 149995fab37eSRobert Watson 150095fab37eSRobert Watson MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 150195fab37eSRobert Watson return (error); 150295fab37eSRobert Watson } 150395fab37eSRobert Watson 150495fab37eSRobert Watson int 1505177142e4SRobert Watson mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1506177142e4SRobert Watson struct vnode *vp) 15077f724f8bSRobert Watson { 15087f724f8bSRobert Watson int error; 15097f724f8bSRobert Watson 15107f724f8bSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 15117f724f8bSRobert Watson 15127f724f8bSRobert Watson if (!mac_enforce_fs) 15137f724f8bSRobert Watson return (0); 15147f724f8bSRobert Watson 1515177142e4SRobert Watson MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 1516177142e4SRobert Watson &vp->v_label); 15177f724f8bSRobert Watson 15187f724f8bSRobert Watson return (error); 15197f724f8bSRobert Watson } 15207f724f8bSRobert Watson 15217f724f8bSRobert Watson int 1522177142e4SRobert Watson mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1523177142e4SRobert Watson struct vnode *vp) 15247f724f8bSRobert Watson { 15257f724f8bSRobert Watson int error; 15267f724f8bSRobert Watson 15277f724f8bSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 15287f724f8bSRobert Watson 15297f724f8bSRobert Watson if (!mac_enforce_fs) 15307f724f8bSRobert Watson return (0); 15317f724f8bSRobert Watson 1532177142e4SRobert Watson MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 1533177142e4SRobert Watson &vp->v_label); 15347f724f8bSRobert Watson 15357f724f8bSRobert Watson return (error); 15367f724f8bSRobert Watson } 15377f724f8bSRobert Watson 15387f724f8bSRobert Watson int 153995fab37eSRobert Watson mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 154095fab37eSRobert Watson { 154195fab37eSRobert Watson int error; 154295fab37eSRobert Watson 154395fab37eSRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 154495fab37eSRobert Watson 154595fab37eSRobert Watson if (!mac_enforce_fs) 154695fab37eSRobert Watson return (0); 154795fab37eSRobert Watson 154895fab37eSRobert Watson MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 154995fab37eSRobert Watson return (error); 155095fab37eSRobert Watson } 155195fab37eSRobert Watson 155295fab37eSRobert Watson int 155395fab37eSRobert Watson mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 155495fab37eSRobert Watson { 155595fab37eSRobert Watson int error; 155695fab37eSRobert Watson 155795fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 155895fab37eSRobert Watson 155995fab37eSRobert Watson if (!mac_enforce_fs) 156095fab37eSRobert Watson return (0); 156195fab37eSRobert Watson 156295fab37eSRobert Watson MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 156395fab37eSRobert Watson return (error); 156495fab37eSRobert Watson } 156595fab37eSRobert Watson 156695fab37eSRobert Watson static int 156795fab37eSRobert Watson mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 156895fab37eSRobert Watson struct label *newlabel) 156995fab37eSRobert Watson { 157095fab37eSRobert Watson int error; 157195fab37eSRobert Watson 157295fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 157395fab37eSRobert Watson 157495fab37eSRobert Watson MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 157595fab37eSRobert Watson 157695fab37eSRobert Watson return (error); 157795fab37eSRobert Watson } 157895fab37eSRobert Watson 157995fab37eSRobert Watson int 158095fab37eSRobert Watson mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 158195fab37eSRobert Watson struct vnode *vp, struct componentname *cnp) 158295fab37eSRobert Watson { 158395fab37eSRobert Watson int error; 158495fab37eSRobert Watson 158595fab37eSRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 158695fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 158795fab37eSRobert Watson 158895fab37eSRobert Watson if (!mac_enforce_fs) 158995fab37eSRobert Watson return (0); 159095fab37eSRobert Watson 159195fab37eSRobert Watson MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 159295fab37eSRobert Watson &vp->v_label, cnp); 159395fab37eSRobert Watson return (error); 159495fab37eSRobert Watson } 159595fab37eSRobert Watson 159695fab37eSRobert Watson int 159795fab37eSRobert Watson mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 159895fab37eSRobert Watson struct vnode *vp, int samedir, struct componentname *cnp) 159995fab37eSRobert Watson { 160095fab37eSRobert Watson int error; 160195fab37eSRobert Watson 160295fab37eSRobert Watson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 160395fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 160495fab37eSRobert Watson 160595fab37eSRobert Watson if (!mac_enforce_fs) 160695fab37eSRobert Watson return (0); 160795fab37eSRobert Watson 160895fab37eSRobert Watson MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 160995fab37eSRobert Watson vp != NULL ? &vp->v_label : NULL, samedir, cnp); 161095fab37eSRobert Watson return (error); 161195fab37eSRobert Watson } 161295fab37eSRobert Watson 161395fab37eSRobert Watson int 161495fab37eSRobert Watson mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 161595fab37eSRobert Watson { 161695fab37eSRobert Watson int error; 161795fab37eSRobert Watson 161895fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 161995fab37eSRobert Watson 162095fab37eSRobert Watson if (!mac_enforce_fs) 162195fab37eSRobert Watson return (0); 162295fab37eSRobert Watson 162395fab37eSRobert Watson MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 162495fab37eSRobert Watson return (error); 162595fab37eSRobert Watson } 162695fab37eSRobert Watson 162795fab37eSRobert Watson int 162895fab37eSRobert Watson mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 162995fab37eSRobert Watson struct acl *acl) 163095fab37eSRobert Watson { 163195fab37eSRobert Watson int error; 163295fab37eSRobert Watson 163395fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 163495fab37eSRobert Watson 163595fab37eSRobert Watson if (!mac_enforce_fs) 163695fab37eSRobert Watson return (0); 163795fab37eSRobert Watson 163895fab37eSRobert Watson MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 163995fab37eSRobert Watson return (error); 164095fab37eSRobert Watson } 164195fab37eSRobert Watson 164295fab37eSRobert Watson int 164395fab37eSRobert Watson mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 164495fab37eSRobert Watson int attrnamespace, const char *name, struct uio *uio) 164595fab37eSRobert Watson { 164695fab37eSRobert Watson int error; 164795fab37eSRobert Watson 164895fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 164995fab37eSRobert Watson 165095fab37eSRobert Watson if (!mac_enforce_fs) 165195fab37eSRobert Watson return (0); 165295fab37eSRobert Watson 165395fab37eSRobert Watson MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 165495fab37eSRobert Watson attrnamespace, name, uio); 165595fab37eSRobert Watson return (error); 165695fab37eSRobert Watson } 165795fab37eSRobert Watson 165895fab37eSRobert Watson int 165995fab37eSRobert Watson mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 166095fab37eSRobert Watson { 166195fab37eSRobert Watson int error; 166295fab37eSRobert Watson 166395fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 166495fab37eSRobert Watson 166595fab37eSRobert Watson if (!mac_enforce_fs) 166695fab37eSRobert Watson return (0); 166795fab37eSRobert Watson 166895fab37eSRobert Watson MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 166995fab37eSRobert Watson return (error); 167095fab37eSRobert Watson } 167195fab37eSRobert Watson 167295fab37eSRobert Watson int 167395fab37eSRobert Watson mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 167495fab37eSRobert Watson { 167595fab37eSRobert Watson int error; 167695fab37eSRobert Watson 167795fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 167895fab37eSRobert Watson 167995fab37eSRobert Watson if (!mac_enforce_fs) 168095fab37eSRobert Watson return (0); 168195fab37eSRobert Watson 168295fab37eSRobert Watson MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 168395fab37eSRobert Watson return (error); 168495fab37eSRobert Watson } 168595fab37eSRobert Watson 168695fab37eSRobert Watson int 168795fab37eSRobert Watson mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 168895fab37eSRobert Watson gid_t gid) 168995fab37eSRobert Watson { 169095fab37eSRobert Watson int error; 169195fab37eSRobert Watson 169295fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 169395fab37eSRobert Watson 169495fab37eSRobert Watson if (!mac_enforce_fs) 169595fab37eSRobert Watson return (0); 169695fab37eSRobert Watson 169795fab37eSRobert Watson MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 169895fab37eSRobert Watson return (error); 169995fab37eSRobert Watson } 170095fab37eSRobert Watson 170195fab37eSRobert Watson int 170295fab37eSRobert Watson mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 170395fab37eSRobert Watson struct timespec atime, struct timespec mtime) 170495fab37eSRobert Watson { 170595fab37eSRobert Watson int error; 170695fab37eSRobert Watson 170795fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 170895fab37eSRobert Watson 170995fab37eSRobert Watson if (!mac_enforce_fs) 171095fab37eSRobert Watson return (0); 171195fab37eSRobert Watson 171295fab37eSRobert Watson MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 171395fab37eSRobert Watson mtime); 171495fab37eSRobert Watson return (error); 171595fab37eSRobert Watson } 171695fab37eSRobert Watson 171795fab37eSRobert Watson int 1718177142e4SRobert Watson mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 1719177142e4SRobert Watson struct vnode *vp) 172095fab37eSRobert Watson { 172195fab37eSRobert Watson int error; 172295fab37eSRobert Watson 172395fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 172495fab37eSRobert Watson 172595fab37eSRobert Watson if (!mac_enforce_fs) 172695fab37eSRobert Watson return (0); 172795fab37eSRobert Watson 1728177142e4SRobert Watson MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 1729177142e4SRobert Watson &vp->v_label); 173095fab37eSRobert Watson return (error); 173195fab37eSRobert Watson } 173295fab37eSRobert Watson 17337f724f8bSRobert Watson int 1734177142e4SRobert Watson mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 1735177142e4SRobert Watson struct vnode *vp) 17367f724f8bSRobert Watson { 17377f724f8bSRobert Watson int error; 17387f724f8bSRobert Watson 17397f724f8bSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 17407f724f8bSRobert Watson 17417f724f8bSRobert Watson if (!mac_enforce_fs) 17427f724f8bSRobert Watson return (0); 17437f724f8bSRobert Watson 1744177142e4SRobert Watson MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 1745177142e4SRobert Watson &vp->v_label); 17467f724f8bSRobert Watson 17477f724f8bSRobert Watson return (error); 17487f724f8bSRobert Watson } 17497f724f8bSRobert Watson 175095fab37eSRobert Watson /* 175195fab37eSRobert Watson * When relabeling a process, call out to the policies for the maximum 175295fab37eSRobert Watson * permission allowed for each object type we know about in its 175395fab37eSRobert Watson * memory space, and revoke access (in the least surprising ways we 175495fab37eSRobert Watson * know) when necessary. The process lock is not held here. 175595fab37eSRobert Watson */ 175695fab37eSRobert Watson static void 175795fab37eSRobert Watson mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 175895fab37eSRobert Watson { 175995fab37eSRobert Watson 176095fab37eSRobert Watson /* XXX freeze all other threads */ 176195fab37eSRobert Watson mac_cred_mmapped_drop_perms_recurse(td, cred, 176295fab37eSRobert Watson &td->td_proc->p_vmspace->vm_map); 176395fab37eSRobert Watson /* XXX allow other threads to continue */ 176495fab37eSRobert Watson } 176595fab37eSRobert Watson 176695fab37eSRobert Watson static __inline const char * 176795fab37eSRobert Watson prot2str(vm_prot_t prot) 176895fab37eSRobert Watson { 176995fab37eSRobert Watson 177095fab37eSRobert Watson switch (prot & VM_PROT_ALL) { 177195fab37eSRobert Watson case VM_PROT_READ: 177295fab37eSRobert Watson return ("r--"); 177395fab37eSRobert Watson case VM_PROT_READ | VM_PROT_WRITE: 177495fab37eSRobert Watson return ("rw-"); 177595fab37eSRobert Watson case VM_PROT_READ | VM_PROT_EXECUTE: 177695fab37eSRobert Watson return ("r-x"); 177795fab37eSRobert Watson case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 177895fab37eSRobert Watson return ("rwx"); 177995fab37eSRobert Watson case VM_PROT_WRITE: 178095fab37eSRobert Watson return ("-w-"); 178195fab37eSRobert Watson case VM_PROT_EXECUTE: 178295fab37eSRobert Watson return ("--x"); 178395fab37eSRobert Watson case VM_PROT_WRITE | VM_PROT_EXECUTE: 178495fab37eSRobert Watson return ("-wx"); 178595fab37eSRobert Watson default: 178695fab37eSRobert Watson return ("---"); 178795fab37eSRobert Watson } 178895fab37eSRobert Watson } 178995fab37eSRobert Watson 179095fab37eSRobert Watson static void 179195fab37eSRobert Watson mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 179295fab37eSRobert Watson struct vm_map *map) 179395fab37eSRobert Watson { 179495fab37eSRobert Watson struct vm_map_entry *vme; 1795e183f80eSRobert Watson int result; 1796e183f80eSRobert Watson vm_prot_t revokeperms; 179795fab37eSRobert Watson vm_object_t object; 179895fab37eSRobert Watson vm_ooffset_t offset; 179995fab37eSRobert Watson struct vnode *vp; 180095fab37eSRobert Watson 1801c0f39905SRobert Watson if (!mac_mmap_revocation) 1802c0f39905SRobert Watson return; 1803c0f39905SRobert Watson 180495fab37eSRobert Watson vm_map_lock_read(map); 180595fab37eSRobert Watson for (vme = map->header.next; vme != &map->header; vme = vme->next) { 180695fab37eSRobert Watson if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 180795fab37eSRobert Watson mac_cred_mmapped_drop_perms_recurse(td, cred, 180895fab37eSRobert Watson vme->object.sub_map); 180995fab37eSRobert Watson continue; 181095fab37eSRobert Watson } 181195fab37eSRobert Watson /* 181295fab37eSRobert Watson * Skip over entries that obviously are not shared. 181395fab37eSRobert Watson */ 181495fab37eSRobert Watson if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 181595fab37eSRobert Watson !vme->max_protection) 181695fab37eSRobert Watson continue; 181795fab37eSRobert Watson /* 181895fab37eSRobert Watson * Drill down to the deepest backing object. 181995fab37eSRobert Watson */ 182095fab37eSRobert Watson offset = vme->offset; 182195fab37eSRobert Watson object = vme->object.vm_object; 182295fab37eSRobert Watson if (object == NULL) 182395fab37eSRobert Watson continue; 182495fab37eSRobert Watson while (object->backing_object != NULL) { 182595fab37eSRobert Watson object = object->backing_object; 182695fab37eSRobert Watson offset += object->backing_object_offset; 182795fab37eSRobert Watson } 182895fab37eSRobert Watson /* 182995fab37eSRobert Watson * At the moment, vm_maps and objects aren't considered 183095fab37eSRobert Watson * by the MAC system, so only things with backing by a 183195fab37eSRobert Watson * normal object (read: vnodes) are checked. 183295fab37eSRobert Watson */ 183395fab37eSRobert Watson if (object->type != OBJT_VNODE) 183495fab37eSRobert Watson continue; 183595fab37eSRobert Watson vp = (struct vnode *)object->handle; 183695fab37eSRobert Watson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1837e183f80eSRobert Watson result = vme->max_protection; 1838e183f80eSRobert Watson mac_check_vnode_mmap_downgrade(cred, vp, &result); 183995fab37eSRobert Watson VOP_UNLOCK(vp, 0, td); 184095fab37eSRobert Watson /* 184195fab37eSRobert Watson * Find out what maximum protection we may be allowing 184295fab37eSRobert Watson * now but a policy needs to get removed. 184395fab37eSRobert Watson */ 184495fab37eSRobert Watson revokeperms = vme->max_protection & ~result; 184595fab37eSRobert Watson if (!revokeperms) 184695fab37eSRobert Watson continue; 1847b656366bSBruce Evans printf("pid %ld: revoking %s perms from %#lx:%ld " 1848b656366bSBruce Evans "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 1849b656366bSBruce Evans prot2str(revokeperms), (u_long)vme->start, 1850b656366bSBruce Evans (long)(vme->end - vme->start), 185195fab37eSRobert Watson prot2str(vme->max_protection), prot2str(vme->protection)); 185295fab37eSRobert Watson vm_map_lock_upgrade(map); 185395fab37eSRobert Watson /* 185495fab37eSRobert Watson * This is the really simple case: if a map has more 185595fab37eSRobert Watson * max_protection than is allowed, but it's not being 185695fab37eSRobert Watson * actually used (that is, the current protection is 185795fab37eSRobert Watson * still allowed), we can just wipe it out and do 185895fab37eSRobert Watson * nothing more. 185995fab37eSRobert Watson */ 186095fab37eSRobert Watson if ((vme->protection & revokeperms) == 0) { 186195fab37eSRobert Watson vme->max_protection -= revokeperms; 186295fab37eSRobert Watson } else { 186395fab37eSRobert Watson if (revokeperms & VM_PROT_WRITE) { 186495fab37eSRobert Watson /* 186595fab37eSRobert Watson * In the more complicated case, flush out all 186695fab37eSRobert Watson * pending changes to the object then turn it 186795fab37eSRobert Watson * copy-on-write. 186895fab37eSRobert Watson */ 186995fab37eSRobert Watson vm_object_reference(object); 187095fab37eSRobert Watson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 187195fab37eSRobert Watson vm_object_page_clean(object, 187295fab37eSRobert Watson OFF_TO_IDX(offset), 187395fab37eSRobert Watson OFF_TO_IDX(offset + vme->end - vme->start + 187495fab37eSRobert Watson PAGE_MASK), 187595fab37eSRobert Watson OBJPC_SYNC); 187695fab37eSRobert Watson VOP_UNLOCK(vp, 0, td); 187795fab37eSRobert Watson vm_object_deallocate(object); 187895fab37eSRobert Watson /* 187995fab37eSRobert Watson * Why bother if there's no read permissions 188095fab37eSRobert Watson * anymore? For the rest, we need to leave 188195fab37eSRobert Watson * the write permissions on for COW, or 188295fab37eSRobert Watson * remove them entirely if configured to. 188395fab37eSRobert Watson */ 188495fab37eSRobert Watson if (!mac_mmap_revocation_via_cow) { 188595fab37eSRobert Watson vme->max_protection &= ~VM_PROT_WRITE; 188695fab37eSRobert Watson vme->protection &= ~VM_PROT_WRITE; 188795fab37eSRobert Watson } if ((revokeperms & VM_PROT_READ) == 0) 188895fab37eSRobert Watson vme->eflags |= MAP_ENTRY_COW | 188995fab37eSRobert Watson MAP_ENTRY_NEEDS_COPY; 189095fab37eSRobert Watson } 189195fab37eSRobert Watson if (revokeperms & VM_PROT_EXECUTE) { 189295fab37eSRobert Watson vme->max_protection &= ~VM_PROT_EXECUTE; 189395fab37eSRobert Watson vme->protection &= ~VM_PROT_EXECUTE; 189495fab37eSRobert Watson } 189595fab37eSRobert Watson if (revokeperms & VM_PROT_READ) { 189695fab37eSRobert Watson vme->max_protection = 0; 189795fab37eSRobert Watson vme->protection = 0; 189895fab37eSRobert Watson } 189995fab37eSRobert Watson pmap_protect(map->pmap, vme->start, vme->end, 190095fab37eSRobert Watson vme->protection & ~revokeperms); 190195fab37eSRobert Watson vm_map_simplify_entry(map, vme); 190295fab37eSRobert Watson } 190395fab37eSRobert Watson vm_map_lock_downgrade(map); 190495fab37eSRobert Watson } 190595fab37eSRobert Watson vm_map_unlock_read(map); 190695fab37eSRobert Watson } 190795fab37eSRobert Watson 190895fab37eSRobert Watson /* 190995fab37eSRobert Watson * When the subject's label changes, it may require revocation of privilege 191095fab37eSRobert Watson * to mapped objects. This can't be done on-the-fly later with a unified 191195fab37eSRobert Watson * buffer cache. 191295fab37eSRobert Watson */ 191395fab37eSRobert Watson static void 191495fab37eSRobert Watson mac_relabel_cred(struct ucred *cred, struct label *newlabel) 191595fab37eSRobert Watson { 191695fab37eSRobert Watson 191795fab37eSRobert Watson MAC_PERFORM(relabel_cred, cred, newlabel); 191895fab37eSRobert Watson } 191995fab37eSRobert Watson 192095fab37eSRobert Watson void 192195fab37eSRobert Watson mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 192295fab37eSRobert Watson { 192395fab37eSRobert Watson 192495fab37eSRobert Watson MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 192595fab37eSRobert Watson } 192695fab37eSRobert Watson 192795fab37eSRobert Watson void 192895fab37eSRobert Watson mac_create_ifnet(struct ifnet *ifnet) 192995fab37eSRobert Watson { 193095fab37eSRobert Watson 193195fab37eSRobert Watson MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 193295fab37eSRobert Watson } 193395fab37eSRobert Watson 193495fab37eSRobert Watson void 193595fab37eSRobert Watson mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 193695fab37eSRobert Watson { 193795fab37eSRobert Watson 193895fab37eSRobert Watson MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 193995fab37eSRobert Watson } 194095fab37eSRobert Watson 194195fab37eSRobert Watson void 194295fab37eSRobert Watson mac_create_socket(struct ucred *cred, struct socket *socket) 194395fab37eSRobert Watson { 194495fab37eSRobert Watson 194595fab37eSRobert Watson MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 194695fab37eSRobert Watson } 194795fab37eSRobert Watson 194895fab37eSRobert Watson void 194995fab37eSRobert Watson mac_create_pipe(struct ucred *cred, struct pipe *pipe) 195095fab37eSRobert Watson { 195195fab37eSRobert Watson 195295fab37eSRobert Watson MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 195395fab37eSRobert Watson } 195495fab37eSRobert Watson 195595fab37eSRobert Watson void 195695fab37eSRobert Watson mac_create_socket_from_socket(struct socket *oldsocket, 195795fab37eSRobert Watson struct socket *newsocket) 195895fab37eSRobert Watson { 195995fab37eSRobert Watson 196095fab37eSRobert Watson MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 196195fab37eSRobert Watson newsocket, &newsocket->so_label); 196295fab37eSRobert Watson } 196395fab37eSRobert Watson 196495fab37eSRobert Watson static void 196595fab37eSRobert Watson mac_relabel_socket(struct ucred *cred, struct socket *socket, 196695fab37eSRobert Watson struct label *newlabel) 196795fab37eSRobert Watson { 196895fab37eSRobert Watson 196995fab37eSRobert Watson MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 197095fab37eSRobert Watson } 197195fab37eSRobert Watson 197295fab37eSRobert Watson static void 197395fab37eSRobert Watson mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 197495fab37eSRobert Watson { 197595fab37eSRobert Watson 197695fab37eSRobert Watson MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 197795fab37eSRobert Watson } 197895fab37eSRobert Watson 197995fab37eSRobert Watson void 198095fab37eSRobert Watson mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 198195fab37eSRobert Watson { 198295fab37eSRobert Watson 198395fab37eSRobert Watson MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label, 198495fab37eSRobert Watson socket, &socket->so_peerlabel); 198595fab37eSRobert Watson } 198695fab37eSRobert Watson 198795fab37eSRobert Watson void 198895fab37eSRobert Watson mac_set_socket_peer_from_socket(struct socket *oldsocket, 198995fab37eSRobert Watson struct socket *newsocket) 199095fab37eSRobert Watson { 199195fab37eSRobert Watson 199295fab37eSRobert Watson MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 199395fab37eSRobert Watson &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 199495fab37eSRobert Watson } 199595fab37eSRobert Watson 199695fab37eSRobert Watson void 199795fab37eSRobert Watson mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 199895fab37eSRobert Watson { 199995fab37eSRobert Watson 200095fab37eSRobert Watson MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 200195fab37eSRobert Watson datagram, &datagram->m_pkthdr.label); 200295fab37eSRobert Watson } 200395fab37eSRobert Watson 200495fab37eSRobert Watson void 200595fab37eSRobert Watson mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 200695fab37eSRobert Watson { 200795fab37eSRobert Watson 200895fab37eSRobert Watson MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label, 200995fab37eSRobert Watson fragment, &fragment->m_pkthdr.label); 201095fab37eSRobert Watson } 201195fab37eSRobert Watson 201295fab37eSRobert Watson void 201395fab37eSRobert Watson mac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 201495fab37eSRobert Watson { 201595fab37eSRobert Watson 201695fab37eSRobert Watson MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq, 201795fab37eSRobert Watson &ipq->ipq_label); 201895fab37eSRobert Watson } 201995fab37eSRobert Watson 202095fab37eSRobert Watson void 202195fab37eSRobert Watson mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 202295fab37eSRobert Watson { 202395fab37eSRobert Watson 202495fab37eSRobert Watson MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label, 202595fab37eSRobert Watson newmbuf, &newmbuf->m_pkthdr.label); 202695fab37eSRobert Watson } 202795fab37eSRobert Watson 202895fab37eSRobert Watson void 202995fab37eSRobert Watson mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 203095fab37eSRobert Watson { 203195fab37eSRobert Watson 203295fab37eSRobert Watson MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 203395fab37eSRobert Watson &mbuf->m_pkthdr.label); 203495fab37eSRobert Watson } 203595fab37eSRobert Watson 203695fab37eSRobert Watson void 203795fab37eSRobert Watson mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 203895fab37eSRobert Watson { 203995fab37eSRobert Watson 204095fab37eSRobert Watson MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 204195fab37eSRobert Watson &mbuf->m_pkthdr.label); 204295fab37eSRobert Watson } 204395fab37eSRobert Watson 204495fab37eSRobert Watson void 204595fab37eSRobert Watson mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 204695fab37eSRobert Watson { 204795fab37eSRobert Watson 204895fab37eSRobert Watson MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 204995fab37eSRobert Watson &mbuf->m_pkthdr.label); 205095fab37eSRobert Watson } 205195fab37eSRobert Watson 205295fab37eSRobert Watson void 205395fab37eSRobert Watson mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 205495fab37eSRobert Watson struct mbuf *newmbuf) 205595fab37eSRobert Watson { 205695fab37eSRobert Watson 205795fab37eSRobert Watson MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, 205895fab37eSRobert Watson &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf, 205995fab37eSRobert Watson &newmbuf->m_pkthdr.label); 206095fab37eSRobert Watson } 206195fab37eSRobert Watson 206295fab37eSRobert Watson void 206395fab37eSRobert Watson mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 206495fab37eSRobert Watson { 206595fab37eSRobert Watson 206695fab37eSRobert Watson MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label, 206795fab37eSRobert Watson newmbuf, &newmbuf->m_pkthdr.label); 206895fab37eSRobert Watson } 206995fab37eSRobert Watson 207095fab37eSRobert Watson int 207195fab37eSRobert Watson mac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 207295fab37eSRobert Watson { 207395fab37eSRobert Watson int result; 207495fab37eSRobert Watson 207595fab37eSRobert Watson result = 1; 207695fab37eSRobert Watson MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label, 207795fab37eSRobert Watson ipq, &ipq->ipq_label); 207895fab37eSRobert Watson 207995fab37eSRobert Watson return (result); 208095fab37eSRobert Watson } 208195fab37eSRobert Watson 208295fab37eSRobert Watson void 208395fab37eSRobert Watson mac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 208495fab37eSRobert Watson { 208595fab37eSRobert Watson 208695fab37eSRobert Watson MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq, 208795fab37eSRobert Watson &ipq->ipq_label); 208895fab37eSRobert Watson } 208995fab37eSRobert Watson 209095fab37eSRobert Watson void 209195fab37eSRobert Watson mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 209295fab37eSRobert Watson { 209395fab37eSRobert Watson 209495fab37eSRobert Watson MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 209595fab37eSRobert Watson &mbuf->m_pkthdr.label); 209695fab37eSRobert Watson } 209795fab37eSRobert Watson 209895fab37eSRobert Watson void 209995fab37eSRobert Watson mac_create_mount(struct ucred *cred, struct mount *mp) 210095fab37eSRobert Watson { 210195fab37eSRobert Watson 210295fab37eSRobert Watson MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 210395fab37eSRobert Watson &mp->mnt_fslabel); 210495fab37eSRobert Watson } 210595fab37eSRobert Watson 210695fab37eSRobert Watson void 210795fab37eSRobert Watson mac_create_root_mount(struct ucred *cred, struct mount *mp) 210895fab37eSRobert Watson { 210995fab37eSRobert Watson 211095fab37eSRobert Watson MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 211195fab37eSRobert Watson &mp->mnt_fslabel); 211295fab37eSRobert Watson } 211395fab37eSRobert Watson 211495fab37eSRobert Watson int 211595fab37eSRobert Watson mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 211695fab37eSRobert Watson { 211795fab37eSRobert Watson int error; 211895fab37eSRobert Watson 211995fab37eSRobert Watson if (!mac_enforce_network) 212095fab37eSRobert Watson return (0); 212195fab37eSRobert Watson 212295fab37eSRobert Watson MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 212395fab37eSRobert Watson &ifnet->if_label); 212495fab37eSRobert Watson 212595fab37eSRobert Watson return (error); 212695fab37eSRobert Watson } 212795fab37eSRobert Watson 212895fab37eSRobert Watson static int 212995fab37eSRobert Watson mac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 213095fab37eSRobert Watson { 213195fab37eSRobert Watson int error; 213295fab37eSRobert Watson 213395fab37eSRobert Watson MAC_CHECK(check_cred_relabel, cred, newlabel); 213495fab37eSRobert Watson 213595fab37eSRobert Watson return (error); 213695fab37eSRobert Watson } 213795fab37eSRobert Watson 213895fab37eSRobert Watson int 213995fab37eSRobert Watson mac_check_cred_visible(struct ucred *u1, struct ucred *u2) 214095fab37eSRobert Watson { 214195fab37eSRobert Watson int error; 214295fab37eSRobert Watson 214395fab37eSRobert Watson if (!mac_enforce_process) 214495fab37eSRobert Watson return (0); 214595fab37eSRobert Watson 214695fab37eSRobert Watson MAC_CHECK(check_cred_visible, u1, u2); 214795fab37eSRobert Watson 214895fab37eSRobert Watson return (error); 214995fab37eSRobert Watson } 215095fab37eSRobert Watson 215195fab37eSRobert Watson int 215295fab37eSRobert Watson mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 215395fab37eSRobert Watson { 215495fab37eSRobert Watson int error; 215595fab37eSRobert Watson 215695fab37eSRobert Watson if (!mac_enforce_network) 215795fab37eSRobert Watson return (0); 215895fab37eSRobert Watson 215995fab37eSRobert Watson KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr")); 216095fab37eSRobert Watson if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED)) 216129e1b85fSBrooks Davis if_printf(ifnet, "not initialized\n"); 216295fab37eSRobert Watson 216395fab37eSRobert Watson MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 216495fab37eSRobert Watson &mbuf->m_pkthdr.label); 216595fab37eSRobert Watson 216695fab37eSRobert Watson return (error); 216795fab37eSRobert Watson } 216895fab37eSRobert Watson 216995fab37eSRobert Watson int 2170e686e5aeSRobert Watson mac_check_kenv_dump(struct ucred *cred) 2171e686e5aeSRobert Watson { 2172e686e5aeSRobert Watson int error; 2173e686e5aeSRobert Watson 2174e686e5aeSRobert Watson if (!mac_enforce_system) 2175e686e5aeSRobert Watson return (0); 2176e686e5aeSRobert Watson 2177e686e5aeSRobert Watson MAC_CHECK(check_kenv_dump, cred); 2178e686e5aeSRobert Watson 2179e686e5aeSRobert Watson return (error); 2180e686e5aeSRobert Watson } 2181e686e5aeSRobert Watson 2182e686e5aeSRobert Watson int 2183e686e5aeSRobert Watson mac_check_kenv_get(struct ucred *cred, char *name) 2184e686e5aeSRobert Watson { 2185e686e5aeSRobert Watson int error; 2186e686e5aeSRobert Watson 2187e686e5aeSRobert Watson if (!mac_enforce_system) 2188e686e5aeSRobert Watson return (0); 2189e686e5aeSRobert Watson 2190e686e5aeSRobert Watson MAC_CHECK(check_kenv_get, cred, name); 2191e686e5aeSRobert Watson 2192e686e5aeSRobert Watson return (error); 2193e686e5aeSRobert Watson } 2194e686e5aeSRobert Watson 2195e686e5aeSRobert Watson int 2196e686e5aeSRobert Watson mac_check_kenv_set(struct ucred *cred, char *name, char *value) 2197e686e5aeSRobert Watson { 2198e686e5aeSRobert Watson int error; 2199e686e5aeSRobert Watson 2200e686e5aeSRobert Watson if (!mac_enforce_system) 2201e686e5aeSRobert Watson return (0); 2202e686e5aeSRobert Watson 2203e686e5aeSRobert Watson MAC_CHECK(check_kenv_set, cred, name, value); 2204e686e5aeSRobert Watson 2205e686e5aeSRobert Watson return (error); 2206e686e5aeSRobert Watson } 2207e686e5aeSRobert Watson 2208e686e5aeSRobert Watson int 2209e686e5aeSRobert Watson mac_check_kenv_unset(struct ucred *cred, char *name) 2210e686e5aeSRobert Watson { 2211e686e5aeSRobert Watson int error; 2212e686e5aeSRobert Watson 2213e686e5aeSRobert Watson if (!mac_enforce_system) 2214e686e5aeSRobert Watson return (0); 2215e686e5aeSRobert Watson 2216e686e5aeSRobert Watson MAC_CHECK(check_kenv_unset, cred, name); 2217e686e5aeSRobert Watson 2218e686e5aeSRobert Watson return (error); 2219e686e5aeSRobert Watson } 2220e686e5aeSRobert Watson 2221e686e5aeSRobert Watson int 222295fab37eSRobert Watson mac_check_mount_stat(struct ucred *cred, struct mount *mount) 222395fab37eSRobert Watson { 222495fab37eSRobert Watson int error; 222595fab37eSRobert Watson 222695fab37eSRobert Watson if (!mac_enforce_fs) 222795fab37eSRobert Watson return (0); 222895fab37eSRobert Watson 222995fab37eSRobert Watson MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 223095fab37eSRobert Watson 223195fab37eSRobert Watson return (error); 223295fab37eSRobert Watson } 223395fab37eSRobert Watson 223495fab37eSRobert Watson int 223595fab37eSRobert Watson mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 223695fab37eSRobert Watson void *data) 223795fab37eSRobert Watson { 223895fab37eSRobert Watson int error; 223995fab37eSRobert Watson 22401aa37f53SRobert Watson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 22411aa37f53SRobert Watson 22421aa37f53SRobert Watson if (!mac_enforce_pipe) 22431aa37f53SRobert Watson return (0); 22441aa37f53SRobert Watson 224595fab37eSRobert Watson MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 224695fab37eSRobert Watson 224795fab37eSRobert Watson return (error); 224895fab37eSRobert Watson } 224995fab37eSRobert Watson 225095fab37eSRobert Watson int 2251c024c3eeSRobert Watson mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 225295fab37eSRobert Watson { 225395fab37eSRobert Watson int error; 225495fab37eSRobert Watson 22551aa37f53SRobert Watson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 22561aa37f53SRobert Watson 22571aa37f53SRobert Watson if (!mac_enforce_pipe) 22581aa37f53SRobert Watson return (0); 22591aa37f53SRobert Watson 2260c024c3eeSRobert Watson MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2261c024c3eeSRobert Watson 2262c024c3eeSRobert Watson return (error); 2263c024c3eeSRobert Watson } 2264c024c3eeSRobert Watson 2265c024c3eeSRobert Watson int 2266c024c3eeSRobert Watson mac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2267c024c3eeSRobert Watson { 2268c024c3eeSRobert Watson int error; 2269c024c3eeSRobert Watson 22701aa37f53SRobert Watson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 22711aa37f53SRobert Watson 22721aa37f53SRobert Watson if (!mac_enforce_pipe) 22731aa37f53SRobert Watson return (0); 22741aa37f53SRobert Watson 2275c024c3eeSRobert Watson MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 227695fab37eSRobert Watson 227795fab37eSRobert Watson return (error); 227895fab37eSRobert Watson } 227995fab37eSRobert Watson 228095fab37eSRobert Watson static int 228195fab37eSRobert Watson mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 228295fab37eSRobert Watson struct label *newlabel) 228395fab37eSRobert Watson { 228495fab37eSRobert Watson int error; 228595fab37eSRobert Watson 22861aa37f53SRobert Watson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 22871aa37f53SRobert Watson 22881aa37f53SRobert Watson if (!mac_enforce_pipe) 22891aa37f53SRobert Watson return (0); 22901aa37f53SRobert Watson 229195fab37eSRobert Watson MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 229295fab37eSRobert Watson 229395fab37eSRobert Watson return (error); 229495fab37eSRobert Watson } 229595fab37eSRobert Watson 229695fab37eSRobert Watson int 2297c024c3eeSRobert Watson mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2298c024c3eeSRobert Watson { 2299c024c3eeSRobert Watson int error; 2300c024c3eeSRobert Watson 23011aa37f53SRobert Watson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 23021aa37f53SRobert Watson 23031aa37f53SRobert Watson if (!mac_enforce_pipe) 23041aa37f53SRobert Watson return (0); 23051aa37f53SRobert Watson 2306c024c3eeSRobert Watson MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2307c024c3eeSRobert Watson 2308c024c3eeSRobert Watson return (error); 2309c024c3eeSRobert Watson } 2310c024c3eeSRobert Watson 2311c024c3eeSRobert Watson int 2312c024c3eeSRobert Watson mac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2313c024c3eeSRobert Watson { 2314c024c3eeSRobert Watson int error; 2315c024c3eeSRobert Watson 23161aa37f53SRobert Watson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 23171aa37f53SRobert Watson 23181aa37f53SRobert Watson if (!mac_enforce_pipe) 23191aa37f53SRobert Watson return (0); 23201aa37f53SRobert Watson 2321c024c3eeSRobert Watson MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2322c024c3eeSRobert Watson 2323c024c3eeSRobert Watson return (error); 2324c024c3eeSRobert Watson } 2325c024c3eeSRobert Watson 2326c024c3eeSRobert Watson int 232795fab37eSRobert Watson mac_check_proc_debug(struct ucred *cred, struct proc *proc) 232895fab37eSRobert Watson { 232995fab37eSRobert Watson int error; 233095fab37eSRobert Watson 2331b12baf55SRobert Watson PROC_LOCK_ASSERT(proc, MA_OWNED); 2332b12baf55SRobert Watson 233395fab37eSRobert Watson if (!mac_enforce_process) 233495fab37eSRobert Watson return (0); 233595fab37eSRobert Watson 233695fab37eSRobert Watson MAC_CHECK(check_proc_debug, cred, proc); 233795fab37eSRobert Watson 233895fab37eSRobert Watson return (error); 233995fab37eSRobert Watson } 234095fab37eSRobert Watson 234195fab37eSRobert Watson int 234295fab37eSRobert Watson mac_check_proc_sched(struct ucred *cred, struct proc *proc) 234395fab37eSRobert Watson { 234495fab37eSRobert Watson int error; 234595fab37eSRobert Watson 2346b12baf55SRobert Watson PROC_LOCK_ASSERT(proc, MA_OWNED); 2347b12baf55SRobert Watson 234895fab37eSRobert Watson if (!mac_enforce_process) 234995fab37eSRobert Watson return (0); 235095fab37eSRobert Watson 235195fab37eSRobert Watson MAC_CHECK(check_proc_sched, cred, proc); 235295fab37eSRobert Watson 235395fab37eSRobert Watson return (error); 235495fab37eSRobert Watson } 235595fab37eSRobert Watson 235695fab37eSRobert Watson int 235795fab37eSRobert Watson mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 235895fab37eSRobert Watson { 235995fab37eSRobert Watson int error; 236095fab37eSRobert Watson 2361b12baf55SRobert Watson PROC_LOCK_ASSERT(proc, MA_OWNED); 2362b12baf55SRobert Watson 236395fab37eSRobert Watson if (!mac_enforce_process) 236495fab37eSRobert Watson return (0); 236595fab37eSRobert Watson 236695fab37eSRobert Watson MAC_CHECK(check_proc_signal, cred, proc, signum); 236795fab37eSRobert Watson 236895fab37eSRobert Watson return (error); 236995fab37eSRobert Watson } 237095fab37eSRobert Watson 237195fab37eSRobert Watson int 237295fab37eSRobert Watson mac_check_socket_bind(struct ucred *ucred, struct socket *socket, 237395fab37eSRobert Watson struct sockaddr *sockaddr) 237495fab37eSRobert Watson { 237595fab37eSRobert Watson int error; 237695fab37eSRobert Watson 237795fab37eSRobert Watson if (!mac_enforce_socket) 237895fab37eSRobert Watson return (0); 237995fab37eSRobert Watson 238095fab37eSRobert Watson MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 238195fab37eSRobert Watson sockaddr); 238295fab37eSRobert Watson 238395fab37eSRobert Watson return (error); 238495fab37eSRobert Watson } 238595fab37eSRobert Watson 238695fab37eSRobert Watson int 238795fab37eSRobert Watson mac_check_socket_connect(struct ucred *cred, struct socket *socket, 238895fab37eSRobert Watson struct sockaddr *sockaddr) 238995fab37eSRobert Watson { 239095fab37eSRobert Watson int error; 239195fab37eSRobert Watson 239295fab37eSRobert Watson if (!mac_enforce_socket) 239395fab37eSRobert Watson return (0); 239495fab37eSRobert Watson 239595fab37eSRobert Watson MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 239695fab37eSRobert Watson sockaddr); 239795fab37eSRobert Watson 239895fab37eSRobert Watson return (error); 239995fab37eSRobert Watson } 240095fab37eSRobert Watson 240195fab37eSRobert Watson int 2402d61198e4SRobert Watson mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2403d61198e4SRobert Watson { 2404d61198e4SRobert Watson int error; 2405d61198e4SRobert Watson 2406d61198e4SRobert Watson if (!mac_enforce_socket) 2407d61198e4SRobert Watson return (0); 2408d61198e4SRobert Watson 2409d61198e4SRobert Watson MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2410d61198e4SRobert Watson &mbuf->m_pkthdr.label); 2411d61198e4SRobert Watson 2412d61198e4SRobert Watson return (error); 2413d61198e4SRobert Watson } 2414d61198e4SRobert Watson 2415d61198e4SRobert Watson int 241695fab37eSRobert Watson mac_check_socket_listen(struct ucred *cred, struct socket *socket) 241795fab37eSRobert Watson { 241895fab37eSRobert Watson int error; 241995fab37eSRobert Watson 242095fab37eSRobert Watson if (!mac_enforce_socket) 242195fab37eSRobert Watson return (0); 242295fab37eSRobert Watson 242395fab37eSRobert Watson MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 242495fab37eSRobert Watson return (error); 242595fab37eSRobert Watson } 242695fab37eSRobert Watson 2427b371c939SRobert Watson int 2428b371c939SRobert Watson mac_check_socket_receive(struct ucred *cred, struct socket *so) 2429b371c939SRobert Watson { 2430b371c939SRobert Watson int error; 2431b371c939SRobert Watson 2432b371c939SRobert Watson if (!mac_enforce_socket) 2433b371c939SRobert Watson return (0); 2434b371c939SRobert Watson 2435b371c939SRobert Watson MAC_CHECK(check_socket_receive, cred, so, &so->so_label); 2436b371c939SRobert Watson 2437b371c939SRobert Watson return (error); 2438b371c939SRobert Watson } 2439b371c939SRobert Watson 244095fab37eSRobert Watson static int 244195fab37eSRobert Watson mac_check_socket_relabel(struct ucred *cred, struct socket *socket, 244295fab37eSRobert Watson struct label *newlabel) 244395fab37eSRobert Watson { 244495fab37eSRobert Watson int error; 244595fab37eSRobert Watson 244695fab37eSRobert Watson MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 244795fab37eSRobert Watson newlabel); 244895fab37eSRobert Watson 244995fab37eSRobert Watson return (error); 245095fab37eSRobert Watson } 245195fab37eSRobert Watson 245295fab37eSRobert Watson int 2453b371c939SRobert Watson mac_check_socket_send(struct ucred *cred, struct socket *so) 2454b371c939SRobert Watson { 2455b371c939SRobert Watson int error; 2456b371c939SRobert Watson 2457b371c939SRobert Watson if (!mac_enforce_socket) 2458b371c939SRobert Watson return (0); 2459b371c939SRobert Watson 2460b371c939SRobert Watson MAC_CHECK(check_socket_send, cred, so, &so->so_label); 2461b371c939SRobert Watson 2462b371c939SRobert Watson return (error); 2463b371c939SRobert Watson } 2464b371c939SRobert Watson 2465b371c939SRobert Watson int 246695fab37eSRobert Watson mac_check_socket_visible(struct ucred *cred, struct socket *socket) 246795fab37eSRobert Watson { 246895fab37eSRobert Watson int error; 246995fab37eSRobert Watson 247095fab37eSRobert Watson if (!mac_enforce_socket) 247195fab37eSRobert Watson return (0); 247295fab37eSRobert Watson 247395fab37eSRobert Watson MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 247495fab37eSRobert Watson 247595fab37eSRobert Watson return (error); 247695fab37eSRobert Watson } 247795fab37eSRobert Watson 247895fab37eSRobert Watson int 2479a2ecb9b7SRobert Watson mac_check_system_reboot(struct ucred *cred, int howto) 2480a2ecb9b7SRobert Watson { 2481a2ecb9b7SRobert Watson int error; 2482a2ecb9b7SRobert Watson 24839e913ebdSRobert Watson if (!mac_enforce_system) 2484a2ecb9b7SRobert Watson return (0); 2485a2ecb9b7SRobert Watson 2486a2ecb9b7SRobert Watson MAC_CHECK(check_system_reboot, cred, howto); 24879e913ebdSRobert Watson 2488a2ecb9b7SRobert Watson return (error); 2489a2ecb9b7SRobert Watson } 2490a2ecb9b7SRobert Watson 2491a2ecb9b7SRobert Watson int 24924b8d5f2dSRobert Watson mac_check_system_settime(struct ucred *cred) 24934b8d5f2dSRobert Watson { 24944b8d5f2dSRobert Watson int error; 24954b8d5f2dSRobert Watson 24964b8d5f2dSRobert Watson if (!mac_enforce_system) 24974b8d5f2dSRobert Watson return (0); 24984b8d5f2dSRobert Watson 24994b8d5f2dSRobert Watson MAC_CHECK(check_system_settime, cred); 25004b8d5f2dSRobert Watson 25014b8d5f2dSRobert Watson return (error); 25024b8d5f2dSRobert Watson } 25034b8d5f2dSRobert Watson 25044b8d5f2dSRobert Watson int 250503ce2c0cSRobert Watson mac_check_system_swapon(struct ucred *cred, struct vnode *vp) 250603ce2c0cSRobert Watson { 250703ce2c0cSRobert Watson int error; 250803ce2c0cSRobert Watson 250903ce2c0cSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon"); 251003ce2c0cSRobert Watson 25119e913ebdSRobert Watson if (!mac_enforce_system) 251203ce2c0cSRobert Watson return (0); 251303ce2c0cSRobert Watson 251403ce2c0cSRobert Watson MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label); 251503ce2c0cSRobert Watson return (error); 251603ce2c0cSRobert Watson } 251703ce2c0cSRobert Watson 251803ce2c0cSRobert Watson int 2519d3fc69eeSRobert Watson mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 2520d3fc69eeSRobert Watson void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 2521d3fc69eeSRobert Watson { 2522d3fc69eeSRobert Watson int error; 2523d3fc69eeSRobert Watson 2524d3fc69eeSRobert Watson /* 2525d3fc69eeSRobert Watson * XXXMAC: We're very much like to assert the SYSCTL_LOCK here, 2526d3fc69eeSRobert Watson * but since it's not exported from kern_sysctl.c, we can't. 2527d3fc69eeSRobert Watson */ 25289e913ebdSRobert Watson if (!mac_enforce_system) 2529d3fc69eeSRobert Watson return (0); 2530d3fc69eeSRobert Watson 2531d3fc69eeSRobert Watson MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp, 2532d3fc69eeSRobert Watson inkernel, new, newlen); 2533d3fc69eeSRobert Watson 2534d3fc69eeSRobert Watson return (error); 2535d3fc69eeSRobert Watson } 2536d3fc69eeSRobert Watson 2537d3fc69eeSRobert Watson int 253895fab37eSRobert Watson mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 253995fab37eSRobert Watson struct ifnet *ifnet) 254095fab37eSRobert Watson { 2541f7b951a8SRobert Watson char *elements, *buffer; 2542f7b951a8SRobert Watson struct mac mac; 254395fab37eSRobert Watson int error; 254495fab37eSRobert Watson 2545f7b951a8SRobert Watson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 254695fab37eSRobert Watson if (error) 254795fab37eSRobert Watson return (error); 254895fab37eSRobert Watson 2549f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 2550f7b951a8SRobert Watson if (error) 2551f7b951a8SRobert Watson return (error); 2552f7b951a8SRobert Watson 2553f7b951a8SRobert Watson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2554f7b951a8SRobert Watson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 2555f7b951a8SRobert Watson if (error) { 2556f7b951a8SRobert Watson free(elements, M_MACTEMP); 2557f7b951a8SRobert Watson return (error); 2558f7b951a8SRobert Watson } 2559f7b951a8SRobert Watson 2560f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2561f7b951a8SRobert Watson error = mac_externalize_ifnet_label(&ifnet->if_label, elements, 2562f7b951a8SRobert Watson buffer, mac.m_buflen, M_WAITOK); 2563f7b951a8SRobert Watson if (error == 0) 2564f7b951a8SRobert Watson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 2565f7b951a8SRobert Watson 2566f7b951a8SRobert Watson free(buffer, M_MACTEMP); 2567f7b951a8SRobert Watson free(elements, M_MACTEMP); 2568f7b951a8SRobert Watson 2569f7b951a8SRobert Watson return (error); 257095fab37eSRobert Watson } 257195fab37eSRobert Watson 257295fab37eSRobert Watson int 257395fab37eSRobert Watson mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 257495fab37eSRobert Watson struct ifnet *ifnet) 257595fab37eSRobert Watson { 257695fab37eSRobert Watson struct label intlabel; 2577f7b951a8SRobert Watson struct mac mac; 2578f7b951a8SRobert Watson char *buffer; 257995fab37eSRobert Watson int error; 258095fab37eSRobert Watson 2581f7b951a8SRobert Watson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 258295fab37eSRobert Watson if (error) 258395fab37eSRobert Watson return (error); 258495fab37eSRobert Watson 2585f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 258695fab37eSRobert Watson if (error) 258795fab37eSRobert Watson return (error); 258895fab37eSRobert Watson 2589f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2590f7b951a8SRobert Watson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 2591f7b951a8SRobert Watson if (error) { 2592f7b951a8SRobert Watson free(buffer, M_MACTEMP); 2593f7b951a8SRobert Watson return (error); 2594f7b951a8SRobert Watson } 2595f7b951a8SRobert Watson 2596f7b951a8SRobert Watson mac_init_ifnet_label(&intlabel); 2597f7b951a8SRobert Watson error = mac_internalize_ifnet_label(&intlabel, buffer); 2598f7b951a8SRobert Watson free(buffer, M_MACTEMP); 2599f7b951a8SRobert Watson if (error) { 2600f7b951a8SRobert Watson mac_destroy_ifnet_label(&intlabel); 2601f7b951a8SRobert Watson return (error); 2602f7b951a8SRobert Watson } 2603f7b951a8SRobert Watson 260495fab37eSRobert Watson /* 260595fab37eSRobert Watson * XXX: Note that this is a redundant privilege check, since 260695fab37eSRobert Watson * policies impose this check themselves if required by the 260795fab37eSRobert Watson * policy. Eventually, this should go away. 260895fab37eSRobert Watson */ 260995fab37eSRobert Watson error = suser_cred(cred, 0); 2610f7b951a8SRobert Watson if (error) { 2611f7b951a8SRobert Watson mac_destroy_ifnet_label(&intlabel); 2612f7b951a8SRobert Watson return (error); 2613f7b951a8SRobert Watson } 261495fab37eSRobert Watson 261595fab37eSRobert Watson MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 261695fab37eSRobert Watson &intlabel); 2617f7b951a8SRobert Watson if (error) { 2618f7b951a8SRobert Watson mac_destroy_ifnet_label(&intlabel); 2619f7b951a8SRobert Watson return (error); 2620f7b951a8SRobert Watson } 262195fab37eSRobert Watson 262295fab37eSRobert Watson MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 262395fab37eSRobert Watson 2624f7b951a8SRobert Watson mac_destroy_ifnet_label(&intlabel); 2625f7b951a8SRobert Watson return (0); 262695fab37eSRobert Watson } 262795fab37eSRobert Watson 262895fab37eSRobert Watson void 262995fab37eSRobert Watson mac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp) 263095fab37eSRobert Watson { 263195fab37eSRobert Watson 263295fab37eSRobert Watson MAC_PERFORM(create_devfs_vnode, de, &de->de_label, vp, &vp->v_label); 263395fab37eSRobert Watson } 263495fab37eSRobert Watson 263595fab37eSRobert Watson void 263695fab37eSRobert Watson mac_create_devfs_device(dev_t dev, struct devfs_dirent *de) 263795fab37eSRobert Watson { 263895fab37eSRobert Watson 263995fab37eSRobert Watson MAC_PERFORM(create_devfs_device, dev, de, &de->de_label); 264095fab37eSRobert Watson } 264195fab37eSRobert Watson 264274e62b1bSRobert Watson void 264374e62b1bSRobert Watson mac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd, 264474e62b1bSRobert Watson struct devfs_dirent *de) 264574e62b1bSRobert Watson { 264674e62b1bSRobert Watson 264774e62b1bSRobert Watson MAC_PERFORM(create_devfs_symlink, cred, dd, &dd->de_label, de, 264874e62b1bSRobert Watson &de->de_label); 264974e62b1bSRobert Watson } 265074e62b1bSRobert Watson 265195fab37eSRobert Watson void 265295fab37eSRobert Watson mac_create_devfs_directory(char *dirname, int dirnamelen, 265395fab37eSRobert Watson struct devfs_dirent *de) 265495fab37eSRobert Watson { 265595fab37eSRobert Watson 265695fab37eSRobert Watson MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de, 265795fab37eSRobert Watson &de->de_label); 265895fab37eSRobert Watson } 265995fab37eSRobert Watson 266095fab37eSRobert Watson int 266195fab37eSRobert Watson mac_setsockopt_label_set(struct ucred *cred, struct socket *so, 2662f7b951a8SRobert Watson struct mac *mac) 266395fab37eSRobert Watson { 266495fab37eSRobert Watson struct label intlabel; 2665f7b951a8SRobert Watson char *buffer; 266695fab37eSRobert Watson int error; 266795fab37eSRobert Watson 2668f7b951a8SRobert Watson error = mac_check_structmac_consistent(mac); 266995fab37eSRobert Watson if (error) 267095fab37eSRobert Watson return (error); 267195fab37eSRobert Watson 2672f7b951a8SRobert Watson buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 2673f7b951a8SRobert Watson error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); 2674f7b951a8SRobert Watson if (error) { 2675f7b951a8SRobert Watson free(buffer, M_MACTEMP); 2676f7b951a8SRobert Watson return (error); 2677f7b951a8SRobert Watson } 2678f7b951a8SRobert Watson 2679f7b951a8SRobert Watson mac_init_socket_label(&intlabel, M_WAITOK); 2680f7b951a8SRobert Watson error = mac_internalize_socket_label(&intlabel, buffer); 2681f7b951a8SRobert Watson free(buffer, M_MACTEMP); 2682f7b951a8SRobert Watson if (error) { 2683f7b951a8SRobert Watson mac_destroy_socket_label(&intlabel); 2684f7b951a8SRobert Watson return (error); 2685f7b951a8SRobert Watson } 2686f7b951a8SRobert Watson 268795fab37eSRobert Watson mac_check_socket_relabel(cred, so, &intlabel); 268895fab37eSRobert Watson if (error) { 2689f7b951a8SRobert Watson mac_destroy_socket_label(&intlabel); 269095fab37eSRobert Watson return (error); 269195fab37eSRobert Watson } 269295fab37eSRobert Watson 269395fab37eSRobert Watson mac_relabel_socket(cred, so, &intlabel); 269495fab37eSRobert Watson 2695f7b951a8SRobert Watson mac_destroy_socket_label(&intlabel); 269695fab37eSRobert Watson return (0); 269795fab37eSRobert Watson } 269895fab37eSRobert Watson 269995fab37eSRobert Watson int 270095fab37eSRobert Watson mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 270195fab37eSRobert Watson { 270295fab37eSRobert Watson int error; 270395fab37eSRobert Watson 27041aa37f53SRobert Watson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 27051aa37f53SRobert Watson 270695fab37eSRobert Watson error = mac_check_pipe_relabel(cred, pipe, label); 270795fab37eSRobert Watson if (error) 270895fab37eSRobert Watson return (error); 270995fab37eSRobert Watson 271095fab37eSRobert Watson mac_relabel_pipe(cred, pipe, label); 271195fab37eSRobert Watson 271295fab37eSRobert Watson return (0); 271395fab37eSRobert Watson } 271495fab37eSRobert Watson 271595fab37eSRobert Watson int 271695fab37eSRobert Watson mac_getsockopt_label_get(struct ucred *cred, struct socket *so, 2717f7b951a8SRobert Watson struct mac *mac) 271895fab37eSRobert Watson { 2719f7b951a8SRobert Watson char *buffer, *elements; 2720f7b951a8SRobert Watson int error; 272195fab37eSRobert Watson 2722f7b951a8SRobert Watson error = mac_check_structmac_consistent(mac); 2723f7b951a8SRobert Watson if (error) 2724f7b951a8SRobert Watson return (error); 2725f7b951a8SRobert Watson 2726f7b951a8SRobert Watson elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 2727f7b951a8SRobert Watson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 2728f7b951a8SRobert Watson if (error) { 2729f7b951a8SRobert Watson free(elements, M_MACTEMP); 2730f7b951a8SRobert Watson return (error); 2731f7b951a8SRobert Watson } 2732f7b951a8SRobert Watson 2733f7b951a8SRobert Watson buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2734f7b951a8SRobert Watson error = mac_externalize_socket_label(&so->so_label, elements, 2735f7b951a8SRobert Watson buffer, mac->m_buflen, M_WAITOK); 2736f7b951a8SRobert Watson if (error == 0) 2737f7b951a8SRobert Watson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 2738f7b951a8SRobert Watson 2739f7b951a8SRobert Watson free(buffer, M_MACTEMP); 2740f7b951a8SRobert Watson free(elements, M_MACTEMP); 2741f7b951a8SRobert Watson 2742f7b951a8SRobert Watson return (error); 274395fab37eSRobert Watson } 274495fab37eSRobert Watson 274595fab37eSRobert Watson int 274695fab37eSRobert Watson mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 2747f7b951a8SRobert Watson struct mac *mac) 274895fab37eSRobert Watson { 2749f7b951a8SRobert Watson char *elements, *buffer; 2750f7b951a8SRobert Watson int error; 275195fab37eSRobert Watson 2752f7b951a8SRobert Watson error = mac_check_structmac_consistent(mac); 2753f7b951a8SRobert Watson if (error) 2754f7b951a8SRobert Watson return (error); 2755f7b951a8SRobert Watson 2756f7b951a8SRobert Watson elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 2757f7b951a8SRobert Watson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 2758f7b951a8SRobert Watson if (error) { 2759f7b951a8SRobert Watson free(elements, M_MACTEMP); 2760f7b951a8SRobert Watson return (error); 2761f7b951a8SRobert Watson } 2762f7b951a8SRobert Watson 2763f7b951a8SRobert Watson buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2764f7b951a8SRobert Watson error = mac_externalize_socket_peer_label(&so->so_peerlabel, 2765f7b951a8SRobert Watson elements, buffer, mac->m_buflen, M_WAITOK); 2766f7b951a8SRobert Watson if (error == 0) 2767f7b951a8SRobert Watson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 2768f7b951a8SRobert Watson 2769f7b951a8SRobert Watson free(buffer, M_MACTEMP); 2770f7b951a8SRobert Watson free(elements, M_MACTEMP); 2771f7b951a8SRobert Watson 2772f7b951a8SRobert Watson return (error); 277395fab37eSRobert Watson } 277495fab37eSRobert Watson 277595fab37eSRobert Watson /* 277695fab37eSRobert Watson * Implementation of VOP_SETLABEL() that relies on extended attributes 277795fab37eSRobert Watson * to store label data. Can be referenced by filesystems supporting 277895fab37eSRobert Watson * extended attributes. 277995fab37eSRobert Watson */ 278095fab37eSRobert Watson int 278195fab37eSRobert Watson vop_stdsetlabel_ea(struct vop_setlabel_args *ap) 278295fab37eSRobert Watson { 278395fab37eSRobert Watson struct vnode *vp = ap->a_vp; 278495fab37eSRobert Watson struct label *intlabel = ap->a_label; 278595fab37eSRobert Watson int error; 278695fab37eSRobert Watson 278795fab37eSRobert Watson ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 278895fab37eSRobert Watson 2789763bbd2fSRobert Watson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 2790763bbd2fSRobert Watson return (EOPNOTSUPP); 279195fab37eSRobert Watson 2792763bbd2fSRobert Watson error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel); 279395fab37eSRobert Watson if (error) 279495fab37eSRobert Watson return (error); 279595fab37eSRobert Watson 279695fab37eSRobert Watson mac_relabel_vnode(ap->a_cred, vp, intlabel); 279795fab37eSRobert Watson 279895fab37eSRobert Watson return (0); 279995fab37eSRobert Watson } 280095fab37eSRobert Watson 280195fab37eSRobert Watson static int 280295fab37eSRobert Watson vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 280395fab37eSRobert Watson { 280495fab37eSRobert Watson int error; 280595fab37eSRobert Watson 280695fab37eSRobert Watson if (vp->v_mount == NULL) { 280795fab37eSRobert Watson /* printf("vn_setlabel: null v_mount\n"); */ 280806be2aaaSNate Lawson if (vp->v_type != VNON) 280906be2aaaSNate Lawson printf("vn_setlabel: null v_mount with non-VNON\n"); 281095fab37eSRobert Watson return (EBADF); 281195fab37eSRobert Watson } 281295fab37eSRobert Watson 281395fab37eSRobert Watson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 281495fab37eSRobert Watson return (EOPNOTSUPP); 281595fab37eSRobert Watson 281695fab37eSRobert Watson /* 281795fab37eSRobert Watson * Multi-phase commit. First check the policies to confirm the 281895fab37eSRobert Watson * change is OK. Then commit via the filesystem. Finally, 281995fab37eSRobert Watson * update the actual vnode label. Question: maybe the filesystem 282095fab37eSRobert Watson * should update the vnode at the end as part of VOP_SETLABEL()? 282195fab37eSRobert Watson */ 282295fab37eSRobert Watson error = mac_check_vnode_relabel(cred, vp, intlabel); 282395fab37eSRobert Watson if (error) 282495fab37eSRobert Watson return (error); 282595fab37eSRobert Watson 282695fab37eSRobert Watson /* 282795fab37eSRobert Watson * VADMIN provides the opportunity for the filesystem to make 282895fab37eSRobert Watson * decisions about who is and is not able to modify labels 282995fab37eSRobert Watson * and protections on files. This might not be right. We can't 283095fab37eSRobert Watson * assume VOP_SETLABEL() will do it, because we might implement 283195fab37eSRobert Watson * that as part of vop_stdsetlabel_ea(). 283295fab37eSRobert Watson */ 283395fab37eSRobert Watson error = VOP_ACCESS(vp, VADMIN, cred, curthread); 283495fab37eSRobert Watson if (error) 283595fab37eSRobert Watson return (error); 283695fab37eSRobert Watson 283795fab37eSRobert Watson error = VOP_SETLABEL(vp, intlabel, cred, curthread); 283895fab37eSRobert Watson if (error) 283995fab37eSRobert Watson return (error); 284095fab37eSRobert Watson 284195fab37eSRobert Watson return (0); 284295fab37eSRobert Watson } 284395fab37eSRobert Watson 2844f7b951a8SRobert Watson int 2845f7b951a8SRobert Watson __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 2846f7b951a8SRobert Watson { 2847f7b951a8SRobert Watson char *elements, *buffer; 2848f7b951a8SRobert Watson struct mac mac; 2849f7b951a8SRobert Watson struct proc *tproc; 2850f7b951a8SRobert Watson struct ucred *tcred; 2851f7b951a8SRobert Watson int error; 2852f7b951a8SRobert Watson 2853f7b951a8SRobert Watson error = copyin(SCARG(uap, mac_p), &mac, sizeof(mac)); 2854f7b951a8SRobert Watson if (error) 2855f7b951a8SRobert Watson return (error); 2856f7b951a8SRobert Watson 2857f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 2858f7b951a8SRobert Watson if (error) 2859f7b951a8SRobert Watson return (error); 2860f7b951a8SRobert Watson 2861f7b951a8SRobert Watson tproc = pfind(uap->pid); 2862f7b951a8SRobert Watson if (tproc == NULL) 2863f7b951a8SRobert Watson return (ESRCH); 2864f7b951a8SRobert Watson 2865f7b951a8SRobert Watson tcred = NULL; /* Satisfy gcc. */ 2866f7b951a8SRobert Watson error = p_cansee(td, tproc); 2867f7b951a8SRobert Watson if (error == 0) 2868f7b951a8SRobert Watson tcred = crhold(tproc->p_ucred); 2869f7b951a8SRobert Watson PROC_UNLOCK(tproc); 2870f7b951a8SRobert Watson if (error) 2871f7b951a8SRobert Watson return (error); 2872f7b951a8SRobert Watson 2873f7b951a8SRobert Watson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2874f7b951a8SRobert Watson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 2875f7b951a8SRobert Watson if (error) { 2876f7b951a8SRobert Watson free(elements, M_MACTEMP); 2877f7b951a8SRobert Watson crfree(tcred); 2878f7b951a8SRobert Watson return (error); 2879f7b951a8SRobert Watson } 2880f7b951a8SRobert Watson 2881f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2882f7b951a8SRobert Watson error = mac_externalize_cred_label(&tcred->cr_label, elements, 2883f7b951a8SRobert Watson buffer, mac.m_buflen, M_WAITOK); 2884f7b951a8SRobert Watson if (error == 0) 2885f7b951a8SRobert Watson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 2886f7b951a8SRobert Watson 2887f7b951a8SRobert Watson free(buffer, M_MACTEMP); 2888f7b951a8SRobert Watson free(elements, M_MACTEMP); 2889f7b951a8SRobert Watson crfree(tcred); 2890f7b951a8SRobert Watson return (error); 2891f7b951a8SRobert Watson } 2892f7b951a8SRobert Watson 289395fab37eSRobert Watson /* 289495fab37eSRobert Watson * MPSAFE 289595fab37eSRobert Watson */ 289695fab37eSRobert Watson int 289795fab37eSRobert Watson __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 289895fab37eSRobert Watson { 2899f7b951a8SRobert Watson char *elements, *buffer; 2900f7b951a8SRobert Watson struct mac mac; 290195fab37eSRobert Watson int error; 290295fab37eSRobert Watson 2903f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 2904f7b951a8SRobert Watson if (error) 2905f7b951a8SRobert Watson return (error); 290695fab37eSRobert Watson 2907f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 2908f7b951a8SRobert Watson if (error) 2909f7b951a8SRobert Watson return (error); 2910f7b951a8SRobert Watson 2911f7b951a8SRobert Watson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2912f7b951a8SRobert Watson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 2913f7b951a8SRobert Watson if (error) { 2914f7b951a8SRobert Watson free(elements, M_MACTEMP); 2915f7b951a8SRobert Watson return (error); 2916f7b951a8SRobert Watson } 2917f7b951a8SRobert Watson 2918f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2919f7b951a8SRobert Watson error = mac_externalize_cred_label(&td->td_ucred->cr_label, 2920f7b951a8SRobert Watson elements, buffer, mac.m_buflen, M_WAITOK); 2921f7b951a8SRobert Watson if (error == 0) 2922f7b951a8SRobert Watson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 2923f7b951a8SRobert Watson 2924f7b951a8SRobert Watson free(buffer, M_MACTEMP); 2925f7b951a8SRobert Watson free(elements, M_MACTEMP); 292695fab37eSRobert Watson return (error); 292795fab37eSRobert Watson } 292895fab37eSRobert Watson 292995fab37eSRobert Watson /* 293095fab37eSRobert Watson * MPSAFE 293195fab37eSRobert Watson */ 293295fab37eSRobert Watson int 293395fab37eSRobert Watson __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 293495fab37eSRobert Watson { 293595fab37eSRobert Watson struct ucred *newcred, *oldcred; 293695fab37eSRobert Watson struct label intlabel; 2937f7b951a8SRobert Watson struct proc *p; 2938f7b951a8SRobert Watson struct mac mac; 2939f7b951a8SRobert Watson char *buffer; 294095fab37eSRobert Watson int error; 294195fab37eSRobert Watson 2942f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 294395fab37eSRobert Watson if (error) 294495fab37eSRobert Watson return (error); 294595fab37eSRobert Watson 2946f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 294795fab37eSRobert Watson if (error) 294895fab37eSRobert Watson return (error); 294995fab37eSRobert Watson 2950f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2951f7b951a8SRobert Watson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 2952f7b951a8SRobert Watson if (error) { 2953f7b951a8SRobert Watson free(buffer, M_MACTEMP); 2954f7b951a8SRobert Watson return (error); 2955f7b951a8SRobert Watson } 2956f7b951a8SRobert Watson 2957f7b951a8SRobert Watson mac_init_cred_label(&intlabel); 2958f7b951a8SRobert Watson error = mac_internalize_cred_label(&intlabel, buffer); 2959f7b951a8SRobert Watson free(buffer, M_MACTEMP); 2960f7b951a8SRobert Watson if (error) { 2961f7b951a8SRobert Watson mac_destroy_cred_label(&intlabel); 2962f7b951a8SRobert Watson return (error); 2963f7b951a8SRobert Watson } 2964f7b951a8SRobert Watson 296595fab37eSRobert Watson newcred = crget(); 296695fab37eSRobert Watson 296795fab37eSRobert Watson p = td->td_proc; 296895fab37eSRobert Watson PROC_LOCK(p); 296995fab37eSRobert Watson oldcred = p->p_ucred; 297095fab37eSRobert Watson 297195fab37eSRobert Watson error = mac_check_cred_relabel(oldcred, &intlabel); 297295fab37eSRobert Watson if (error) { 297395fab37eSRobert Watson PROC_UNLOCK(p); 297495fab37eSRobert Watson crfree(newcred); 2975f7b951a8SRobert Watson goto out; 297695fab37eSRobert Watson } 297795fab37eSRobert Watson 297895fab37eSRobert Watson setsugid(p); 297995fab37eSRobert Watson crcopy(newcred, oldcred); 298095fab37eSRobert Watson mac_relabel_cred(newcred, &intlabel); 298195fab37eSRobert Watson p->p_ucred = newcred; 2982e5cb5e37SRobert Watson 2983e5cb5e37SRobert Watson /* 2984e5cb5e37SRobert Watson * Grab additional reference for use while revoking mmaps, prior 2985e5cb5e37SRobert Watson * to releasing the proc lock and sharing the cred. 2986e5cb5e37SRobert Watson */ 2987e5cb5e37SRobert Watson crhold(newcred); 298895fab37eSRobert Watson PROC_UNLOCK(p); 2989e5cb5e37SRobert Watson 2990f7b951a8SRobert Watson if (mac_enforce_vm) { 299116140035SRobert Watson mtx_lock(&Giant); 2992e5cb5e37SRobert Watson mac_cred_mmapped_drop_perms(td, newcred); 299316140035SRobert Watson mtx_unlock(&Giant); 2994f7b951a8SRobert Watson } 2995e5cb5e37SRobert Watson 2996e5cb5e37SRobert Watson crfree(newcred); /* Free revocation reference. */ 299795fab37eSRobert Watson crfree(oldcred); 2998f7b951a8SRobert Watson 2999f7b951a8SRobert Watson out: 3000f7b951a8SRobert Watson mac_destroy_cred_label(&intlabel); 3001f7b951a8SRobert Watson return (error); 300295fab37eSRobert Watson } 300395fab37eSRobert Watson 300495fab37eSRobert Watson /* 300595fab37eSRobert Watson * MPSAFE 300695fab37eSRobert Watson */ 300795fab37eSRobert Watson int 300895fab37eSRobert Watson __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 300995fab37eSRobert Watson { 3010f7b951a8SRobert Watson char *elements, *buffer; 3011f7b951a8SRobert Watson struct label intlabel; 301295fab37eSRobert Watson struct file *fp; 3013f7b951a8SRobert Watson struct mac mac; 301495fab37eSRobert Watson struct vnode *vp; 301595fab37eSRobert Watson struct pipe *pipe; 3016f7b951a8SRobert Watson short label_type; 301795fab37eSRobert Watson int error; 301895fab37eSRobert Watson 3019f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3020f7b951a8SRobert Watson if (error) 3021f7b951a8SRobert Watson return (error); 302295fab37eSRobert Watson 3023f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 3024f7b951a8SRobert Watson if (error) 3025f7b951a8SRobert Watson return (error); 3026f7b951a8SRobert Watson 3027f7b951a8SRobert Watson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3028f7b951a8SRobert Watson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3029f7b951a8SRobert Watson if (error) { 3030f7b951a8SRobert Watson free(elements, M_MACTEMP); 3031f7b951a8SRobert Watson return (error); 3032f7b951a8SRobert Watson } 3033f7b951a8SRobert Watson 3034f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3035f7b951a8SRobert Watson mtx_lock(&Giant); /* VFS */ 303695fab37eSRobert Watson error = fget(td, SCARG(uap, fd), &fp); 303795fab37eSRobert Watson if (error) 303895fab37eSRobert Watson goto out; 303995fab37eSRobert Watson 3040f7b951a8SRobert Watson label_type = fp->f_type; 304195fab37eSRobert Watson switch (fp->f_type) { 304295fab37eSRobert Watson case DTYPE_FIFO: 304395fab37eSRobert Watson case DTYPE_VNODE: 304495fab37eSRobert Watson vp = (struct vnode *)fp->f_data; 304595fab37eSRobert Watson 3046f7b951a8SRobert Watson mac_init_vnode_label(&intlabel); 3047f7b951a8SRobert Watson 304895fab37eSRobert Watson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3049f7b951a8SRobert Watson mac_copy_vnode_label(&vp->v_label, &intlabel); 305095fab37eSRobert Watson VOP_UNLOCK(vp, 0, td); 3051f7b951a8SRobert Watson 305295fab37eSRobert Watson break; 305395fab37eSRobert Watson case DTYPE_PIPE: 305495fab37eSRobert Watson pipe = (struct pipe *)fp->f_data; 3055f7b951a8SRobert Watson 3056f7b951a8SRobert Watson mac_init_pipe_label(&intlabel); 3057f7b951a8SRobert Watson 3058f7b951a8SRobert Watson PIPE_LOCK(pipe); 3059f7b951a8SRobert Watson mac_copy_pipe_label(pipe->pipe_label, &intlabel); 3060f7b951a8SRobert Watson PIPE_UNLOCK(pipe); 306195fab37eSRobert Watson break; 306295fab37eSRobert Watson default: 306395fab37eSRobert Watson error = EINVAL; 3064f7b951a8SRobert Watson fdrop(fp, td); 3065f7b951a8SRobert Watson goto out; 3066f7b951a8SRobert Watson } 3067f7b951a8SRobert Watson fdrop(fp, td); 3068f7b951a8SRobert Watson 3069f7b951a8SRobert Watson switch (label_type) { 3070f7b951a8SRobert Watson case DTYPE_FIFO: 3071f7b951a8SRobert Watson case DTYPE_VNODE: 3072f7b951a8SRobert Watson if (error == 0) 3073f7b951a8SRobert Watson error = mac_externalize_vnode_label(&intlabel, 3074f7b951a8SRobert Watson elements, buffer, mac.m_buflen, M_WAITOK); 3075f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 3076f7b951a8SRobert Watson break; 3077f7b951a8SRobert Watson case DTYPE_PIPE: 3078f7b951a8SRobert Watson error = mac_externalize_pipe_label(&intlabel, elements, 3079f7b951a8SRobert Watson buffer, mac.m_buflen, M_WAITOK); 3080f7b951a8SRobert Watson mac_destroy_pipe_label(&intlabel); 3081f7b951a8SRobert Watson break; 3082f7b951a8SRobert Watson default: 3083f7b951a8SRobert Watson panic("__mac_get_fd: corrupted label_type"); 308495fab37eSRobert Watson } 308595fab37eSRobert Watson 308695fab37eSRobert Watson if (error == 0) 3087f7b951a8SRobert Watson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 308895fab37eSRobert Watson 308995fab37eSRobert Watson out: 3090f7b951a8SRobert Watson mtx_unlock(&Giant); /* VFS */ 3091f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3092f7b951a8SRobert Watson free(elements, M_MACTEMP); 3093f7b951a8SRobert Watson 309495fab37eSRobert Watson return (error); 309595fab37eSRobert Watson } 309695fab37eSRobert Watson 309795fab37eSRobert Watson /* 309895fab37eSRobert Watson * MPSAFE 309995fab37eSRobert Watson */ 310095fab37eSRobert Watson int 310195fab37eSRobert Watson __mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 310295fab37eSRobert Watson { 3103f7b951a8SRobert Watson char *elements, *buffer; 310495fab37eSRobert Watson struct nameidata nd; 3105f7b951a8SRobert Watson struct label intlabel; 3106f7b951a8SRobert Watson struct mac mac; 310795fab37eSRobert Watson int error; 310895fab37eSRobert Watson 3109f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3110f7b951a8SRobert Watson if (error) 3111f7b951a8SRobert Watson return (error); 3112f7b951a8SRobert Watson 3113f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 3114f7b951a8SRobert Watson if (error) 3115f7b951a8SRobert Watson return (error); 3116f7b951a8SRobert Watson 3117f7b951a8SRobert Watson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3118f7b951a8SRobert Watson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3119f7b951a8SRobert Watson if (error) { 3120f7b951a8SRobert Watson free(elements, M_MACTEMP); 3121f7b951a8SRobert Watson return (error); 3122f7b951a8SRobert Watson } 3123f7b951a8SRobert Watson 3124f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3125f7b951a8SRobert Watson mtx_lock(&Giant); /* VFS */ 3126f7b951a8SRobert Watson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3127f7b951a8SRobert Watson td); 312895fab37eSRobert Watson error = namei(&nd); 312995fab37eSRobert Watson if (error) 313095fab37eSRobert Watson goto out; 313195fab37eSRobert Watson 3132f7b951a8SRobert Watson mac_init_vnode_label(&intlabel); 3133f7b951a8SRobert Watson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3134763bbd2fSRobert Watson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3135763bbd2fSRobert Watson mac.m_buflen, M_WAITOK); 3136f7b951a8SRobert Watson 313795fab37eSRobert Watson NDFREE(&nd, 0); 3138f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 3139f7b951a8SRobert Watson 3140f7b951a8SRobert Watson if (error == 0) 3141f7b951a8SRobert Watson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3142f7b951a8SRobert Watson 3143f7b951a8SRobert Watson out: 3144f7b951a8SRobert Watson mtx_unlock(&Giant); /* VFS */ 3145f7b951a8SRobert Watson 3146f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3147f7b951a8SRobert Watson free(elements, M_MACTEMP); 3148f7b951a8SRobert Watson 3149f7b951a8SRobert Watson return (error); 3150f7b951a8SRobert Watson } 3151f7b951a8SRobert Watson 3152f7b951a8SRobert Watson /* 3153f7b951a8SRobert Watson * MPSAFE 3154f7b951a8SRobert Watson */ 3155f7b951a8SRobert Watson int 3156f7b951a8SRobert Watson __mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3157f7b951a8SRobert Watson { 3158f7b951a8SRobert Watson char *elements, *buffer; 3159f7b951a8SRobert Watson struct nameidata nd; 3160f7b951a8SRobert Watson struct label intlabel; 3161f7b951a8SRobert Watson struct mac mac; 3162f7b951a8SRobert Watson int error; 3163f7b951a8SRobert Watson 3164f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3165f7b951a8SRobert Watson if (error) 3166f7b951a8SRobert Watson return (error); 3167f7b951a8SRobert Watson 3168f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 3169f7b951a8SRobert Watson if (error) 3170f7b951a8SRobert Watson return (error); 3171f7b951a8SRobert Watson 3172f7b951a8SRobert Watson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3173f7b951a8SRobert Watson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3174f7b951a8SRobert Watson if (error) { 3175f7b951a8SRobert Watson free(elements, M_MACTEMP); 3176f7b951a8SRobert Watson return (error); 3177f7b951a8SRobert Watson } 3178f7b951a8SRobert Watson 3179f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3180f7b951a8SRobert Watson mtx_lock(&Giant); /* VFS */ 3181f7b951a8SRobert Watson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3182f7b951a8SRobert Watson td); 3183f7b951a8SRobert Watson error = namei(&nd); 318495fab37eSRobert Watson if (error) 318595fab37eSRobert Watson goto out; 318695fab37eSRobert Watson 3187f7b951a8SRobert Watson mac_init_vnode_label(&intlabel); 3188f7b951a8SRobert Watson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3189763bbd2fSRobert Watson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3190763bbd2fSRobert Watson mac.m_buflen, M_WAITOK); 3191f7b951a8SRobert Watson NDFREE(&nd, 0); 3192f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 3193f7b951a8SRobert Watson 3194f7b951a8SRobert Watson if (error == 0) 3195f7b951a8SRobert Watson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 319695fab37eSRobert Watson 319795fab37eSRobert Watson out: 3198f7b951a8SRobert Watson mtx_unlock(&Giant); /* VFS */ 3199f7b951a8SRobert Watson 3200f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3201f7b951a8SRobert Watson free(elements, M_MACTEMP); 3202f7b951a8SRobert Watson 320395fab37eSRobert Watson return (error); 320495fab37eSRobert Watson } 320595fab37eSRobert Watson 320695fab37eSRobert Watson /* 320795fab37eSRobert Watson * MPSAFE 320895fab37eSRobert Watson */ 320995fab37eSRobert Watson int 321095fab37eSRobert Watson __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 321195fab37eSRobert Watson { 321295fab37eSRobert Watson struct label intlabel; 3213f7b951a8SRobert Watson struct pipe *pipe; 3214f7b951a8SRobert Watson struct file *fp; 321595fab37eSRobert Watson struct mount *mp; 321695fab37eSRobert Watson struct vnode *vp; 3217f7b951a8SRobert Watson struct mac mac; 3218f7b951a8SRobert Watson char *buffer; 321995fab37eSRobert Watson int error; 322095fab37eSRobert Watson 3221f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3222f7b951a8SRobert Watson if (error) 3223f7b951a8SRobert Watson return (error); 3224f7b951a8SRobert Watson 3225f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 3226f7b951a8SRobert Watson if (error) 3227f7b951a8SRobert Watson return (error); 3228f7b951a8SRobert Watson 3229f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3230f7b951a8SRobert Watson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3231f7b951a8SRobert Watson if (error) { 3232f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3233f7b951a8SRobert Watson return (error); 3234f7b951a8SRobert Watson } 3235f7b951a8SRobert Watson 3236f7b951a8SRobert Watson mtx_lock(&Giant); /* VFS */ 3237f7b951a8SRobert Watson 323895fab37eSRobert Watson error = fget(td, SCARG(uap, fd), &fp); 323995fab37eSRobert Watson if (error) 3240f7b951a8SRobert Watson goto out; 324195fab37eSRobert Watson 324295fab37eSRobert Watson switch (fp->f_type) { 324395fab37eSRobert Watson case DTYPE_FIFO: 324495fab37eSRobert Watson case DTYPE_VNODE: 3245f7b951a8SRobert Watson mac_init_vnode_label(&intlabel); 3246f7b951a8SRobert Watson error = mac_internalize_vnode_label(&intlabel, buffer); 3247f7b951a8SRobert Watson if (error) { 3248f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 3249f7b951a8SRobert Watson break; 3250f7b951a8SRobert Watson } 3251f7b951a8SRobert Watson 325295fab37eSRobert Watson vp = (struct vnode *)fp->f_data; 325395fab37eSRobert Watson error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3254f7b951a8SRobert Watson if (error != 0) { 3255f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 325695fab37eSRobert Watson break; 3257f7b951a8SRobert Watson } 325895fab37eSRobert Watson 325995fab37eSRobert Watson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 326095fab37eSRobert Watson error = vn_setlabel(vp, &intlabel, td->td_ucred); 326195fab37eSRobert Watson VOP_UNLOCK(vp, 0, td); 326295fab37eSRobert Watson vn_finished_write(mp); 3263f7b951a8SRobert Watson 3264f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 326595fab37eSRobert Watson break; 3266f7b951a8SRobert Watson 326795fab37eSRobert Watson case DTYPE_PIPE: 3268f7b951a8SRobert Watson mac_init_pipe_label(&intlabel); 3269f7b951a8SRobert Watson error = mac_internalize_pipe_label(&intlabel, buffer); 3270f7b951a8SRobert Watson if (error == 0) { 327195fab37eSRobert Watson pipe = (struct pipe *)fp->f_data; 32721aa37f53SRobert Watson PIPE_LOCK(pipe); 3273f7b951a8SRobert Watson error = mac_pipe_label_set(td->td_ucred, pipe, 3274f7b951a8SRobert Watson &intlabel); 32751aa37f53SRobert Watson PIPE_UNLOCK(pipe); 3276f7b951a8SRobert Watson } 3277f7b951a8SRobert Watson 3278f7b951a8SRobert Watson mac_destroy_pipe_label(&intlabel); 327995fab37eSRobert Watson break; 3280f7b951a8SRobert Watson 328195fab37eSRobert Watson default: 328295fab37eSRobert Watson error = EINVAL; 328395fab37eSRobert Watson } 328495fab37eSRobert Watson 328595fab37eSRobert Watson fdrop(fp, td); 3286f7b951a8SRobert Watson out: 3287f7b951a8SRobert Watson mtx_unlock(&Giant); /* VFS */ 3288f7b951a8SRobert Watson 3289f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3290f7b951a8SRobert Watson 329195fab37eSRobert Watson return (error); 329295fab37eSRobert Watson } 329395fab37eSRobert Watson 329495fab37eSRobert Watson /* 329595fab37eSRobert Watson * MPSAFE 329695fab37eSRobert Watson */ 329795fab37eSRobert Watson int 329895fab37eSRobert Watson __mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 329995fab37eSRobert Watson { 330095fab37eSRobert Watson struct label intlabel; 3301f7b951a8SRobert Watson struct nameidata nd; 330295fab37eSRobert Watson struct mount *mp; 3303f7b951a8SRobert Watson struct mac mac; 3304f7b951a8SRobert Watson char *buffer; 330595fab37eSRobert Watson int error; 330695fab37eSRobert Watson 3307f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 330895fab37eSRobert Watson if (error) 3309f7b951a8SRobert Watson return (error); 331095fab37eSRobert Watson 3311f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 331295fab37eSRobert Watson if (error) 3313f7b951a8SRobert Watson return (error); 331495fab37eSRobert Watson 3315f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3316f7b951a8SRobert Watson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3317f7b951a8SRobert Watson if (error) { 3318f7b951a8SRobert Watson free(buffer, M_MACTEMP); 331995fab37eSRobert Watson return (error); 332095fab37eSRobert Watson } 332195fab37eSRobert Watson 3322f7b951a8SRobert Watson mac_init_vnode_label(&intlabel); 3323f7b951a8SRobert Watson error = mac_internalize_vnode_label(&intlabel, buffer); 3324f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3325f7b951a8SRobert Watson if (error) { 3326f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 3327f7b951a8SRobert Watson return (error); 3328f7b951a8SRobert Watson } 3329f7b951a8SRobert Watson 3330f7b951a8SRobert Watson mtx_lock(&Giant); /* VFS */ 3331f7b951a8SRobert Watson 3332f7b951a8SRobert Watson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3333f7b951a8SRobert Watson td); 3334f7b951a8SRobert Watson error = namei(&nd); 3335f7b951a8SRobert Watson if (error == 0) { 3336f7b951a8SRobert Watson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3337f7b951a8SRobert Watson if (error == 0) 3338f7b951a8SRobert Watson error = vn_setlabel(nd.ni_vp, &intlabel, 3339f7b951a8SRobert Watson td->td_ucred); 3340f7b951a8SRobert Watson vn_finished_write(mp); 3341f7b951a8SRobert Watson } 3342f7b951a8SRobert Watson 3343f7b951a8SRobert Watson NDFREE(&nd, 0); 3344f7b951a8SRobert Watson mtx_unlock(&Giant); /* VFS */ 3345f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 3346f7b951a8SRobert Watson 3347f7b951a8SRobert Watson return (error); 3348f7b951a8SRobert Watson } 3349f7b951a8SRobert Watson 3350f7b951a8SRobert Watson /* 3351f7b951a8SRobert Watson * MPSAFE 3352f7b951a8SRobert Watson */ 3353f7b951a8SRobert Watson int 3354f7b951a8SRobert Watson __mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3355f7b951a8SRobert Watson { 3356f7b951a8SRobert Watson struct label intlabel; 3357f7b951a8SRobert Watson struct nameidata nd; 3358f7b951a8SRobert Watson struct mount *mp; 3359f7b951a8SRobert Watson struct mac mac; 3360f7b951a8SRobert Watson char *buffer; 3361f7b951a8SRobert Watson int error; 3362f7b951a8SRobert Watson 3363f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3364f7b951a8SRobert Watson if (error) 3365f7b951a8SRobert Watson return (error); 3366f7b951a8SRobert Watson 3367f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 3368f7b951a8SRobert Watson if (error) 3369f7b951a8SRobert Watson return (error); 3370f7b951a8SRobert Watson 3371f7b951a8SRobert Watson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3372f7b951a8SRobert Watson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3373f7b951a8SRobert Watson if (error) { 3374f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3375f7b951a8SRobert Watson return (error); 3376f7b951a8SRobert Watson } 3377f7b951a8SRobert Watson 3378f7b951a8SRobert Watson mac_init_vnode_label(&intlabel); 3379f7b951a8SRobert Watson error = mac_internalize_vnode_label(&intlabel, buffer); 3380f7b951a8SRobert Watson free(buffer, M_MACTEMP); 3381f7b951a8SRobert Watson if (error) { 3382f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 3383f7b951a8SRobert Watson return (error); 3384f7b951a8SRobert Watson } 3385f7b951a8SRobert Watson 3386f7b951a8SRobert Watson mtx_lock(&Giant); /* VFS */ 3387f7b951a8SRobert Watson 3388f7b951a8SRobert Watson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3389f7b951a8SRobert Watson td); 3390f7b951a8SRobert Watson error = namei(&nd); 3391f7b951a8SRobert Watson if (error == 0) { 3392f7b951a8SRobert Watson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3393f7b951a8SRobert Watson if (error == 0) 3394f7b951a8SRobert Watson error = vn_setlabel(nd.ni_vp, &intlabel, 3395f7b951a8SRobert Watson td->td_ucred); 3396f7b951a8SRobert Watson vn_finished_write(mp); 3397f7b951a8SRobert Watson } 3398f7b951a8SRobert Watson 3399f7b951a8SRobert Watson NDFREE(&nd, 0); 3400f7b951a8SRobert Watson mtx_unlock(&Giant); /* VFS */ 3401f7b951a8SRobert Watson mac_destroy_vnode_label(&intlabel); 3402f7b951a8SRobert Watson 3403f7b951a8SRobert Watson return (error); 3404f7b951a8SRobert Watson } 3405f7b951a8SRobert Watson 3406f7b951a8SRobert Watson /* 3407f7b951a8SRobert Watson * MPSAFE 3408f7b951a8SRobert Watson */ 340927f2eac7SRobert Watson int 341027f2eac7SRobert Watson mac_syscall(struct thread *td, struct mac_syscall_args *uap) 341127f2eac7SRobert Watson { 341227f2eac7SRobert Watson struct mac_policy_conf *mpc; 341327f2eac7SRobert Watson char target[MAC_MAX_POLICY_NAME]; 341427f2eac7SRobert Watson int error; 341527f2eac7SRobert Watson 341627f2eac7SRobert Watson error = copyinstr(SCARG(uap, policy), target, sizeof(target), NULL); 341727f2eac7SRobert Watson if (error) 341827f2eac7SRobert Watson return (error); 341927f2eac7SRobert Watson 342027f2eac7SRobert Watson error = ENOSYS; 342127f2eac7SRobert Watson MAC_POLICY_LIST_BUSY(); 342227f2eac7SRobert Watson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 342327f2eac7SRobert Watson if (strcmp(mpc->mpc_name, target) == 0 && 342427f2eac7SRobert Watson mpc->mpc_ops->mpo_syscall != NULL) { 342527f2eac7SRobert Watson error = mpc->mpc_ops->mpo_syscall(td, 342627f2eac7SRobert Watson SCARG(uap, call), SCARG(uap, arg)); 342727f2eac7SRobert Watson goto out; 342827f2eac7SRobert Watson } 342927f2eac7SRobert Watson } 343027f2eac7SRobert Watson 343127f2eac7SRobert Watson out: 343227f2eac7SRobert Watson MAC_POLICY_LIST_UNBUSY(); 343327f2eac7SRobert Watson return (error); 343427f2eac7SRobert Watson } 343527f2eac7SRobert Watson 343695fab37eSRobert Watson SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 343795fab37eSRobert Watson SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 343895fab37eSRobert Watson 343995fab37eSRobert Watson #else /* !MAC */ 34407bc82500SRobert Watson 34417bc82500SRobert Watson int 3442f7b951a8SRobert Watson __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3443f7b951a8SRobert Watson { 3444f7b951a8SRobert Watson 3445f7b951a8SRobert Watson return (ENOSYS); 3446f7b951a8SRobert Watson } 3447f7b951a8SRobert Watson 3448f7b951a8SRobert Watson int 34497bc82500SRobert Watson __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 34507bc82500SRobert Watson { 34517bc82500SRobert Watson 34527bc82500SRobert Watson return (ENOSYS); 34537bc82500SRobert Watson } 34547bc82500SRobert Watson 34557bc82500SRobert Watson int 34567bc82500SRobert Watson __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 34577bc82500SRobert Watson { 34587bc82500SRobert Watson 34597bc82500SRobert Watson return (ENOSYS); 34607bc82500SRobert Watson } 34617bc82500SRobert Watson 34627bc82500SRobert Watson int 34637bc82500SRobert Watson __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 34647bc82500SRobert Watson { 34657bc82500SRobert Watson 34667bc82500SRobert Watson return (ENOSYS); 34677bc82500SRobert Watson } 34687bc82500SRobert Watson 34697bc82500SRobert Watson int 34707bc82500SRobert Watson __mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 34717bc82500SRobert Watson { 34727bc82500SRobert Watson 34737bc82500SRobert Watson return (ENOSYS); 34747bc82500SRobert Watson } 34757bc82500SRobert Watson 34767bc82500SRobert Watson int 3477f7b951a8SRobert Watson __mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3478f7b951a8SRobert Watson { 3479f7b951a8SRobert Watson 3480f7b951a8SRobert Watson return (ENOSYS); 3481f7b951a8SRobert Watson } 3482f7b951a8SRobert Watson 3483f7b951a8SRobert Watson int 34847bc82500SRobert Watson __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 34857bc82500SRobert Watson { 34867bc82500SRobert Watson 34877bc82500SRobert Watson return (ENOSYS); 34887bc82500SRobert Watson } 34897bc82500SRobert Watson 34907bc82500SRobert Watson int 34917bc82500SRobert Watson __mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 34927bc82500SRobert Watson { 34937bc82500SRobert Watson 34947bc82500SRobert Watson return (ENOSYS); 34957bc82500SRobert Watson } 349695fab37eSRobert Watson 349727f2eac7SRobert Watson int 3498f7b951a8SRobert Watson __mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3499f7b951a8SRobert Watson { 3500f7b951a8SRobert Watson 3501f7b951a8SRobert Watson return (ENOSYS); 3502f7b951a8SRobert Watson } 3503f7b951a8SRobert Watson 3504f7b951a8SRobert Watson int 350527f2eac7SRobert Watson mac_syscall(struct thread *td, struct mac_syscall_args *uap) 350627f2eac7SRobert Watson { 350727f2eac7SRobert Watson 350827f2eac7SRobert Watson return (ENOSYS); 350927f2eac7SRobert Watson } 351027f2eac7SRobert Watson 3511f7b951a8SRobert Watson #endif 3512