mac_internal.h revision 105474
1233294Sstas/*- 2142403Snectar * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 3233294Sstas * Copyright (c) 2001 Ilmar S. Habibulin 4233294Sstas * Copyright (c) 2001, 2002 Networks Associates Technology, Inc. 5233294Sstas * All rights reserved. 6233294Sstas * 7233294Sstas * This software was developed by Robert Watson and Ilmar Habibulin for the 8233294Sstas * TrustedBSD Project. 9233294Sstas * 10233294Sstas * This software was developed for the FreeBSD Project in part by NAI Labs, 11233294Sstas * the Security Research Division of Network Associates, Inc. under 12233294Sstas * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 13233294Sstas * CHATS research program. 14233294Sstas * 15233294Sstas * Redistribution and use in source and binary forms, with or without 16233294Sstas * modification, are permitted provided that the following conditions 17233294Sstas * are met: 18233294Sstas * 1. Redistributions of source code must retain the above copyright 19233294Sstas * notice, this list of conditions and the following disclaimer. 20233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 21233294Sstas * notice, this list of conditions and the following disclaimer in the 22233294Sstas * documentation and/or other materials provided with the distribution. 23233294Sstas * 3. The names of the authors may not be used to endorse or promote 24233294Sstas * products derived from this software without specific prior written 25233294Sstas * permission. 26233294Sstas * 27233294Sstas * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 28233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30178825Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 31178825Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32142403Snectar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34178825Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35178825Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36178825Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37178825Sdfr * SUCH DAMAGE. 38178825Sdfr * 39178825Sdfr * $FreeBSD: head/sys/security/mac/mac_internal.h 105474 2002-10-19 20:30:12Z rwatson $ 40233294Sstas */ 41178825Sdfr/* 42178825Sdfr * Developed by the TrustedBSD Project. 43142403Snectar * 44233294Sstas * Framework for extensible kernel access control. Kernel and userland 45178825Sdfr * interface to the framework, policy registration and composition. 46178825Sdfr */ 47178825Sdfr 48178825Sdfr#include "opt_mac.h" 49178825Sdfr#include "opt_devfs.h" 50178825Sdfr 51178825Sdfr#include <sys/param.h> 52233294Sstas#include <sys/extattr.h> 53178825Sdfr#include <sys/kernel.h> 54178825Sdfr#include <sys/lock.h> 55178825Sdfr#include <sys/malloc.h> 56178825Sdfr#include <sys/mutex.h> 57178825Sdfr#include <sys/mac.h> 58178825Sdfr#include <sys/module.h> 59178825Sdfr#include <sys/proc.h> 60178825Sdfr#include <sys/systm.h> 61178825Sdfr#include <sys/sysproto.h> 62178825Sdfr#include <sys/sysent.h> 63178825Sdfr#include <sys/vnode.h> 64178825Sdfr#include <sys/mount.h> 65178825Sdfr#include <sys/file.h> 66233294Sstas#include <sys/namei.h> 67178825Sdfr#include <sys/socket.h> 68178825Sdfr#include <sys/pipe.h> 69178825Sdfr#include <sys/socketvar.h> 70178825Sdfr#include <sys/sysctl.h> 71178825Sdfr 72233294Sstas#include <vm/vm.h> 73178825Sdfr#include <vm/pmap.h> 74178825Sdfr#include <vm/vm_map.h> 75178825Sdfr#include <vm/vm_object.h> 76178825Sdfr 77178825Sdfr#include <sys/mac_policy.h> 78178825Sdfr 79178825Sdfr#include <fs/devfs/devfs.h> 80178825Sdfr 81178825Sdfr#include <net/bpfdesc.h> 82178825Sdfr#include <net/if.h> 83178825Sdfr#include <net/if_var.h> 84233294Sstas 85178825Sdfr#include <netinet/in.h> 86178825Sdfr#include <netinet/ip_var.h> 87178825Sdfr 88178825Sdfr#ifdef MAC 89233294Sstas 90178825Sdfr/* 91178825Sdfr * Declare that the kernel provides MAC support, version 1. This permits 92178825Sdfr * modules to refuse to be loaded if the necessary support isn't present, 93233294Sstas * even if it's pre-boot. 94178825Sdfr */ 95178825SdfrMODULE_VERSION(kernel_mac_support, 1); 96178825Sdfr 97233294SstasSYSCTL_DECL(_security); 98178825Sdfr 99178825SdfrSYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0, 100178825Sdfr "TrustedBSD MAC policy controls"); 101178825Sdfr 102178825Sdfr#ifndef MAC_MAX_POLICIES 103233294Sstas#define MAC_MAX_POLICIES 8 104178825Sdfr#endif 105178825Sdfr#if MAC_MAX_POLICIES > 32 106178825Sdfr#error "MAC_MAX_POLICIES too large" 107178825Sdfr#endif 108233294Sstasstatic unsigned int mac_max_policies = MAC_MAX_POLICIES; 109178825Sdfrstatic unsigned int mac_policy_offsets_free = (1 << MAC_MAX_POLICIES) - 1; 110178825SdfrSYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD, 111178825Sdfr &mac_max_policies, 0, ""); 112178825Sdfr 113233294Sstasstatic int mac_late = 0; 114178825Sdfr 115178825Sdfrstatic int mac_enforce_fs = 1; 116233294SstasSYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW, 117178825Sdfr &mac_enforce_fs, 0, "Enforce MAC policy on file system objects"); 118178825SdfrTUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs); 119178825Sdfr 120233294Sstasstatic int mac_enforce_network = 1; 121178825SdfrSYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, 122178825Sdfr &mac_enforce_network, 0, "Enforce MAC policy on network packets"); 123178825SdfrTUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); 124233294Sstas 125178825Sdfrstatic int mac_enforce_pipe = 1; 126178825SdfrSYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW, 127233294Sstas &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations"); 128178825SdfrTUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe); 129178825Sdfr 130178825Sdfrstatic int mac_enforce_process = 1; 131178825SdfrSYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW, 132178825Sdfr &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations"); 133178825SdfrTUNABLE_INT("security.mac.enforce_process", &mac_enforce_process); 134178825Sdfr 135178825Sdfrstatic int mac_enforce_socket = 1; 136178825SdfrSYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 137178825Sdfr &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 138178825SdfrTUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 139178825Sdfr 140178825Sdfrstatic int mac_enforce_vm = 1; 141178825SdfrSYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW, 142178825Sdfr &mac_enforce_vm, 0, "Enforce MAC policy on vm operations"); 143178825SdfrTUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm); 144178825Sdfr 145233294Sstasstatic int mac_label_size = sizeof(struct mac); 146178825SdfrSYSCTL_INT(_security_mac, OID_AUTO, label_size, CTLFLAG_RD, 147178825Sdfr &mac_label_size, 0, "Pre-compiled MAC label size"); 148178825Sdfr 149178825Sdfrstatic int mac_cache_fslabel_in_vnode = 1; 150178825SdfrSYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW, 151178825Sdfr &mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode"); 152178825SdfrTUNABLE_INT("security.mac.cache_fslabel_in_vnode", 153233294Sstas &mac_cache_fslabel_in_vnode); 154178825Sdfr 155178825Sdfrstatic int mac_vnode_label_cache_hits = 0; 156178825SdfrSYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_hits, CTLFLAG_RD, 157178825Sdfr &mac_vnode_label_cache_hits, 0, "Cache hits on vnode labels"); 158178825Sdfrstatic int mac_vnode_label_cache_misses = 0; 159178825SdfrSYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_misses, CTLFLAG_RD, 160178825Sdfr &mac_vnode_label_cache_misses, 0, "Cache misses on vnode labels"); 161178825Sdfr 162178825Sdfrstatic int mac_mmap_revocation = 1; 163178825SdfrSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW, 164178825Sdfr &mac_mmap_revocation, 0, "Revoke mmap access to files on subject " 165178825Sdfr "relabel"); 166178825Sdfrstatic int mac_mmap_revocation_via_cow = 0; 167178825SdfrSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW, 168178825Sdfr &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via " 169178825Sdfr "copy-on-write semantics, or by removing all write access"); 170178825Sdfr 171178825Sdfr#ifdef MAC_DEBUG 172178825SdfrSYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0, 173178825Sdfr "TrustedBSD MAC debug info"); 174178825Sdfr 175178825Sdfrstatic int mac_debug_label_fallback = 0; 176178825SdfrSYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW, 177178825Sdfr &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label" 178178825Sdfr "when label is corrupted."); 179178825SdfrTUNABLE_INT("security.mac.debug_label_fallback", 180178825Sdfr &mac_debug_label_fallback); 181178825Sdfr 182178825SdfrSYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0, 183233294Sstas "TrustedBSD MAC object counters"); 184178825Sdfr 185178825Sdfrstatic unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs, 186178825Sdfr nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents, 187233294Sstas nmacipqs, nmacpipes; 188178825Sdfr 189178825SdfrSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD, 190178825Sdfr &nmacmbufs, 0, "number of mbufs in use"); 191178825SdfrSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD, 192233294Sstas &nmaccreds, 0, "number of ucreds in use"); 193178825SdfrSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD, 194178825Sdfr &nmacifnets, 0, "number of ifnets in use"); 195178825SdfrSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD, 196178825Sdfr &nmacipqs, 0, "number of ipqs in use"); 197178825SdfrSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD, 198233294Sstas &nmacbpfdescs, 0, "number of bpfdescs in use"); 199178825SdfrSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD, 200178825Sdfr &nmacsockets, 0, "number of sockets in use"); 201178825SdfrSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, pipes, CTLFLAG_RD, 202178825Sdfr &nmacpipes, 0, "number of pipes in use"); 203233294SstasSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD, 204178825Sdfr &nmacmounts, 0, "number of mounts in use"); 205178825SdfrSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD, 206178825Sdfr &nmactemp, 0, "number of temporary labels in use"); 207178825SdfrSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD, 208178825Sdfr &nmacvnodes, 0, "number of vnodes in use"); 209233294SstasSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD, 210178825Sdfr &nmacdevfsdirents, 0, "number of devfs dirents inuse"); 211178825Sdfr#endif 212178825Sdfr 213178825Sdfrstatic int error_select(int error1, int error2); 214178825Sdfrstatic int mac_externalize(struct label *label, struct mac *mac); 215178825Sdfrstatic int mac_policy_register(struct mac_policy_conf *mpc); 216178825Sdfrstatic int mac_policy_unregister(struct mac_policy_conf *mpc); 217178825Sdfr 218178825Sdfrstatic int mac_stdcreatevnode_ea(struct vnode *vp); 219178825Sdfrstatic void mac_check_vnode_mmap_downgrade(struct ucred *cred, 220178825Sdfr struct vnode *vp, int *prot); 221178825Sdfrstatic void mac_cred_mmapped_drop_perms_recurse(struct thread *td, 222178825Sdfr struct ucred *cred, struct vm_map *map); 223178825Sdfr 224178825Sdfrstatic void mac_destroy_socket_label(struct label *label); 225178825Sdfr 226178825SdfrMALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector"); 227178825SdfrMALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes"); 228178825Sdfr 229178825Sdfr/* 230178825Sdfr * mac_policy_list_lock protects the consistency of 'mac_policy_list', 231178825Sdfr * the linked list of attached policy modules. Read-only consumers of 232178825Sdfr * the list must acquire a shared lock for the duration of their use; 233178825Sdfr * writers must acquire an exclusive lock. Note that for compound 234178825Sdfr * operations, locks should be held for the entire compound operation, 235233294Sstas * and that this is not yet done for relabel requests. 236178825Sdfr */ 237178825Sdfrstatic struct mtx mac_policy_list_lock; 238178825Sdfrstatic LIST_HEAD(, mac_policy_conf) mac_policy_list; 239178825Sdfrstatic int mac_policy_list_busy; 240178825Sdfr#define MAC_POLICY_LIST_LOCKINIT() mtx_init(&mac_policy_list_lock, \ 241178825Sdfr "mac_policy_list_lock", NULL, MTX_DEF); 242233294Sstas#define MAC_POLICY_LIST_LOCK() mtx_lock(&mac_policy_list_lock); 243178825Sdfr#define MAC_POLICY_LIST_UNLOCK() mtx_unlock(&mac_policy_list_lock); 244178825Sdfr 245178825Sdfr#define MAC_POLICY_LIST_BUSY() do { \ 246178825Sdfr MAC_POLICY_LIST_LOCK(); \ 247178825Sdfr mac_policy_list_busy++; \ 248233294Sstas MAC_POLICY_LIST_UNLOCK(); \ 249178825Sdfr} while (0) 250178825Sdfr 251178825Sdfr#define MAC_POLICY_LIST_UNBUSY() do { \ 252178825Sdfr MAC_POLICY_LIST_LOCK(); \ 253178825Sdfr mac_policy_list_busy--; \ 254142403Snectar if (mac_policy_list_busy < 0) \ 255142403Snectar panic("Extra mac_policy_list_busy--"); \ 256178825Sdfr MAC_POLICY_LIST_UNLOCK(); \ 257178825Sdfr} while (0) 258178825Sdfr 259233294Sstas/* 260178825Sdfr * MAC_CHECK performs the designated check by walking the policy 261178825Sdfr * module list and checking with each as to how it feels about the 262178825Sdfr * request. Note that it returns its value via 'error' in the scope 263178825Sdfr * of the caller. 264178825Sdfr */ 265233294Sstas#define MAC_CHECK(check, args...) do { \ 266127808Snectar struct mac_policy_conf *mpc; \ 267178825Sdfr \ 268127808Snectar error = 0; \ 269178825Sdfr MAC_POLICY_LIST_BUSY(); \ 270127808Snectar LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 271233294Sstas if (mpc->mpc_ops->mpo_ ## check != NULL) \ 272178825Sdfr error = error_select( \ 273178825Sdfr mpc->mpc_ops->mpo_ ## check (args), \ 274178825Sdfr error); \ 275178825Sdfr } \ 276178825Sdfr MAC_POLICY_LIST_UNBUSY(); \ 277178825Sdfr} while (0) 278178825Sdfr 279178825Sdfr/* 280178825Sdfr * MAC_BOOLEAN performs the designated boolean composition by walking 281233294Sstas * the module list, invoking each instance of the operation, and 282178825Sdfr * combining the results using the passed C operator. Note that it 283178825Sdfr * returns its value via 'result' in the scope of the caller, which 284178825Sdfr * should be initialized by the caller in a meaningful way to get 285178825Sdfr * a meaningful result. 286178825Sdfr */ 287233294Sstas#define MAC_BOOLEAN(operation, composition, args...) do { \ 288178825Sdfr struct mac_policy_conf *mpc; \ 289178825Sdfr \ 290178825Sdfr MAC_POLICY_LIST_BUSY(); \ 291103423Snectar LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 292103423Snectar if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 293103423Snectar result = result composition \ 294103423Snectar mpc->mpc_ops->mpo_ ## operation (args); \ 295102644Snectar } \ 296102644Snectar MAC_POLICY_LIST_UNBUSY(); \ 297103423Snectar} while (0) 298103423Snectar 299103423Snectar/* 300103423Snectar * MAC_PERFORM performs the designated operation by walking the policy 301102644Snectar * module list and invoking that operation for each policy. 302102644Snectar */ 303102644Snectar#define MAC_PERFORM(operation, args...) do { \ 304102644Snectar struct mac_policy_conf *mpc; \ 305102644Snectar \ 306102644Snectar MAC_POLICY_LIST_BUSY(); \ 307102644Snectar LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 308102644Snectar if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 309102644Snectar mpc->mpc_ops->mpo_ ## operation (args); \ 310102644Snectar } \ 311102644Snectar MAC_POLICY_LIST_UNBUSY(); \ 312102644Snectar} while (0) 313102644Snectar 314102644Snectar/* 315102644Snectar * Initialize the MAC subsystem, including appropriate SMP locks. 316102644Snectar */ 317102644Snectarstatic void 318102644Snectarmac_init(void) 319102644Snectar{ 320102644Snectar 321102644Snectar LIST_INIT(&mac_policy_list); 322102644Snectar MAC_POLICY_LIST_LOCKINIT(); 323102644Snectar} 324102644Snectar 325102644Snectar/* 326102644Snectar * For the purposes of modules that want to know if they were loaded 327102644Snectar * "early", set the mac_late flag once we've processed modules either 328102644Snectar * linked into the kernel, or loaded before the kernel startup. 329102644Snectar */ 330102644Snectarstatic void 331102644Snectarmac_late_init(void) 332102644Snectar{ 33390926Snectar 33490926Snectar mac_late = 1; 33590926Snectar} 33690926Snectar 33790926Snectar/* 33890926Snectar * Allow MAC policy modules to register during boot, etc. 33990926Snectar */ 34090926Snectarint 34190926Snectarmac_policy_modevent(module_t mod, int type, void *data) 34290926Snectar{ 34390926Snectar struct mac_policy_conf *mpc; 34490926Snectar int error; 34590926Snectar 34690926Snectar error = 0; 34790926Snectar mpc = (struct mac_policy_conf *) data; 34890926Snectar 34990926Snectar switch (type) { 35090926Snectar case MOD_LOAD: 35190926Snectar if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && 35290926Snectar mac_late) { 35390926Snectar printf("mac_policy_modevent: can't load %s policy " 35490926Snectar "after booting\n", mpc->mpc_name); 35590926Snectar error = EBUSY; 35690926Snectar break; 35790926Snectar } 35890926Snectar error = mac_policy_register(mpc); 35990926Snectar break; 36090926Snectar case MOD_UNLOAD: 36190926Snectar /* Don't unregister the module if it was never registered. */ 36290926Snectar if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) 36390926Snectar != 0) 36490926Snectar error = mac_policy_unregister(mpc); 36590926Snectar else 36690926Snectar error = 0; 36790926Snectar break; 36878527Sassar default: 36978527Sassar break; 37078527Sassar } 37178527Sassar 37278527Sassar return (error); 37378527Sassar} 37478527Sassar 37578527Sassarstatic int 37678527Sassarmac_policy_register(struct mac_policy_conf *mpc) 37778527Sassar{ 37878527Sassar struct mac_policy_conf *tmpc; 37978527Sassar struct mac_policy_op_entry *mpe; 38078527Sassar int slot; 38178527Sassar 38278527Sassar MALLOC(mpc->mpc_ops, struct mac_policy_ops *, sizeof(*mpc->mpc_ops), 38378527Sassar M_MACOPVEC, M_WAITOK | M_ZERO); 38478527Sassar for (mpe = mpc->mpc_entries; mpe->mpe_constant != MAC_OP_LAST; mpe++) { 38578527Sassar switch (mpe->mpe_constant) { 38678527Sassar case MAC_OP_LAST: 38778527Sassar /* 38878527Sassar * Doesn't actually happen, but this allows checking 38978527Sassar * that all enumerated values are handled. 39078527Sassar */ 39178527Sassar break; 39278527Sassar case MAC_DESTROY: 39378527Sassar mpc->mpc_ops->mpo_destroy = 39478527Sassar mpe->mpe_function; 39578527Sassar break; 39678527Sassar case MAC_INIT: 39778527Sassar mpc->mpc_ops->mpo_init = 39878527Sassar mpe->mpe_function; 39978527Sassar break; 40078527Sassar case MAC_SYSCALL: 40172445Sassar mpc->mpc_ops->mpo_syscall = 40272445Sassar mpe->mpe_function; 40372445Sassar break; 40472445Sassar case MAC_INIT_BPFDESC_LABEL: 40572445Sassar mpc->mpc_ops->mpo_init_bpfdesc_label = 40672445Sassar mpe->mpe_function; 40772445Sassar break; 40872445Sassar case MAC_INIT_CRED_LABEL: 40972445Sassar mpc->mpc_ops->mpo_init_cred_label = 41072445Sassar mpe->mpe_function; 41172445Sassar break; 41272445Sassar case MAC_INIT_DEVFSDIRENT_LABEL: 41372445Sassar mpc->mpc_ops->mpo_init_devfsdirent_label = 41472445Sassar mpe->mpe_function; 41572445Sassar break; 41672445Sassar case MAC_INIT_IFNET_LABEL: 41772445Sassar mpc->mpc_ops->mpo_init_ifnet_label = 41872445Sassar mpe->mpe_function; 41972445Sassar break; 42072445Sassar case MAC_INIT_IPQ_LABEL: 42172445Sassar mpc->mpc_ops->mpo_init_ipq_label = 42272445Sassar mpe->mpe_function; 42372445Sassar break; 42478527Sassar case MAC_INIT_MBUF_LABEL: 42578527Sassar mpc->mpc_ops->mpo_init_mbuf_label = 42678527Sassar mpe->mpe_function; 42772445Sassar break; 42872445Sassar case MAC_INIT_MOUNT_LABEL: 42972445Sassar mpc->mpc_ops->mpo_init_mount_label = 43072445Sassar mpe->mpe_function; 43172445Sassar break; 43272445Sassar case MAC_INIT_MOUNT_FS_LABEL: 43372445Sassar mpc->mpc_ops->mpo_init_mount_fs_label = 43472445Sassar mpe->mpe_function; 43572445Sassar break; 43672445Sassar case MAC_INIT_PIPE_LABEL: 43772445Sassar mpc->mpc_ops->mpo_init_pipe_label = 43872445Sassar mpe->mpe_function; 43972445Sassar break; 44072445Sassar case MAC_INIT_SOCKET_LABEL: 44172445Sassar mpc->mpc_ops->mpo_init_socket_label = 44272445Sassar mpe->mpe_function; 44372445Sassar break; 44472445Sassar case MAC_INIT_SOCKET_PEER_LABEL: 44572445Sassar mpc->mpc_ops->mpo_init_socket_peer_label = 44672445Sassar mpe->mpe_function; 44772445Sassar break; 44872445Sassar case MAC_INIT_TEMP_LABEL: 44972445Sassar mpc->mpc_ops->mpo_init_temp_label = 45072445Sassar mpe->mpe_function; 45172445Sassar break; 45272445Sassar case MAC_INIT_VNODE_LABEL: 45372445Sassar mpc->mpc_ops->mpo_init_vnode_label = 45472445Sassar mpe->mpe_function; 45572445Sassar break; 45672445Sassar case MAC_DESTROY_BPFDESC_LABEL: 45772445Sassar mpc->mpc_ops->mpo_destroy_bpfdesc_label = 45872445Sassar mpe->mpe_function; 45972445Sassar break; 46072445Sassar case MAC_DESTROY_CRED_LABEL: 46172445Sassar mpc->mpc_ops->mpo_destroy_cred_label = 46272445Sassar mpe->mpe_function; 46372445Sassar break; 46472445Sassar case MAC_DESTROY_DEVFSDIRENT_LABEL: 46572445Sassar mpc->mpc_ops->mpo_destroy_devfsdirent_label = 46672445Sassar mpe->mpe_function; 46772445Sassar break; 46872445Sassar case MAC_DESTROY_IFNET_LABEL: 46972445Sassar mpc->mpc_ops->mpo_destroy_ifnet_label = 47072445Sassar mpe->mpe_function; 47172445Sassar break; 47272445Sassar case MAC_DESTROY_IPQ_LABEL: 47372445Sassar mpc->mpc_ops->mpo_destroy_ipq_label = 47472445Sassar mpe->mpe_function; 47572445Sassar break; 47672445Sassar case MAC_DESTROY_MBUF_LABEL: 47772445Sassar mpc->mpc_ops->mpo_destroy_mbuf_label = 47872445Sassar mpe->mpe_function; 47972445Sassar break; 48072445Sassar case MAC_DESTROY_MOUNT_LABEL: 48172445Sassar mpc->mpc_ops->mpo_destroy_mount_label = 48272445Sassar mpe->mpe_function; 48372445Sassar break; 48472445Sassar case MAC_DESTROY_MOUNT_FS_LABEL: 48572445Sassar mpc->mpc_ops->mpo_destroy_mount_fs_label = 48672445Sassar mpe->mpe_function; 48772445Sassar break; 48872445Sassar case MAC_DESTROY_PIPE_LABEL: 48972445Sassar mpc->mpc_ops->mpo_destroy_pipe_label = 49072445Sassar mpe->mpe_function; 49172445Sassar break; 49272445Sassar case MAC_DESTROY_SOCKET_LABEL: 49372445Sassar mpc->mpc_ops->mpo_destroy_socket_label = 49472445Sassar mpe->mpe_function; 49572445Sassar break; 49672445Sassar case MAC_DESTROY_SOCKET_PEER_LABEL: 49772445Sassar mpc->mpc_ops->mpo_destroy_socket_peer_label = 49872445Sassar mpe->mpe_function; 49957419Smarkm break; 50057419Smarkm case MAC_DESTROY_TEMP_LABEL: 50157419Smarkm mpc->mpc_ops->mpo_destroy_temp_label = 50257419Smarkm mpe->mpe_function; 50357419Smarkm break; 50457416Smarkm case MAC_DESTROY_VNODE_LABEL: 50557416Smarkm mpc->mpc_ops->mpo_destroy_vnode_label = 50657416Smarkm mpe->mpe_function; 50757416Smarkm break; 50857416Smarkm case MAC_EXTERNALIZE: 50957416Smarkm mpc->mpc_ops->mpo_externalize = 51057416Smarkm mpe->mpe_function; 51157416Smarkm break; 51257416Smarkm case MAC_INTERNALIZE: 51357416Smarkm mpc->mpc_ops->mpo_internalize = 51457416Smarkm mpe->mpe_function; 51557416Smarkm break; 51657416Smarkm case MAC_CREATE_DEVFS_DEVICE: 51757416Smarkm mpc->mpc_ops->mpo_create_devfs_device = 51857416Smarkm mpe->mpe_function; 51957416Smarkm break; 52057416Smarkm case MAC_CREATE_DEVFS_DIRECTORY: 52157416Smarkm mpc->mpc_ops->mpo_create_devfs_directory = 52257416Smarkm mpe->mpe_function; 52357416Smarkm break; 52457416Smarkm case MAC_CREATE_DEVFS_SYMLINK: 52557416Smarkm mpc->mpc_ops->mpo_create_devfs_symlink = 52657416Smarkm mpe->mpe_function; 52757416Smarkm break; 52857416Smarkm case MAC_CREATE_DEVFS_VNODE: 52957416Smarkm mpc->mpc_ops->mpo_create_devfs_vnode = 53057416Smarkm mpe->mpe_function; 53157416Smarkm break; 53257416Smarkm case MAC_STDCREATEVNODE_EA: 53357416Smarkm mpc->mpc_ops->mpo_stdcreatevnode_ea = 53457416Smarkm mpe->mpe_function; 53557416Smarkm break; 53657416Smarkm case MAC_CREATE_VNODE: 53757416Smarkm mpc->mpc_ops->mpo_create_vnode = 53857416Smarkm mpe->mpe_function; 53957416Smarkm break; 54057416Smarkm case MAC_CREATE_MOUNT: 54157416Smarkm mpc->mpc_ops->mpo_create_mount = 54257416Smarkm mpe->mpe_function; 54357416Smarkm break; 54457416Smarkm case MAC_CREATE_ROOT_MOUNT: 54557416Smarkm mpc->mpc_ops->mpo_create_root_mount = 54657416Smarkm mpe->mpe_function; 54757416Smarkm break; 54857416Smarkm case MAC_RELABEL_VNODE: 54957416Smarkm mpc->mpc_ops->mpo_relabel_vnode = 55057416Smarkm mpe->mpe_function; 55157416Smarkm break; 55257416Smarkm case MAC_UPDATE_DEVFSDIRENT: 55357416Smarkm mpc->mpc_ops->mpo_update_devfsdirent = 55457416Smarkm mpe->mpe_function; 55557416Smarkm break; 55657416Smarkm case MAC_UPDATE_PROCFSVNODE: 55757416Smarkm mpc->mpc_ops->mpo_update_procfsvnode = 55857416Smarkm mpe->mpe_function; 55957416Smarkm break; 56057416Smarkm case MAC_UPDATE_VNODE_FROM_EXTATTR: 56157416Smarkm mpc->mpc_ops->mpo_update_vnode_from_extattr = 56257416Smarkm mpe->mpe_function; 56357416Smarkm break; 56457416Smarkm case MAC_UPDATE_VNODE_FROM_EXTERNALIZED: 56557416Smarkm mpc->mpc_ops->mpo_update_vnode_from_externalized = 56657416Smarkm mpe->mpe_function; 56757416Smarkm break; 56857416Smarkm case MAC_UPDATE_VNODE_FROM_MOUNT: 56957416Smarkm mpc->mpc_ops->mpo_update_vnode_from_mount = 57057416Smarkm mpe->mpe_function; 57157416Smarkm break; 57257416Smarkm case MAC_CREATE_MBUF_FROM_SOCKET: 57357416Smarkm mpc->mpc_ops->mpo_create_mbuf_from_socket = 57457416Smarkm mpe->mpe_function; 57557416Smarkm break; 57657416Smarkm case MAC_CREATE_PIPE: 57757416Smarkm mpc->mpc_ops->mpo_create_pipe = 57857416Smarkm mpe->mpe_function; 57957416Smarkm break; 58057416Smarkm case MAC_CREATE_SOCKET: 58157416Smarkm mpc->mpc_ops->mpo_create_socket = 58257416Smarkm mpe->mpe_function; 58357416Smarkm break; 58457416Smarkm case MAC_CREATE_SOCKET_FROM_SOCKET: 58557416Smarkm mpc->mpc_ops->mpo_create_socket_from_socket = 58657416Smarkm mpe->mpe_function; 58757416Smarkm break; 58857416Smarkm case MAC_RELABEL_PIPE: 58957416Smarkm mpc->mpc_ops->mpo_relabel_pipe = 59057416Smarkm mpe->mpe_function; 59157416Smarkm break; 59257416Smarkm case MAC_RELABEL_SOCKET: 59357416Smarkm mpc->mpc_ops->mpo_relabel_socket = 59457416Smarkm mpe->mpe_function; 59557416Smarkm break; 59657416Smarkm case MAC_SET_SOCKET_PEER_FROM_MBUF: 59757416Smarkm mpc->mpc_ops->mpo_set_socket_peer_from_mbuf = 59857416Smarkm mpe->mpe_function; 59957416Smarkm break; 60057416Smarkm case MAC_SET_SOCKET_PEER_FROM_SOCKET: 60157416Smarkm mpc->mpc_ops->mpo_set_socket_peer_from_socket = 60257416Smarkm mpe->mpe_function; 60357416Smarkm break; 60457416Smarkm case MAC_CREATE_BPFDESC: 60557416Smarkm mpc->mpc_ops->mpo_create_bpfdesc = 60657416Smarkm mpe->mpe_function; 60757416Smarkm break; 60857416Smarkm case MAC_CREATE_DATAGRAM_FROM_IPQ: 60957416Smarkm mpc->mpc_ops->mpo_create_datagram_from_ipq = 61057416Smarkm mpe->mpe_function; 61157416Smarkm break; 61257416Smarkm case MAC_CREATE_FRAGMENT: 61357416Smarkm mpc->mpc_ops->mpo_create_fragment = 61457416Smarkm mpe->mpe_function; 61557416Smarkm break; 61657416Smarkm case MAC_CREATE_IFNET: 61757416Smarkm mpc->mpc_ops->mpo_create_ifnet = 61857416Smarkm mpe->mpe_function; 61957416Smarkm break; 62057416Smarkm case MAC_CREATE_IPQ: 62157416Smarkm mpc->mpc_ops->mpo_create_ipq = 62257416Smarkm mpe->mpe_function; 62357416Smarkm break; 62457416Smarkm case MAC_CREATE_MBUF_FROM_MBUF: 62557416Smarkm mpc->mpc_ops->mpo_create_mbuf_from_mbuf = 62657416Smarkm mpe->mpe_function; 62757416Smarkm break; 62857416Smarkm case MAC_CREATE_MBUF_LINKLAYER: 62957416Smarkm mpc->mpc_ops->mpo_create_mbuf_linklayer = 63057416Smarkm mpe->mpe_function; 63157416Smarkm break; 63257416Smarkm case MAC_CREATE_MBUF_FROM_BPFDESC: 63357416Smarkm mpc->mpc_ops->mpo_create_mbuf_from_bpfdesc = 63457416Smarkm mpe->mpe_function; 63557416Smarkm break; 63657416Smarkm case MAC_CREATE_MBUF_FROM_IFNET: 63757416Smarkm mpc->mpc_ops->mpo_create_mbuf_from_ifnet = 63857416Smarkm mpe->mpe_function; 63957416Smarkm break; 64057416Smarkm case MAC_CREATE_MBUF_MULTICAST_ENCAP: 64157416Smarkm mpc->mpc_ops->mpo_create_mbuf_multicast_encap = 64257416Smarkm mpe->mpe_function; 64357416Smarkm break; 64457416Smarkm case MAC_CREATE_MBUF_NETLAYER: 64557416Smarkm mpc->mpc_ops->mpo_create_mbuf_netlayer = 64657416Smarkm mpe->mpe_function; 64757416Smarkm break; 64857416Smarkm case MAC_FRAGMENT_MATCH: 64957416Smarkm mpc->mpc_ops->mpo_fragment_match = 65057416Smarkm mpe->mpe_function; 65157416Smarkm break; 65257416Smarkm case MAC_RELABEL_IFNET: 65357416Smarkm mpc->mpc_ops->mpo_relabel_ifnet = 65457416Smarkm mpe->mpe_function; 65557416Smarkm break; 65657416Smarkm case MAC_UPDATE_IPQ: 65757416Smarkm mpc->mpc_ops->mpo_update_ipq = 65857416Smarkm mpe->mpe_function; 65957416Smarkm break; 66057416Smarkm case MAC_CREATE_CRED: 66157416Smarkm mpc->mpc_ops->mpo_create_cred = 66257416Smarkm mpe->mpe_function; 66357416Smarkm break; 66457416Smarkm case MAC_EXECVE_TRANSITION: 66557416Smarkm mpc->mpc_ops->mpo_execve_transition = 66657416Smarkm mpe->mpe_function; 66757416Smarkm break; 66857416Smarkm case MAC_EXECVE_WILL_TRANSITION: 66957416Smarkm mpc->mpc_ops->mpo_execve_will_transition = 67057416Smarkm mpe->mpe_function; 67157416Smarkm break; 67257416Smarkm case MAC_CREATE_PROC0: 67357416Smarkm mpc->mpc_ops->mpo_create_proc0 = 67457416Smarkm mpe->mpe_function; 67557416Smarkm break; 67657416Smarkm case MAC_CREATE_PROC1: 67757416Smarkm mpc->mpc_ops->mpo_create_proc1 = 67857416Smarkm mpe->mpe_function; 67957416Smarkm break; 68057416Smarkm case MAC_RELABEL_CRED: 68157416Smarkm mpc->mpc_ops->mpo_relabel_cred = 68257416Smarkm mpe->mpe_function; 68357416Smarkm break; 68457416Smarkm case MAC_THREAD_USERRET: 68557416Smarkm mpc->mpc_ops->mpo_thread_userret = 68657416Smarkm mpe->mpe_function; 68757416Smarkm break; 68857416Smarkm case MAC_CHECK_BPFDESC_RECEIVE: 68957416Smarkm mpc->mpc_ops->mpo_check_bpfdesc_receive = 69057416Smarkm mpe->mpe_function; 69157416Smarkm break; 69257416Smarkm case MAC_CHECK_CRED_RELABEL: 69357416Smarkm mpc->mpc_ops->mpo_check_cred_relabel = 69457416Smarkm mpe->mpe_function; 69557416Smarkm break; 69657416Smarkm case MAC_CHECK_CRED_VISIBLE: 69757416Smarkm mpc->mpc_ops->mpo_check_cred_visible = 69857416Smarkm mpe->mpe_function; 69957416Smarkm break; 70057416Smarkm case MAC_CHECK_IFNET_RELABEL: 70157416Smarkm mpc->mpc_ops->mpo_check_ifnet_relabel = 70257416Smarkm mpe->mpe_function; 70357416Smarkm break; 70457416Smarkm case MAC_CHECK_IFNET_TRANSMIT: 70557416Smarkm mpc->mpc_ops->mpo_check_ifnet_transmit = 70657416Smarkm mpe->mpe_function; 70757416Smarkm break; 70857416Smarkm case MAC_CHECK_MOUNT_STAT: 70957416Smarkm mpc->mpc_ops->mpo_check_mount_stat = 71057416Smarkm mpe->mpe_function; 71157416Smarkm break; 71257416Smarkm case MAC_CHECK_PIPE_IOCTL: 71357416Smarkm mpc->mpc_ops->mpo_check_pipe_ioctl = 71457416Smarkm mpe->mpe_function; 71557416Smarkm break; 71657416Smarkm case MAC_CHECK_PIPE_POLL: 71757416Smarkm mpc->mpc_ops->mpo_check_pipe_poll = 71857416Smarkm mpe->mpe_function; 71957416Smarkm break; 72057416Smarkm case MAC_CHECK_PIPE_READ: 72157416Smarkm mpc->mpc_ops->mpo_check_pipe_read = 72257416Smarkm mpe->mpe_function; 72357416Smarkm break; 72457416Smarkm case MAC_CHECK_PIPE_RELABEL: 72557416Smarkm mpc->mpc_ops->mpo_check_pipe_relabel = 72657416Smarkm mpe->mpe_function; 72757416Smarkm break; 72857416Smarkm case MAC_CHECK_PIPE_STAT: 72957416Smarkm mpc->mpc_ops->mpo_check_pipe_stat = 73057416Smarkm mpe->mpe_function; 73157416Smarkm break; 73257416Smarkm case MAC_CHECK_PIPE_WRITE: 73357416Smarkm mpc->mpc_ops->mpo_check_pipe_write = 73457416Smarkm mpe->mpe_function; 73557416Smarkm break; 73657416Smarkm case MAC_CHECK_PROC_DEBUG: 73757416Smarkm mpc->mpc_ops->mpo_check_proc_debug = 73857416Smarkm mpe->mpe_function; 73957416Smarkm break; 74057416Smarkm case MAC_CHECK_PROC_SCHED: 74157416Smarkm mpc->mpc_ops->mpo_check_proc_sched = 74257416Smarkm mpe->mpe_function; 74357416Smarkm break; 74457416Smarkm case MAC_CHECK_PROC_SIGNAL: 74557416Smarkm mpc->mpc_ops->mpo_check_proc_signal = 74657416Smarkm mpe->mpe_function; 74757416Smarkm break; 74857416Smarkm case MAC_CHECK_SOCKET_BIND: 74957416Smarkm mpc->mpc_ops->mpo_check_socket_bind = 75057416Smarkm mpe->mpe_function; 75157416Smarkm break; 75257416Smarkm case MAC_CHECK_SOCKET_CONNECT: 75357416Smarkm mpc->mpc_ops->mpo_check_socket_connect = 75457416Smarkm mpe->mpe_function; 75557416Smarkm break; 75657416Smarkm case MAC_CHECK_SOCKET_DELIVER: 75757416Smarkm mpc->mpc_ops->mpo_check_socket_deliver = 75857416Smarkm mpe->mpe_function; 75957416Smarkm break; 76057416Smarkm case MAC_CHECK_SOCKET_LISTEN: 76157416Smarkm mpc->mpc_ops->mpo_check_socket_listen = 76257416Smarkm mpe->mpe_function; 76357416Smarkm break; 76457416Smarkm case MAC_CHECK_SOCKET_RECEIVE: 76557416Smarkm mpc->mpc_ops->mpo_check_socket_receive = 76657416Smarkm mpe->mpe_function; 76757416Smarkm break; 76857416Smarkm case MAC_CHECK_SOCKET_RELABEL: 76957416Smarkm mpc->mpc_ops->mpo_check_socket_relabel = 77057416Smarkm mpe->mpe_function; 77157416Smarkm break; 77257416Smarkm case MAC_CHECK_SOCKET_SEND: 77357416Smarkm mpc->mpc_ops->mpo_check_socket_send = 77457416Smarkm mpe->mpe_function; 77557416Smarkm break; 77657416Smarkm case MAC_CHECK_SOCKET_VISIBLE: 77757416Smarkm mpc->mpc_ops->mpo_check_socket_visible = 77857416Smarkm mpe->mpe_function; 77957416Smarkm break; 78057416Smarkm case MAC_CHECK_VNODE_ACCESS: 78157416Smarkm mpc->mpc_ops->mpo_check_vnode_access = 78257416Smarkm mpe->mpe_function; 78357416Smarkm break; 78457416Smarkm case MAC_CHECK_VNODE_CHDIR: 78557416Smarkm mpc->mpc_ops->mpo_check_vnode_chdir = 78657416Smarkm mpe->mpe_function; 78757416Smarkm break; 78857416Smarkm case MAC_CHECK_VNODE_CHROOT: 78957416Smarkm mpc->mpc_ops->mpo_check_vnode_chroot = 79057416Smarkm mpe->mpe_function; 79157416Smarkm break; 79257416Smarkm case MAC_CHECK_VNODE_CREATE: 79357416Smarkm mpc->mpc_ops->mpo_check_vnode_create = 79457416Smarkm mpe->mpe_function; 79557416Smarkm break; 79657416Smarkm case MAC_CHECK_VNODE_DELETE: 79757416Smarkm mpc->mpc_ops->mpo_check_vnode_delete = 79857416Smarkm mpe->mpe_function; 79957416Smarkm break; 80057416Smarkm case MAC_CHECK_VNODE_DELETEACL: 80157416Smarkm mpc->mpc_ops->mpo_check_vnode_deleteacl = 80257416Smarkm mpe->mpe_function; 80357416Smarkm break; 80457416Smarkm case MAC_CHECK_VNODE_EXEC: 80557416Smarkm mpc->mpc_ops->mpo_check_vnode_exec = 80657416Smarkm mpe->mpe_function; 80757416Smarkm break; 80857416Smarkm case MAC_CHECK_VNODE_GETACL: 80957416Smarkm mpc->mpc_ops->mpo_check_vnode_getacl = 81057416Smarkm mpe->mpe_function; 81157416Smarkm break; 81257416Smarkm case MAC_CHECK_VNODE_GETEXTATTR: 81357416Smarkm mpc->mpc_ops->mpo_check_vnode_getextattr = 81457416Smarkm mpe->mpe_function; 81557416Smarkm break; 81657416Smarkm case MAC_CHECK_VNODE_LINK: 81757416Smarkm mpc->mpc_ops->mpo_check_vnode_link = 81857416Smarkm mpe->mpe_function; 81957416Smarkm break; 82057416Smarkm case MAC_CHECK_VNODE_LOOKUP: 82157416Smarkm mpc->mpc_ops->mpo_check_vnode_lookup = 82257416Smarkm mpe->mpe_function; 82357416Smarkm break; 82457416Smarkm case MAC_CHECK_VNODE_MMAP: 82557416Smarkm mpc->mpc_ops->mpo_check_vnode_mmap = 82657416Smarkm mpe->mpe_function; 82757416Smarkm break; 82857416Smarkm case MAC_CHECK_VNODE_MMAP_DOWNGRADE: 82957416Smarkm mpc->mpc_ops->mpo_check_vnode_mmap_downgrade = 83057416Smarkm mpe->mpe_function; 83157416Smarkm break; 832 case MAC_CHECK_VNODE_MPROTECT: 833 mpc->mpc_ops->mpo_check_vnode_mprotect = 834 mpe->mpe_function; 835 break; 836 case MAC_CHECK_VNODE_OPEN: 837 mpc->mpc_ops->mpo_check_vnode_open = 838 mpe->mpe_function; 839 break; 840 case MAC_CHECK_VNODE_POLL: 841 mpc->mpc_ops->mpo_check_vnode_poll = 842 mpe->mpe_function; 843 break; 844 case MAC_CHECK_VNODE_READ: 845 mpc->mpc_ops->mpo_check_vnode_read = 846 mpe->mpe_function; 847 break; 848 case MAC_CHECK_VNODE_READDIR: 849 mpc->mpc_ops->mpo_check_vnode_readdir = 850 mpe->mpe_function; 851 break; 852 case MAC_CHECK_VNODE_READLINK: 853 mpc->mpc_ops->mpo_check_vnode_readlink = 854 mpe->mpe_function; 855 break; 856 case MAC_CHECK_VNODE_RELABEL: 857 mpc->mpc_ops->mpo_check_vnode_relabel = 858 mpe->mpe_function; 859 break; 860 case MAC_CHECK_VNODE_RENAME_FROM: 861 mpc->mpc_ops->mpo_check_vnode_rename_from = 862 mpe->mpe_function; 863 break; 864 case MAC_CHECK_VNODE_RENAME_TO: 865 mpc->mpc_ops->mpo_check_vnode_rename_to = 866 mpe->mpe_function; 867 break; 868 case MAC_CHECK_VNODE_REVOKE: 869 mpc->mpc_ops->mpo_check_vnode_revoke = 870 mpe->mpe_function; 871 break; 872 case MAC_CHECK_VNODE_SETACL: 873 mpc->mpc_ops->mpo_check_vnode_setacl = 874 mpe->mpe_function; 875 break; 876 case MAC_CHECK_VNODE_SETEXTATTR: 877 mpc->mpc_ops->mpo_check_vnode_setextattr = 878 mpe->mpe_function; 879 break; 880 case MAC_CHECK_VNODE_SETFLAGS: 881 mpc->mpc_ops->mpo_check_vnode_setflags = 882 mpe->mpe_function; 883 break; 884 case MAC_CHECK_VNODE_SETMODE: 885 mpc->mpc_ops->mpo_check_vnode_setmode = 886 mpe->mpe_function; 887 break; 888 case MAC_CHECK_VNODE_SETOWNER: 889 mpc->mpc_ops->mpo_check_vnode_setowner = 890 mpe->mpe_function; 891 break; 892 case MAC_CHECK_VNODE_SETUTIMES: 893 mpc->mpc_ops->mpo_check_vnode_setutimes = 894 mpe->mpe_function; 895 break; 896 case MAC_CHECK_VNODE_STAT: 897 mpc->mpc_ops->mpo_check_vnode_stat = 898 mpe->mpe_function; 899 break; 900 case MAC_CHECK_VNODE_WRITE: 901 mpc->mpc_ops->mpo_check_vnode_write = 902 mpe->mpe_function; 903 break; 904/* 905 default: 906 printf("MAC policy `%s': unknown operation %d\n", 907 mpc->mpc_name, mpe->mpe_constant); 908 return (EINVAL); 909*/ 910 } 911 } 912 MAC_POLICY_LIST_LOCK(); 913 if (mac_policy_list_busy > 0) { 914 MAC_POLICY_LIST_UNLOCK(); 915 FREE(mpc->mpc_ops, M_MACOPVEC); 916 mpc->mpc_ops = NULL; 917 return (EBUSY); 918 } 919 LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 920 if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 921 MAC_POLICY_LIST_UNLOCK(); 922 FREE(mpc->mpc_ops, M_MACOPVEC); 923 mpc->mpc_ops = NULL; 924 return (EEXIST); 925 } 926 } 927 if (mpc->mpc_field_off != NULL) { 928 slot = ffs(mac_policy_offsets_free); 929 if (slot == 0) { 930 MAC_POLICY_LIST_UNLOCK(); 931 FREE(mpc->mpc_ops, M_MACOPVEC); 932 mpc->mpc_ops = NULL; 933 return (ENOMEM); 934 } 935 slot--; 936 mac_policy_offsets_free &= ~(1 << slot); 937 *mpc->mpc_field_off = slot; 938 } 939 mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; 940 LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); 941 942 /* Per-policy initialization. */ 943 if (mpc->mpc_ops->mpo_init != NULL) 944 (*(mpc->mpc_ops->mpo_init))(mpc); 945 MAC_POLICY_LIST_UNLOCK(); 946 947 printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, 948 mpc->mpc_name); 949 950 return (0); 951} 952 953static int 954mac_policy_unregister(struct mac_policy_conf *mpc) 955{ 956 957 /* 958 * If we fail the load, we may get a request to unload. Check 959 * to see if we did the run-time registration, and if not, 960 * silently succeed. 961 */ 962 MAC_POLICY_LIST_LOCK(); 963 if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) { 964 MAC_POLICY_LIST_UNLOCK(); 965 return (0); 966 } 967#if 0 968 /* 969 * Don't allow unloading modules with private data. 970 */ 971 if (mpc->mpc_field_off != NULL) { 972 MAC_POLICY_LIST_UNLOCK(); 973 return (EBUSY); 974 } 975#endif 976 /* 977 * Only allow the unload to proceed if the module is unloadable 978 * by its own definition. 979 */ 980 if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) { 981 MAC_POLICY_LIST_UNLOCK(); 982 return (EBUSY); 983 } 984 /* 985 * Right now, we EBUSY if the list is in use. In the future, 986 * for reliability reasons, we might want to sleep and wakeup 987 * later to try again. 988 */ 989 if (mac_policy_list_busy > 0) { 990 MAC_POLICY_LIST_UNLOCK(); 991 return (EBUSY); 992 } 993 if (mpc->mpc_ops->mpo_destroy != NULL) 994 (*(mpc->mpc_ops->mpo_destroy))(mpc); 995 996 LIST_REMOVE(mpc, mpc_list); 997 MAC_POLICY_LIST_UNLOCK(); 998 999 FREE(mpc->mpc_ops, M_MACOPVEC); 1000 mpc->mpc_ops = NULL; 1001 mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED; 1002 1003 printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, 1004 mpc->mpc_name); 1005 1006 return (0); 1007} 1008 1009/* 1010 * Define an error value precedence, and given two arguments, selects the 1011 * value with the higher precedence. 1012 */ 1013static int 1014error_select(int error1, int error2) 1015{ 1016 1017 /* Certain decision-making errors take top priority. */ 1018 if (error1 == EDEADLK || error2 == EDEADLK) 1019 return (EDEADLK); 1020 1021 /* Invalid arguments should be reported where possible. */ 1022 if (error1 == EINVAL || error2 == EINVAL) 1023 return (EINVAL); 1024 1025 /* Precedence goes to "visibility", with both process and file. */ 1026 if (error1 == ESRCH || error2 == ESRCH) 1027 return (ESRCH); 1028 1029 if (error1 == ENOENT || error2 == ENOENT) 1030 return (ENOENT); 1031 1032 /* Precedence goes to DAC/MAC protections. */ 1033 if (error1 == EACCES || error2 == EACCES) 1034 return (EACCES); 1035 1036 /* Precedence goes to privilege. */ 1037 if (error1 == EPERM || error2 == EPERM) 1038 return (EPERM); 1039 1040 /* Precedence goes to error over success; otherwise, arbitrary. */ 1041 if (error1 != 0) 1042 return (error1); 1043 return (error2); 1044} 1045 1046static void 1047mac_init_label(struct label *label) 1048{ 1049 1050 bzero(label, sizeof(*label)); 1051 label->l_flags = MAC_FLAG_INITIALIZED; 1052} 1053 1054static void 1055mac_destroy_label(struct label *label) 1056{ 1057 1058 KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 1059 ("destroying uninitialized label")); 1060 1061 bzero(label, sizeof(*label)); 1062 /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 1063} 1064 1065static void 1066mac_init_structmac(struct mac *mac) 1067{ 1068 1069 bzero(mac, sizeof(*mac)); 1070 mac->m_macflags = MAC_FLAG_INITIALIZED; 1071} 1072 1073void 1074mac_init_bpfdesc(struct bpf_d *bpf_d) 1075{ 1076 1077 mac_init_label(&bpf_d->bd_label); 1078 MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label); 1079#ifdef MAC_DEBUG 1080 atomic_add_int(&nmacbpfdescs, 1); 1081#endif 1082} 1083 1084void 1085mac_init_cred(struct ucred *cr) 1086{ 1087 1088 mac_init_label(&cr->cr_label); 1089 MAC_PERFORM(init_cred_label, &cr->cr_label); 1090#ifdef MAC_DEBUG 1091 atomic_add_int(&nmaccreds, 1); 1092#endif 1093} 1094 1095void 1096mac_init_devfsdirent(struct devfs_dirent *de) 1097{ 1098 1099 mac_init_label(&de->de_label); 1100 MAC_PERFORM(init_devfsdirent_label, &de->de_label); 1101#ifdef MAC_DEBUG 1102 atomic_add_int(&nmacdevfsdirents, 1); 1103#endif 1104} 1105 1106void 1107mac_init_ifnet(struct ifnet *ifp) 1108{ 1109 1110 mac_init_label(&ifp->if_label); 1111 MAC_PERFORM(init_ifnet_label, &ifp->if_label); 1112#ifdef MAC_DEBUG 1113 atomic_add_int(&nmacifnets, 1); 1114#endif 1115} 1116 1117void 1118mac_init_ipq(struct ipq *ipq) 1119{ 1120 1121 mac_init_label(&ipq->ipq_label); 1122 MAC_PERFORM(init_ipq_label, &ipq->ipq_label); 1123#ifdef MAC_DEBUG 1124 atomic_add_int(&nmacipqs, 1); 1125#endif 1126} 1127 1128int 1129mac_init_mbuf(struct mbuf *m, int flag) 1130{ 1131 int error; 1132 1133 KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf")); 1134 1135 mac_init_label(&m->m_pkthdr.label); 1136 1137 MAC_CHECK(init_mbuf_label, &m->m_pkthdr.label, flag); 1138 if (error) { 1139 MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 1140 mac_destroy_label(&m->m_pkthdr.label); 1141 } 1142 1143#ifdef MAC_DEBUG 1144 if (error == 0) 1145 atomic_add_int(&nmacmbufs, 1); 1146#endif 1147 return (error); 1148} 1149 1150void 1151mac_init_mount(struct mount *mp) 1152{ 1153 1154 mac_init_label(&mp->mnt_mntlabel); 1155 mac_init_label(&mp->mnt_fslabel); 1156 MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel); 1157 MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel); 1158#ifdef MAC_DEBUG 1159 atomic_add_int(&nmacmounts, 1); 1160#endif 1161} 1162 1163void 1164mac_init_pipe(struct pipe *pipe) 1165{ 1166 struct label *label; 1167 1168 label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 1169 mac_init_label(label); 1170 pipe->pipe_label = label; 1171 pipe->pipe_peer->pipe_label = label; 1172 MAC_PERFORM(init_pipe_label, pipe->pipe_label); 1173#ifdef MAC_DEBUG 1174 atomic_add_int(&nmacpipes, 1); 1175#endif 1176} 1177 1178static int 1179mac_init_socket_label(struct label *label, int flag) 1180{ 1181 int error; 1182 1183 mac_init_label(label); 1184 1185 MAC_CHECK(init_socket_label, label, flag); 1186 if (error) { 1187 MAC_PERFORM(destroy_socket_label, label); 1188 mac_destroy_label(label); 1189 } 1190 1191#ifdef MAC_DEBUG 1192 if (error == 0) 1193 atomic_add_int(&nmacsockets, 1); 1194#endif 1195 1196 return (error); 1197} 1198 1199static int 1200mac_init_socket_peer_label(struct label *label, int flag) 1201{ 1202 int error; 1203 1204 mac_init_label(label); 1205 1206 MAC_CHECK(init_socket_peer_label, label, flag); 1207 if (error) { 1208 MAC_PERFORM(destroy_socket_label, label); 1209 mac_destroy_label(label); 1210 } 1211 1212 return (error); 1213} 1214 1215int 1216mac_init_socket(struct socket *socket, int flag) 1217{ 1218 int error; 1219 1220 error = mac_init_socket_label(&socket->so_label, flag); 1221 if (error) 1222 return (error); 1223 1224 error = mac_init_socket_peer_label(&socket->so_peerlabel, flag); 1225 if (error) 1226 mac_destroy_socket_label(&socket->so_label); 1227 1228 return (error); 1229} 1230 1231static void 1232mac_init_temp(struct label *label) 1233{ 1234 1235 mac_init_label(label); 1236 MAC_PERFORM(init_temp_label, label); 1237#ifdef MAC_DEBUG 1238 atomic_add_int(&nmactemp, 1); 1239#endif 1240} 1241 1242void 1243mac_init_vnode(struct vnode *vp) 1244{ 1245 1246 mac_init_label(&vp->v_label); 1247 MAC_PERFORM(init_vnode_label, &vp->v_label); 1248#ifdef MAC_DEBUG 1249 atomic_add_int(&nmacvnodes, 1); 1250#endif 1251} 1252 1253void 1254mac_destroy_bpfdesc(struct bpf_d *bpf_d) 1255{ 1256 1257 MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label); 1258 mac_destroy_label(&bpf_d->bd_label); 1259#ifdef MAC_DEBUG 1260 atomic_subtract_int(&nmacbpfdescs, 1); 1261#endif 1262} 1263 1264void 1265mac_destroy_cred(struct ucred *cr) 1266{ 1267 1268 MAC_PERFORM(destroy_cred_label, &cr->cr_label); 1269 mac_destroy_label(&cr->cr_label); 1270#ifdef MAC_DEBUG 1271 atomic_subtract_int(&nmaccreds, 1); 1272#endif 1273} 1274 1275void 1276mac_destroy_devfsdirent(struct devfs_dirent *de) 1277{ 1278 1279 MAC_PERFORM(destroy_devfsdirent_label, &de->de_label); 1280 mac_destroy_label(&de->de_label); 1281#ifdef MAC_DEBUG 1282 atomic_subtract_int(&nmacdevfsdirents, 1); 1283#endif 1284} 1285 1286void 1287mac_destroy_ifnet(struct ifnet *ifp) 1288{ 1289 1290 MAC_PERFORM(destroy_ifnet_label, &ifp->if_label); 1291 mac_destroy_label(&ifp->if_label); 1292#ifdef MAC_DEBUG 1293 atomic_subtract_int(&nmacifnets, 1); 1294#endif 1295} 1296 1297void 1298mac_destroy_ipq(struct ipq *ipq) 1299{ 1300 1301 MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 1302 mac_destroy_label(&ipq->ipq_label); 1303#ifdef MAC_DEBUG 1304 atomic_subtract_int(&nmacipqs, 1); 1305#endif 1306} 1307 1308void 1309mac_destroy_mbuf(struct mbuf *m) 1310{ 1311 1312 MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 1313 mac_destroy_label(&m->m_pkthdr.label); 1314#ifdef MAC_DEBUG 1315 atomic_subtract_int(&nmacmbufs, 1); 1316#endif 1317} 1318 1319void 1320mac_destroy_mount(struct mount *mp) 1321{ 1322 1323 MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel); 1324 MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel); 1325 mac_destroy_label(&mp->mnt_fslabel); 1326 mac_destroy_label(&mp->mnt_mntlabel); 1327#ifdef MAC_DEBUG 1328 atomic_subtract_int(&nmacmounts, 1); 1329#endif 1330} 1331 1332void 1333mac_destroy_pipe(struct pipe *pipe) 1334{ 1335 1336 MAC_PERFORM(destroy_pipe_label, pipe->pipe_label); 1337 mac_destroy_label(pipe->pipe_label); 1338 free(pipe->pipe_label, M_MACPIPELABEL); 1339#ifdef MAC_DEBUG 1340 atomic_subtract_int(&nmacpipes, 1); 1341#endif 1342} 1343 1344static void 1345mac_destroy_socket_label(struct label *label) 1346{ 1347 1348 MAC_PERFORM(destroy_socket_label, label); 1349 mac_destroy_label(label); 1350#ifdef MAC_DEBUG 1351 atomic_subtract_int(&nmacsockets, 1); 1352#endif 1353} 1354 1355static void 1356mac_destroy_socket_peer_label(struct label *label) 1357{ 1358 1359 MAC_PERFORM(destroy_socket_peer_label, label); 1360 mac_destroy_label(label); 1361} 1362 1363void 1364mac_destroy_socket(struct socket *socket) 1365{ 1366 1367 mac_destroy_socket_label(&socket->so_label); 1368 mac_destroy_socket_peer_label(&socket->so_peerlabel); 1369} 1370 1371static void 1372mac_destroy_temp(struct label *label) 1373{ 1374 1375 MAC_PERFORM(destroy_temp_label, label); 1376 mac_destroy_label(label); 1377#ifdef MAC_DEBUG 1378 atomic_subtract_int(&nmactemp, 1); 1379#endif 1380} 1381 1382void 1383mac_destroy_vnode(struct vnode *vp) 1384{ 1385 1386 MAC_PERFORM(destroy_vnode_label, &vp->v_label); 1387 mac_destroy_label(&vp->v_label); 1388#ifdef MAC_DEBUG 1389 atomic_subtract_int(&nmacvnodes, 1); 1390#endif 1391} 1392 1393static int 1394mac_externalize(struct label *label, struct mac *mac) 1395{ 1396 int error; 1397 1398 mac_init_structmac(mac); 1399 MAC_CHECK(externalize, label, mac); 1400 1401 return (error); 1402} 1403 1404static int 1405mac_internalize(struct label *label, struct mac *mac) 1406{ 1407 int error; 1408 1409 mac_init_temp(label); 1410 MAC_CHECK(internalize, label, mac); 1411 if (error) 1412 mac_destroy_temp(label); 1413 1414 return (error); 1415} 1416 1417/* 1418 * Initialize MAC label for the first kernel process, from which other 1419 * kernel processes and threads are spawned. 1420 */ 1421void 1422mac_create_proc0(struct ucred *cred) 1423{ 1424 1425 MAC_PERFORM(create_proc0, cred); 1426} 1427 1428/* 1429 * Initialize MAC label for the first userland process, from which other 1430 * userland processes and threads are spawned. 1431 */ 1432void 1433mac_create_proc1(struct ucred *cred) 1434{ 1435 1436 MAC_PERFORM(create_proc1, cred); 1437} 1438 1439void 1440mac_thread_userret(struct thread *td) 1441{ 1442 1443 MAC_PERFORM(thread_userret, td); 1444} 1445 1446/* 1447 * When a new process is created, its label must be initialized. Generally, 1448 * this involves inheritence from the parent process, modulo possible 1449 * deltas. This function allows that processing to take place. 1450 */ 1451void 1452mac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 1453{ 1454 1455 MAC_PERFORM(create_cred, parent_cred, child_cred); 1456} 1457 1458void 1459mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp) 1460{ 1461 1462 MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label); 1463} 1464 1465void 1466mac_update_procfsvnode(struct vnode *vp, struct ucred *cred) 1467{ 1468 1469 MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred); 1470} 1471 1472/* 1473 * Support callout for policies that manage their own externalization 1474 * using extended attributes. 1475 */ 1476static int 1477mac_update_vnode_from_extattr(struct vnode *vp, struct mount *mp) 1478{ 1479 int error; 1480 1481 MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp, 1482 &mp->mnt_fslabel); 1483 1484 return (error); 1485} 1486 1487/* 1488 * Given an externalized mac label, internalize it and stamp it on a 1489 * vnode. 1490 */ 1491static int 1492mac_update_vnode_from_externalized(struct vnode *vp, struct mac *extmac) 1493{ 1494 int error; 1495 1496 MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac); 1497 1498 return (error); 1499} 1500 1501/* 1502 * Call out to individual policies to update the label in a vnode from 1503 * the mountpoint. 1504 */ 1505void 1506mac_update_vnode_from_mount(struct vnode *vp, struct mount *mp) 1507{ 1508 1509 MAC_PERFORM(update_vnode_from_mount, vp, &vp->v_label, mp, 1510 &mp->mnt_fslabel); 1511 1512 ASSERT_VOP_LOCKED(vp, "mac_update_vnode_from_mount"); 1513 if (mac_cache_fslabel_in_vnode) 1514 vp->v_vflag |= VV_CACHEDLABEL; 1515} 1516 1517/* 1518 * Implementation of VOP_REFRESHLABEL() that relies on extended attributes 1519 * to store label data. Can be referenced by filesystems supporting 1520 * extended attributes. 1521 */ 1522int 1523vop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap) 1524{ 1525 struct vnode *vp = ap->a_vp; 1526 struct mac extmac; 1527 int buflen, error; 1528 1529 ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea"); 1530 1531 /* 1532 * Call out to external policies first. Order doesn't really 1533 * matter, as long as failure of one assures failure of all. 1534 */ 1535 error = mac_update_vnode_from_extattr(vp, vp->v_mount); 1536 if (error) 1537 return (error); 1538 1539 buflen = sizeof(extmac); 1540 error = vn_extattr_get(vp, IO_NODELOCKED, 1541 FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, &buflen, 1542 (char *)&extmac, curthread); 1543 switch (error) { 1544 case 0: 1545 /* Got it */ 1546 break; 1547 1548 case ENOATTR: 1549 /* 1550 * Use the label from the mount point. 1551 */ 1552 mac_update_vnode_from_mount(vp, vp->v_mount); 1553 return (0); 1554 1555 case EOPNOTSUPP: 1556 default: 1557 /* Fail horribly. */ 1558 return (error); 1559 } 1560 1561 if (buflen != sizeof(extmac)) 1562 error = EPERM; /* Fail very closed. */ 1563 if (error == 0) 1564 error = mac_update_vnode_from_externalized(vp, &extmac); 1565 if (error == 0) 1566 vp->v_vflag |= VV_CACHEDLABEL; 1567 else { 1568 struct vattr va; 1569 1570 printf("Corrupted label on %s", 1571 vp->v_mount->mnt_stat.f_mntonname); 1572 if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread) == 0) 1573 printf(" inum %ld", va.va_fileid); 1574#ifdef MAC_DEBUG 1575 if (mac_debug_label_fallback) { 1576 printf(", falling back.\n"); 1577 mac_update_vnode_from_mount(vp, vp->v_mount); 1578 error = 0; 1579 } else { 1580#endif 1581 printf(".\n"); 1582 error = EPERM; 1583#ifdef MAC_DEBUG 1584 } 1585#endif 1586 } 1587 1588 return (error); 1589} 1590 1591/* 1592 * Make sure the vnode label is up-to-date. If EOPNOTSUPP, then we handle 1593 * the labeling activity outselves. Filesystems should be careful not 1594 * to change their minds regarding whether they support vop_refreshlabel() 1595 * for a vnode or not. Don't cache the vnode here, allow the file 1596 * system code to determine if it's safe to cache. If we update from 1597 * the mount, don't cache since a change to the mount label should affect 1598 * all vnodes. 1599 */ 1600static int 1601vn_refreshlabel(struct vnode *vp, struct ucred *cred) 1602{ 1603 int error; 1604 1605 ASSERT_VOP_LOCKED(vp, "vn_refreshlabel"); 1606 1607 if (vp->v_mount == NULL) { 1608/* 1609 Eventually, we probably want to special-case refreshing 1610 of deadfs vnodes, and if there's a lock-free race somewhere, 1611 that case might be handled here. 1612 1613 mac_update_vnode_deadfs(vp); 1614 return (0); 1615 */ 1616 /* printf("vn_refreshlabel: null v_mount\n"); */ 1617 if (vp->v_type != VNON) 1618 printf( 1619 "vn_refreshlabel: null v_mount with non-VNON\n"); 1620 return (EBADF); 1621 } 1622 1623 if (vp->v_vflag & VV_CACHEDLABEL) { 1624 mac_vnode_label_cache_hits++; 1625 return (0); 1626 } else 1627 mac_vnode_label_cache_misses++; 1628 1629 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) { 1630 mac_update_vnode_from_mount(vp, vp->v_mount); 1631 return (0); 1632 } 1633 1634 error = VOP_REFRESHLABEL(vp, cred, curthread); 1635 switch (error) { 1636 case EOPNOTSUPP: 1637 /* 1638 * If labels are not supported on this vnode, fall back to 1639 * the label in the mount and propagate it to the vnode. 1640 * There should probably be some sort of policy/flag/decision 1641 * about doing this. 1642 */ 1643 mac_update_vnode_from_mount(vp, vp->v_mount); 1644 error = 0; 1645 default: 1646 return (error); 1647 } 1648} 1649 1650/* 1651 * Helper function for file systems using the vop_std*_ea() calls. This 1652 * function must be called after EA service is available for the vnode, 1653 * but before it's hooked up to the namespace so that the node persists 1654 * if there's a crash, or before it can be accessed. On successful 1655 * commit of the label to disk (etc), do cache the label. 1656 */ 1657int 1658vop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp, struct ucred *cred) 1659{ 1660 struct mac extmac; 1661 int error; 1662 1663 ASSERT_VOP_LOCKED(tvp, "vop_stdcreatevnode_ea"); 1664 if ((dvp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) { 1665 mac_update_vnode_from_mount(tvp, tvp->v_mount); 1666 } else { 1667 error = vn_refreshlabel(dvp, cred); 1668 if (error) 1669 return (error); 1670 1671 /* 1672 * Stick the label in the vnode. Then try to write to 1673 * disk. If we fail, return a failure to abort the 1674 * create operation. Really, this failure shouldn't 1675 * happen except in fairly unusual circumstances (out 1676 * of disk, etc). 1677 */ 1678 mac_create_vnode(cred, dvp, tvp); 1679 1680 error = mac_stdcreatevnode_ea(tvp); 1681 if (error) 1682 return (error); 1683 1684 /* 1685 * XXX: Eventually this will go away and all policies will 1686 * directly manage their extended attributes. 1687 */ 1688 error = mac_externalize(&tvp->v_label, &extmac); 1689 if (error) 1690 return (error); 1691 1692 error = vn_extattr_set(tvp, IO_NODELOCKED, 1693 FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, 1694 sizeof(extmac), (char *)&extmac, curthread); 1695 if (error == 0) 1696 tvp->v_vflag |= VV_CACHEDLABEL; 1697 else { 1698#if 0 1699 /* 1700 * In theory, we could have fall-back behavior here. 1701 * It would probably be incorrect. 1702 */ 1703#endif 1704 return (error); 1705 } 1706 } 1707 1708 return (0); 1709} 1710 1711void 1712mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp) 1713{ 1714 int error; 1715 1716 ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1717 1718 error = vn_refreshlabel(vp, old); 1719 if (error) { 1720 printf("mac_execve_transition: vn_refreshlabel returned %d\n", 1721 error); 1722 printf("mac_execve_transition: using old vnode label\n"); 1723 } 1724 1725 MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label); 1726} 1727 1728int 1729mac_execve_will_transition(struct ucred *old, struct vnode *vp) 1730{ 1731 int error, result; 1732 1733 error = vn_refreshlabel(vp, old); 1734 if (error) 1735 return (error); 1736 1737 result = 0; 1738 MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label); 1739 1740 return (result); 1741} 1742 1743int 1744mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags) 1745{ 1746 int error; 1747 1748 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1749 1750 if (!mac_enforce_fs) 1751 return (0); 1752 1753 error = vn_refreshlabel(vp, cred); 1754 if (error) 1755 return (error); 1756 1757 MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags); 1758 return (error); 1759} 1760 1761int 1762mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 1763{ 1764 int error; 1765 1766 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 1767 1768 if (!mac_enforce_fs) 1769 return (0); 1770 1771 error = vn_refreshlabel(dvp, cred); 1772 if (error) 1773 return (error); 1774 1775 MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 1776 return (error); 1777} 1778 1779int 1780mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 1781{ 1782 int error; 1783 1784 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 1785 1786 if (!mac_enforce_fs) 1787 return (0); 1788 1789 error = vn_refreshlabel(dvp, cred); 1790 if (error) 1791 return (error); 1792 1793 MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1794 return (error); 1795} 1796 1797int 1798mac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1799 struct componentname *cnp, struct vattr *vap) 1800{ 1801 int error; 1802 1803 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1804 1805 if (!mac_enforce_fs) 1806 return (0); 1807 1808 error = vn_refreshlabel(dvp, cred); 1809 if (error) 1810 return (error); 1811 1812 MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 1813 return (error); 1814} 1815 1816int 1817mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 1818 struct componentname *cnp) 1819{ 1820 int error; 1821 1822 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 1823 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 1824 1825 if (!mac_enforce_fs) 1826 return (0); 1827 1828 error = vn_refreshlabel(dvp, cred); 1829 if (error) 1830 return (error); 1831 error = vn_refreshlabel(vp, cred); 1832 if (error) 1833 return (error); 1834 1835 MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1836 &vp->v_label, cnp); 1837 return (error); 1838} 1839 1840int 1841mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1842 acl_type_t type) 1843{ 1844 int error; 1845 1846 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1847 1848 if (!mac_enforce_fs) 1849 return (0); 1850 1851 error = vn_refreshlabel(vp, cred); 1852 if (error) 1853 return (error); 1854 1855 MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1856 return (error); 1857} 1858 1859int 1860mac_check_vnode_exec(struct ucred *cred, struct vnode *vp) 1861{ 1862 int error; 1863 1864 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1865 1866 if (!mac_enforce_process && !mac_enforce_fs) 1867 return (0); 1868 1869 error = vn_refreshlabel(vp, cred); 1870 if (error) 1871 return (error); 1872 MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label); 1873 1874 return (error); 1875} 1876 1877int 1878mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1879{ 1880 int error; 1881 1882 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1883 1884 if (!mac_enforce_fs) 1885 return (0); 1886 1887 error = vn_refreshlabel(vp, cred); 1888 if (error) 1889 return (error); 1890 1891 MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1892 return (error); 1893} 1894 1895int 1896mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1897 int attrnamespace, const char *name, struct uio *uio) 1898{ 1899 int error; 1900 1901 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1902 1903 if (!mac_enforce_fs) 1904 return (0); 1905 1906 error = vn_refreshlabel(vp, cred); 1907 if (error) 1908 return (error); 1909 1910 MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1911 attrnamespace, name, uio); 1912 return (error); 1913} 1914 1915int 1916mac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 1917 struct vnode *vp, struct componentname *cnp) 1918{ 1919 1920 int error; 1921 1922 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link"); 1923 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link"); 1924 1925 if (!mac_enforce_fs) 1926 return (0); 1927 1928 error = vn_refreshlabel(dvp, cred); 1929 if (error) 1930 return (error); 1931 1932 error = vn_refreshlabel(vp, cred); 1933 if (error) 1934 return (error); 1935 1936 MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp, 1937 &vp->v_label, cnp); 1938 return (error); 1939} 1940 1941int 1942mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1943 struct componentname *cnp) 1944{ 1945 int error; 1946 1947 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 1948 1949 if (!mac_enforce_fs) 1950 return (0); 1951 1952 error = vn_refreshlabel(dvp, cred); 1953 if (error) 1954 return (error); 1955 1956 MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 1957 return (error); 1958} 1959 1960int 1961mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) 1962{ 1963 int error; 1964 1965 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); 1966 1967 if (!mac_enforce_fs || !mac_enforce_vm) 1968 return (0); 1969 1970 error = vn_refreshlabel(vp, cred); 1971 if (error) 1972 return (error); 1973 1974 MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); 1975 return (error); 1976} 1977 1978void 1979mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) 1980{ 1981 int result = *prot; 1982 1983 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); 1984 1985 if (!mac_enforce_fs || !mac_enforce_vm) 1986 return; 1987 1988 MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, 1989 &result); 1990 1991 *prot = result; 1992} 1993 1994int 1995mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) 1996{ 1997 int error; 1998 1999 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); 2000 2001 if (!mac_enforce_fs || !mac_enforce_vm) 2002 return (0); 2003 2004 error = vn_refreshlabel(vp, cred); 2005 if (error) 2006 return (error); 2007 2008 MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); 2009 return (error); 2010} 2011 2012int 2013mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode) 2014{ 2015 int error; 2016 2017 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 2018 2019 if (!mac_enforce_fs) 2020 return (0); 2021 2022 error = vn_refreshlabel(vp, cred); 2023 if (error) 2024 return (error); 2025 2026 MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 2027 return (error); 2028} 2029 2030int 2031mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2032 struct vnode *vp) 2033{ 2034 int error; 2035 2036 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 2037 2038 if (!mac_enforce_fs) 2039 return (0); 2040 2041 error = vn_refreshlabel(vp, active_cred); 2042 if (error) 2043 return (error); 2044 2045 MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 2046 &vp->v_label); 2047 2048 return (error); 2049} 2050 2051int 2052mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2053 struct vnode *vp) 2054{ 2055 int error; 2056 2057 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 2058 2059 if (!mac_enforce_fs) 2060 return (0); 2061 2062 error = vn_refreshlabel(vp, active_cred); 2063 if (error) 2064 return (error); 2065 2066 MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 2067 &vp->v_label); 2068 2069 return (error); 2070} 2071 2072int 2073mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 2074{ 2075 int error; 2076 2077 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 2078 2079 if (!mac_enforce_fs) 2080 return (0); 2081 2082 error = vn_refreshlabel(dvp, cred); 2083 if (error) 2084 return (error); 2085 2086 MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 2087 return (error); 2088} 2089 2090int 2091mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 2092{ 2093 int error; 2094 2095 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 2096 2097 if (!mac_enforce_fs) 2098 return (0); 2099 2100 error = vn_refreshlabel(vp, cred); 2101 if (error) 2102 return (error); 2103 2104 MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 2105 return (error); 2106} 2107 2108static int 2109mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2110 struct label *newlabel) 2111{ 2112 int error; 2113 2114 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 2115 2116 error = vn_refreshlabel(vp, cred); 2117 if (error) 2118 return (error); 2119 2120 MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 2121 2122 return (error); 2123} 2124 2125int 2126mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2127 struct vnode *vp, struct componentname *cnp) 2128{ 2129 int error; 2130 2131 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 2132 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 2133 2134 if (!mac_enforce_fs) 2135 return (0); 2136 2137 error = vn_refreshlabel(dvp, cred); 2138 if (error) 2139 return (error); 2140 error = vn_refreshlabel(vp, cred); 2141 if (error) 2142 return (error); 2143 2144 MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 2145 &vp->v_label, cnp); 2146 return (error); 2147} 2148 2149int 2150mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2151 struct vnode *vp, int samedir, struct componentname *cnp) 2152{ 2153 int error; 2154 2155 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 2156 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 2157 2158 if (!mac_enforce_fs) 2159 return (0); 2160 2161 error = vn_refreshlabel(dvp, cred); 2162 if (error) 2163 return (error); 2164 if (vp != NULL) { 2165 error = vn_refreshlabel(vp, cred); 2166 if (error) 2167 return (error); 2168 } 2169 MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 2170 vp != NULL ? &vp->v_label : NULL, samedir, cnp); 2171 return (error); 2172} 2173 2174int 2175mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 2176{ 2177 int error; 2178 2179 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 2180 2181 if (!mac_enforce_fs) 2182 return (0); 2183 2184 error = vn_refreshlabel(vp, cred); 2185 if (error) 2186 return (error); 2187 2188 MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 2189 return (error); 2190} 2191 2192int 2193mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 2194 struct acl *acl) 2195{ 2196 int error; 2197 2198 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 2199 2200 if (!mac_enforce_fs) 2201 return (0); 2202 2203 error = vn_refreshlabel(vp, cred); 2204 if (error) 2205 return (error); 2206 2207 MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 2208 return (error); 2209} 2210 2211int 2212mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2213 int attrnamespace, const char *name, struct uio *uio) 2214{ 2215 int error; 2216 2217 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 2218 2219 if (!mac_enforce_fs) 2220 return (0); 2221 2222 error = vn_refreshlabel(vp, cred); 2223 if (error) 2224 return (error); 2225 2226 MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 2227 attrnamespace, name, uio); 2228 return (error); 2229} 2230 2231int 2232mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 2233{ 2234 int error; 2235 2236 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 2237 2238 if (!mac_enforce_fs) 2239 return (0); 2240 2241 error = vn_refreshlabel(vp, cred); 2242 if (error) 2243 return (error); 2244 2245 MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 2246 return (error); 2247} 2248 2249int 2250mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 2251{ 2252 int error; 2253 2254 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 2255 2256 if (!mac_enforce_fs) 2257 return (0); 2258 2259 error = vn_refreshlabel(vp, cred); 2260 if (error) 2261 return (error); 2262 2263 MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 2264 return (error); 2265} 2266 2267int 2268mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 2269 gid_t gid) 2270{ 2271 int error; 2272 2273 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 2274 2275 if (!mac_enforce_fs) 2276 return (0); 2277 2278 error = vn_refreshlabel(vp, cred); 2279 if (error) 2280 return (error); 2281 2282 MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 2283 return (error); 2284} 2285 2286int 2287mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2288 struct timespec atime, struct timespec mtime) 2289{ 2290 int error; 2291 2292 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 2293 2294 if (!mac_enforce_fs) 2295 return (0); 2296 2297 error = vn_refreshlabel(vp, cred); 2298 if (error) 2299 return (error); 2300 2301 MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 2302 mtime); 2303 return (error); 2304} 2305 2306int 2307mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2308 struct vnode *vp) 2309{ 2310 int error; 2311 2312 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 2313 2314 if (!mac_enforce_fs) 2315 return (0); 2316 2317 error = vn_refreshlabel(vp, active_cred); 2318 if (error) 2319 return (error); 2320 2321 MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 2322 &vp->v_label); 2323 return (error); 2324} 2325 2326int 2327mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 2328 struct vnode *vp) 2329{ 2330 int error; 2331 2332 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 2333 2334 if (!mac_enforce_fs) 2335 return (0); 2336 2337 error = vn_refreshlabel(vp, active_cred); 2338 if (error) 2339 return (error); 2340 2341 MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 2342 &vp->v_label); 2343 2344 return (error); 2345} 2346 2347/* 2348 * When relabeling a process, call out to the policies for the maximum 2349 * permission allowed for each object type we know about in its 2350 * memory space, and revoke access (in the least surprising ways we 2351 * know) when necessary. The process lock is not held here. 2352 */ 2353static void 2354mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 2355{ 2356 2357 /* XXX freeze all other threads */ 2358 mac_cred_mmapped_drop_perms_recurse(td, cred, 2359 &td->td_proc->p_vmspace->vm_map); 2360 /* XXX allow other threads to continue */ 2361} 2362 2363static __inline const char * 2364prot2str(vm_prot_t prot) 2365{ 2366 2367 switch (prot & VM_PROT_ALL) { 2368 case VM_PROT_READ: 2369 return ("r--"); 2370 case VM_PROT_READ | VM_PROT_WRITE: 2371 return ("rw-"); 2372 case VM_PROT_READ | VM_PROT_EXECUTE: 2373 return ("r-x"); 2374 case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 2375 return ("rwx"); 2376 case VM_PROT_WRITE: 2377 return ("-w-"); 2378 case VM_PROT_EXECUTE: 2379 return ("--x"); 2380 case VM_PROT_WRITE | VM_PROT_EXECUTE: 2381 return ("-wx"); 2382 default: 2383 return ("---"); 2384 } 2385} 2386 2387static void 2388mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 2389 struct vm_map *map) 2390{ 2391 struct vm_map_entry *vme; 2392 int result; 2393 vm_prot_t revokeperms; 2394 vm_object_t object; 2395 vm_ooffset_t offset; 2396 struct vnode *vp; 2397 2398 if (!mac_mmap_revocation) 2399 return; 2400 2401 vm_map_lock_read(map); 2402 for (vme = map->header.next; vme != &map->header; vme = vme->next) { 2403 if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 2404 mac_cred_mmapped_drop_perms_recurse(td, cred, 2405 vme->object.sub_map); 2406 continue; 2407 } 2408 /* 2409 * Skip over entries that obviously are not shared. 2410 */ 2411 if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 2412 !vme->max_protection) 2413 continue; 2414 /* 2415 * Drill down to the deepest backing object. 2416 */ 2417 offset = vme->offset; 2418 object = vme->object.vm_object; 2419 if (object == NULL) 2420 continue; 2421 while (object->backing_object != NULL) { 2422 object = object->backing_object; 2423 offset += object->backing_object_offset; 2424 } 2425 /* 2426 * At the moment, vm_maps and objects aren't considered 2427 * by the MAC system, so only things with backing by a 2428 * normal object (read: vnodes) are checked. 2429 */ 2430 if (object->type != OBJT_VNODE) 2431 continue; 2432 vp = (struct vnode *)object->handle; 2433 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2434 result = vme->max_protection; 2435 mac_check_vnode_mmap_downgrade(cred, vp, &result); 2436 VOP_UNLOCK(vp, 0, td); 2437 /* 2438 * Find out what maximum protection we may be allowing 2439 * now but a policy needs to get removed. 2440 */ 2441 revokeperms = vme->max_protection & ~result; 2442 if (!revokeperms) 2443 continue; 2444 printf("pid %ld: revoking %s perms from %#lx:%ld " 2445 "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 2446 prot2str(revokeperms), (u_long)vme->start, 2447 (long)(vme->end - vme->start), 2448 prot2str(vme->max_protection), prot2str(vme->protection)); 2449 vm_map_lock_upgrade(map); 2450 /* 2451 * This is the really simple case: if a map has more 2452 * max_protection than is allowed, but it's not being 2453 * actually used (that is, the current protection is 2454 * still allowed), we can just wipe it out and do 2455 * nothing more. 2456 */ 2457 if ((vme->protection & revokeperms) == 0) { 2458 vme->max_protection -= revokeperms; 2459 } else { 2460 if (revokeperms & VM_PROT_WRITE) { 2461 /* 2462 * In the more complicated case, flush out all 2463 * pending changes to the object then turn it 2464 * copy-on-write. 2465 */ 2466 vm_object_reference(object); 2467 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2468 vm_object_page_clean(object, 2469 OFF_TO_IDX(offset), 2470 OFF_TO_IDX(offset + vme->end - vme->start + 2471 PAGE_MASK), 2472 OBJPC_SYNC); 2473 VOP_UNLOCK(vp, 0, td); 2474 vm_object_deallocate(object); 2475 /* 2476 * Why bother if there's no read permissions 2477 * anymore? For the rest, we need to leave 2478 * the write permissions on for COW, or 2479 * remove them entirely if configured to. 2480 */ 2481 if (!mac_mmap_revocation_via_cow) { 2482 vme->max_protection &= ~VM_PROT_WRITE; 2483 vme->protection &= ~VM_PROT_WRITE; 2484 } if ((revokeperms & VM_PROT_READ) == 0) 2485 vme->eflags |= MAP_ENTRY_COW | 2486 MAP_ENTRY_NEEDS_COPY; 2487 } 2488 if (revokeperms & VM_PROT_EXECUTE) { 2489 vme->max_protection &= ~VM_PROT_EXECUTE; 2490 vme->protection &= ~VM_PROT_EXECUTE; 2491 } 2492 if (revokeperms & VM_PROT_READ) { 2493 vme->max_protection = 0; 2494 vme->protection = 0; 2495 } 2496 pmap_protect(map->pmap, vme->start, vme->end, 2497 vme->protection & ~revokeperms); 2498 vm_map_simplify_entry(map, vme); 2499 } 2500 vm_map_lock_downgrade(map); 2501 } 2502 vm_map_unlock_read(map); 2503} 2504 2505/* 2506 * When the subject's label changes, it may require revocation of privilege 2507 * to mapped objects. This can't be done on-the-fly later with a unified 2508 * buffer cache. 2509 */ 2510static void 2511mac_relabel_cred(struct ucred *cred, struct label *newlabel) 2512{ 2513 2514 MAC_PERFORM(relabel_cred, cred, newlabel); 2515} 2516 2517void 2518mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 2519{ 2520 2521 MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 2522} 2523 2524void 2525mac_create_ifnet(struct ifnet *ifnet) 2526{ 2527 2528 MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2529} 2530 2531void 2532mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2533{ 2534 2535 MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2536} 2537 2538void 2539mac_create_socket(struct ucred *cred, struct socket *socket) 2540{ 2541 2542 MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2543} 2544 2545void 2546mac_create_pipe(struct ucred *cred, struct pipe *pipe) 2547{ 2548 2549 MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2550} 2551 2552void 2553mac_create_socket_from_socket(struct socket *oldsocket, 2554 struct socket *newsocket) 2555{ 2556 2557 MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2558 newsocket, &newsocket->so_label); 2559} 2560 2561static void 2562mac_relabel_socket(struct ucred *cred, struct socket *socket, 2563 struct label *newlabel) 2564{ 2565 2566 MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2567} 2568 2569static void 2570mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2571{ 2572 2573 MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2574} 2575 2576void 2577mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2578{ 2579 2580 MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label, 2581 socket, &socket->so_peerlabel); 2582} 2583 2584void 2585mac_set_socket_peer_from_socket(struct socket *oldsocket, 2586 struct socket *newsocket) 2587{ 2588 2589 MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2590 &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2591} 2592 2593void 2594mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2595{ 2596 2597 MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2598 datagram, &datagram->m_pkthdr.label); 2599} 2600 2601void 2602mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2603{ 2604 2605 MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label, 2606 fragment, &fragment->m_pkthdr.label); 2607} 2608 2609void 2610mac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2611{ 2612 2613 MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2614 &ipq->ipq_label); 2615} 2616 2617void 2618mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2619{ 2620 2621 MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label, 2622 newmbuf, &newmbuf->m_pkthdr.label); 2623} 2624 2625void 2626mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2627{ 2628 2629 MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2630 &mbuf->m_pkthdr.label); 2631} 2632 2633void 2634mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2635{ 2636 2637 MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2638 &mbuf->m_pkthdr.label); 2639} 2640 2641void 2642mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2643{ 2644 2645 MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2646 &mbuf->m_pkthdr.label); 2647} 2648 2649void 2650mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2651 struct mbuf *newmbuf) 2652{ 2653 2654 MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, 2655 &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf, 2656 &newmbuf->m_pkthdr.label); 2657} 2658 2659void 2660mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2661{ 2662 2663 MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label, 2664 newmbuf, &newmbuf->m_pkthdr.label); 2665} 2666 2667int 2668mac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2669{ 2670 int result; 2671 2672 result = 1; 2673 MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label, 2674 ipq, &ipq->ipq_label); 2675 2676 return (result); 2677} 2678 2679void 2680mac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2681{ 2682 2683 MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2684 &ipq->ipq_label); 2685} 2686 2687void 2688mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2689{ 2690 2691 MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2692 &mbuf->m_pkthdr.label); 2693} 2694 2695void 2696mac_create_mount(struct ucred *cred, struct mount *mp) 2697{ 2698 2699 MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2700 &mp->mnt_fslabel); 2701} 2702 2703void 2704mac_create_root_mount(struct ucred *cred, struct mount *mp) 2705{ 2706 2707 MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2708 &mp->mnt_fslabel); 2709} 2710 2711int 2712mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2713{ 2714 int error; 2715 2716 if (!mac_enforce_network) 2717 return (0); 2718 2719 MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2720 &ifnet->if_label); 2721 2722 return (error); 2723} 2724 2725static int 2726mac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2727{ 2728 int error; 2729 2730 MAC_CHECK(check_cred_relabel, cred, newlabel); 2731 2732 return (error); 2733} 2734 2735int 2736mac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2737{ 2738 int error; 2739 2740 if (!mac_enforce_process) 2741 return (0); 2742 2743 MAC_CHECK(check_cred_visible, u1, u2); 2744 2745 return (error); 2746} 2747 2748int 2749mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2750{ 2751 int error; 2752 2753 if (!mac_enforce_network) 2754 return (0); 2755 2756 KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr")); 2757 if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED)) 2758 printf("%s%d: not initialized\n", ifnet->if_name, 2759 ifnet->if_unit); 2760 2761 MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2762 &mbuf->m_pkthdr.label); 2763 2764 return (error); 2765} 2766 2767int 2768mac_check_mount_stat(struct ucred *cred, struct mount *mount) 2769{ 2770 int error; 2771 2772 if (!mac_enforce_fs) 2773 return (0); 2774 2775 MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2776 2777 return (error); 2778} 2779 2780int 2781mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2782 void *data) 2783{ 2784 int error; 2785 2786 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2787 2788 if (!mac_enforce_pipe) 2789 return (0); 2790 2791 MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2792 2793 return (error); 2794} 2795 2796int 2797mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2798{ 2799 int error; 2800 2801 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2802 2803 if (!mac_enforce_pipe) 2804 return (0); 2805 2806 MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2807 2808 return (error); 2809} 2810 2811int 2812mac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2813{ 2814 int error; 2815 2816 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2817 2818 if (!mac_enforce_pipe) 2819 return (0); 2820 2821 MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2822 2823 return (error); 2824} 2825 2826static int 2827mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2828 struct label *newlabel) 2829{ 2830 int error; 2831 2832 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2833 2834 if (!mac_enforce_pipe) 2835 return (0); 2836 2837 MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2838 2839 return (error); 2840} 2841 2842int 2843mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2844{ 2845 int error; 2846 2847 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2848 2849 if (!mac_enforce_pipe) 2850 return (0); 2851 2852 MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2853 2854 return (error); 2855} 2856 2857int 2858mac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2859{ 2860 int error; 2861 2862 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2863 2864 if (!mac_enforce_pipe) 2865 return (0); 2866 2867 MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2868 2869 return (error); 2870} 2871 2872int 2873mac_check_proc_debug(struct ucred *cred, struct proc *proc) 2874{ 2875 int error; 2876 2877 PROC_LOCK_ASSERT(proc, MA_OWNED); 2878 2879 if (!mac_enforce_process) 2880 return (0); 2881 2882 MAC_CHECK(check_proc_debug, cred, proc); 2883 2884 return (error); 2885} 2886 2887int 2888mac_check_proc_sched(struct ucred *cred, struct proc *proc) 2889{ 2890 int error; 2891 2892 PROC_LOCK_ASSERT(proc, MA_OWNED); 2893 2894 if (!mac_enforce_process) 2895 return (0); 2896 2897 MAC_CHECK(check_proc_sched, cred, proc); 2898 2899 return (error); 2900} 2901 2902int 2903mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2904{ 2905 int error; 2906 2907 PROC_LOCK_ASSERT(proc, MA_OWNED); 2908 2909 if (!mac_enforce_process) 2910 return (0); 2911 2912 MAC_CHECK(check_proc_signal, cred, proc, signum); 2913 2914 return (error); 2915} 2916 2917int 2918mac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2919 struct sockaddr *sockaddr) 2920{ 2921 int error; 2922 2923 if (!mac_enforce_socket) 2924 return (0); 2925 2926 MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2927 sockaddr); 2928 2929 return (error); 2930} 2931 2932int 2933mac_check_socket_connect(struct ucred *cred, struct socket *socket, 2934 struct sockaddr *sockaddr) 2935{ 2936 int error; 2937 2938 if (!mac_enforce_socket) 2939 return (0); 2940 2941 MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2942 sockaddr); 2943 2944 return (error); 2945} 2946 2947int 2948mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2949{ 2950 int error; 2951 2952 if (!mac_enforce_socket) 2953 return (0); 2954 2955 MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2956 &mbuf->m_pkthdr.label); 2957 2958 return (error); 2959} 2960 2961int 2962mac_check_socket_listen(struct ucred *cred, struct socket *socket) 2963{ 2964 int error; 2965 2966 if (!mac_enforce_socket) 2967 return (0); 2968 2969 MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2970 return (error); 2971} 2972 2973int 2974mac_check_socket_receive(struct ucred *cred, struct socket *so) 2975{ 2976 int error; 2977 2978 if (!mac_enforce_socket) 2979 return (0); 2980 2981 MAC_CHECK(check_socket_receive, cred, so, &so->so_label); 2982 2983 return (error); 2984} 2985 2986static int 2987mac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2988 struct label *newlabel) 2989{ 2990 int error; 2991 2992 MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2993 newlabel); 2994 2995 return (error); 2996} 2997 2998int 2999mac_check_socket_send(struct ucred *cred, struct socket *so) 3000{ 3001 int error; 3002 3003 if (!mac_enforce_socket) 3004 return (0); 3005 3006 MAC_CHECK(check_socket_send, cred, so, &so->so_label); 3007 3008 return (error); 3009} 3010 3011int 3012mac_check_socket_visible(struct ucred *cred, struct socket *socket) 3013{ 3014 int error; 3015 3016 if (!mac_enforce_socket) 3017 return (0); 3018 3019 MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 3020 3021 return (error); 3022} 3023 3024int 3025mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 3026 struct ifnet *ifnet) 3027{ 3028 struct mac label; 3029 int error; 3030 3031 error = mac_externalize(&ifnet->if_label, &label); 3032 if (error) 3033 return (error); 3034 3035 return (copyout(&label, ifr->ifr_ifru.ifru_data, sizeof(label))); 3036} 3037 3038int 3039mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 3040 struct ifnet *ifnet) 3041{ 3042 struct mac newlabel; 3043 struct label intlabel; 3044 int error; 3045 3046 error = copyin(ifr->ifr_ifru.ifru_data, &newlabel, sizeof(newlabel)); 3047 if (error) 3048 return (error); 3049 3050 error = mac_internalize(&intlabel, &newlabel); 3051 if (error) 3052 return (error); 3053 3054 /* 3055 * XXX: Note that this is a redundant privilege check, since 3056 * policies impose this check themselves if required by the 3057 * policy. Eventually, this should go away. 3058 */ 3059 error = suser_cred(cred, 0); 3060 if (error) 3061 goto out; 3062 3063 MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 3064 &intlabel); 3065 if (error) 3066 goto out; 3067 3068 MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 3069 3070out: 3071 mac_destroy_temp(&intlabel); 3072 return (error); 3073} 3074 3075void 3076mac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp) 3077{ 3078 3079 MAC_PERFORM(create_devfs_vnode, de, &de->de_label, vp, &vp->v_label); 3080} 3081 3082void 3083mac_create_devfs_device(dev_t dev, struct devfs_dirent *de) 3084{ 3085 3086 MAC_PERFORM(create_devfs_device, dev, de, &de->de_label); 3087} 3088 3089void 3090mac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd, 3091 struct devfs_dirent *de) 3092{ 3093 3094 MAC_PERFORM(create_devfs_symlink, cred, dd, &dd->de_label, de, 3095 &de->de_label); 3096} 3097 3098static int 3099mac_stdcreatevnode_ea(struct vnode *vp) 3100{ 3101 int error; 3102 3103 MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label); 3104 3105 return (error); 3106} 3107 3108void 3109mac_create_devfs_directory(char *dirname, int dirnamelen, 3110 struct devfs_dirent *de) 3111{ 3112 3113 MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de, 3114 &de->de_label); 3115} 3116 3117/* 3118 * When a new vnode is created, this call will initialize its label. 3119 */ 3120void 3121mac_create_vnode(struct ucred *cred, struct vnode *parent, 3122 struct vnode *child) 3123{ 3124 int error; 3125 3126 ASSERT_VOP_LOCKED(parent, "mac_create_vnode"); 3127 ASSERT_VOP_LOCKED(child, "mac_create_vnode"); 3128 3129 error = vn_refreshlabel(parent, cred); 3130 if (error) { 3131 printf("mac_create_vnode: vn_refreshlabel returned %d\n", 3132 error); 3133 printf("mac_create_vnode: using old vnode label\n"); 3134 } 3135 3136 MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child, 3137 &child->v_label); 3138} 3139 3140int 3141mac_setsockopt_label_set(struct ucred *cred, struct socket *so, 3142 struct mac *extmac) 3143{ 3144 struct label intlabel; 3145 int error; 3146 3147 error = mac_internalize(&intlabel, extmac); 3148 if (error) 3149 return (error); 3150 3151 mac_check_socket_relabel(cred, so, &intlabel); 3152 if (error) { 3153 mac_destroy_temp(&intlabel); 3154 return (error); 3155 } 3156 3157 mac_relabel_socket(cred, so, &intlabel); 3158 3159 mac_destroy_temp(&intlabel); 3160 return (0); 3161} 3162 3163int 3164mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 3165{ 3166 int error; 3167 3168 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 3169 3170 error = mac_check_pipe_relabel(cred, pipe, label); 3171 if (error) 3172 return (error); 3173 3174 mac_relabel_pipe(cred, pipe, label); 3175 3176 return (0); 3177} 3178 3179int 3180mac_getsockopt_label_get(struct ucred *cred, struct socket *so, 3181 struct mac *extmac) 3182{ 3183 3184 return (mac_externalize(&so->so_label, extmac)); 3185} 3186 3187int 3188mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 3189 struct mac *extmac) 3190{ 3191 3192 return (mac_externalize(&so->so_peerlabel, extmac)); 3193} 3194 3195/* 3196 * Implementation of VOP_SETLABEL() that relies on extended attributes 3197 * to store label data. Can be referenced by filesystems supporting 3198 * extended attributes. 3199 */ 3200int 3201vop_stdsetlabel_ea(struct vop_setlabel_args *ap) 3202{ 3203 struct vnode *vp = ap->a_vp; 3204 struct label *intlabel = ap->a_label; 3205 struct mac extmac; 3206 int error; 3207 3208 ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 3209 3210 /* 3211 * XXX: Eventually call out to EA check/set calls here. 3212 * Be particularly careful to avoid race conditions, 3213 * consistency problems, and stability problems when 3214 * dealing with multiple EAs. In particular, we require 3215 * the ability to write multiple EAs on the same file in 3216 * a single transaction, which the current EA interface 3217 * does not provide. 3218 */ 3219 3220 error = mac_externalize(intlabel, &extmac); 3221 if (error) 3222 return (error); 3223 3224 error = vn_extattr_set(vp, IO_NODELOCKED, 3225 FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, 3226 sizeof(extmac), (char *)&extmac, curthread); 3227 if (error) 3228 return (error); 3229 3230 mac_relabel_vnode(ap->a_cred, vp, intlabel); 3231 3232 vp->v_vflag |= VV_CACHEDLABEL; 3233 3234 return (0); 3235} 3236 3237static int 3238vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 3239{ 3240 int error; 3241 3242 if (vp->v_mount == NULL) { 3243 /* printf("vn_setlabel: null v_mount\n"); */ 3244 if (vp->v_type != VNON) 3245 printf("vn_setlabel: null v_mount with non-VNON\n"); 3246 return (EBADF); 3247 } 3248 3249 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3250 return (EOPNOTSUPP); 3251 3252 /* 3253 * Multi-phase commit. First check the policies to confirm the 3254 * change is OK. Then commit via the filesystem. Finally, 3255 * update the actual vnode label. Question: maybe the filesystem 3256 * should update the vnode at the end as part of VOP_SETLABEL()? 3257 */ 3258 error = mac_check_vnode_relabel(cred, vp, intlabel); 3259 if (error) 3260 return (error); 3261 3262 /* 3263 * VADMIN provides the opportunity for the filesystem to make 3264 * decisions about who is and is not able to modify labels 3265 * and protections on files. This might not be right. We can't 3266 * assume VOP_SETLABEL() will do it, because we might implement 3267 * that as part of vop_stdsetlabel_ea(). 3268 */ 3269 error = VOP_ACCESS(vp, VADMIN, cred, curthread); 3270 if (error) 3271 return (error); 3272 3273 error = VOP_SETLABEL(vp, intlabel, cred, curthread); 3274 if (error) 3275 return (error); 3276 3277 return (0); 3278} 3279 3280/* 3281 * MPSAFE 3282 */ 3283int 3284__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3285{ 3286 struct mac extmac; 3287 int error; 3288 3289 error = mac_externalize(&td->td_ucred->cr_label, &extmac); 3290 if (error == 0) 3291 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac)); 3292 3293 return (error); 3294} 3295 3296/* 3297 * MPSAFE 3298 */ 3299int 3300__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3301{ 3302 struct ucred *newcred, *oldcred; 3303 struct proc *p; 3304 struct mac extmac; 3305 struct label intlabel; 3306 int error; 3307 3308 error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac)); 3309 if (error) 3310 return (error); 3311 3312 error = mac_internalize(&intlabel, &extmac); 3313 if (error) 3314 return (error); 3315 3316 newcred = crget(); 3317 3318 p = td->td_proc; 3319 PROC_LOCK(p); 3320 oldcred = p->p_ucred; 3321 3322 error = mac_check_cred_relabel(oldcred, &intlabel); 3323 if (error) { 3324 PROC_UNLOCK(p); 3325 mac_destroy_temp(&intlabel); 3326 crfree(newcred); 3327 return (error); 3328 } 3329 3330 setsugid(p); 3331 crcopy(newcred, oldcred); 3332 mac_relabel_cred(newcred, &intlabel); 3333 p->p_ucred = newcred; 3334 3335 /* 3336 * Grab additional reference for use while revoking mmaps, prior 3337 * to releasing the proc lock and sharing the cred. 3338 */ 3339 crhold(newcred); 3340 PROC_UNLOCK(p); 3341 3342 mtx_lock(&Giant); 3343 mac_cred_mmapped_drop_perms(td, newcred); 3344 mtx_unlock(&Giant); 3345 3346 crfree(newcred); /* Free revocation reference. */ 3347 crfree(oldcred); 3348 mac_destroy_temp(&intlabel); 3349 return (0); 3350} 3351 3352/* 3353 * MPSAFE 3354 */ 3355int 3356__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3357{ 3358 struct file *fp; 3359 struct mac extmac; 3360 struct vnode *vp; 3361 struct pipe *pipe; 3362 int error; 3363 3364 mtx_lock(&Giant); 3365 3366 error = fget(td, SCARG(uap, fd), &fp); 3367 if (error) 3368 goto out; 3369 3370 switch (fp->f_type) { 3371 case DTYPE_FIFO: 3372 case DTYPE_VNODE: 3373 vp = (struct vnode *)fp->f_data; 3374 3375 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3376 error = vn_refreshlabel(vp, td->td_ucred); 3377 if (error == 0) 3378 error = mac_externalize(&vp->v_label, &extmac); 3379 VOP_UNLOCK(vp, 0, td); 3380 break; 3381 case DTYPE_PIPE: 3382 pipe = (struct pipe *)fp->f_data; 3383 error = mac_externalize(pipe->pipe_label, &extmac); 3384 break; 3385 default: 3386 error = EINVAL; 3387 } 3388 3389 if (error == 0) 3390 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac)); 3391 3392 fdrop(fp, td); 3393 3394out: 3395 mtx_unlock(&Giant); 3396 return (error); 3397} 3398 3399/* 3400 * MPSAFE 3401 */ 3402int 3403__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3404{ 3405 struct nameidata nd; 3406 struct mac extmac; 3407 int error; 3408 3409 mtx_lock(&Giant); 3410 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, 3411 SCARG(uap, path_p), td); 3412 error = namei(&nd); 3413 if (error) 3414 goto out; 3415 3416 error = vn_refreshlabel(nd.ni_vp, td->td_ucred); 3417 if (error == 0) 3418 error = mac_externalize(&nd.ni_vp->v_label, &extmac); 3419 NDFREE(&nd, 0); 3420 if (error) 3421 goto out; 3422 3423 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac)); 3424 3425out: 3426 mtx_unlock(&Giant); 3427 return (error); 3428} 3429 3430/* 3431 * MPSAFE 3432 */ 3433int 3434__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3435{ 3436 struct file *fp; 3437 struct mac extmac; 3438 struct label intlabel; 3439 struct mount *mp; 3440 struct vnode *vp; 3441 struct pipe *pipe; 3442 int error; 3443 3444 mtx_lock(&Giant); 3445 error = fget(td, SCARG(uap, fd), &fp); 3446 if (error) 3447 goto out1; 3448 3449 error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac)); 3450 if (error) 3451 goto out2; 3452 3453 error = mac_internalize(&intlabel, &extmac); 3454 if (error) 3455 goto out2; 3456 3457 switch (fp->f_type) { 3458 case DTYPE_FIFO: 3459 case DTYPE_VNODE: 3460 vp = (struct vnode *)fp->f_data; 3461 error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3462 if (error != 0) 3463 break; 3464 3465 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3466 error = vn_setlabel(vp, &intlabel, td->td_ucred); 3467 VOP_UNLOCK(vp, 0, td); 3468 vn_finished_write(mp); 3469 mac_destroy_temp(&intlabel); 3470 break; 3471 case DTYPE_PIPE: 3472 pipe = (struct pipe *)fp->f_data; 3473 PIPE_LOCK(pipe); 3474 error = mac_pipe_label_set(td->td_ucred, pipe, &intlabel); 3475 PIPE_UNLOCK(pipe); 3476 break; 3477 default: 3478 error = EINVAL; 3479 } 3480 3481out2: 3482 fdrop(fp, td); 3483out1: 3484 mtx_unlock(&Giant); 3485 return (error); 3486} 3487 3488/* 3489 * MPSAFE 3490 */ 3491int 3492__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3493{ 3494 struct nameidata nd; 3495 struct mac extmac; 3496 struct label intlabel; 3497 struct mount *mp; 3498 int error; 3499 3500 mtx_lock(&Giant); 3501 3502 error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac)); 3503 if (error) 3504 goto out; 3505 3506 error = mac_internalize(&intlabel, &extmac); 3507 if (error) 3508 goto out; 3509 3510 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, 3511 SCARG(uap, path_p), td); 3512 error = namei(&nd); 3513 if (error) 3514 goto out2; 3515 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3516 if (error) 3517 goto out2; 3518 3519 error = vn_setlabel(nd.ni_vp, &intlabel, td->td_ucred); 3520 3521 vn_finished_write(mp); 3522out2: 3523 mac_destroy_temp(&intlabel); 3524 NDFREE(&nd, 0); 3525out: 3526 mtx_unlock(&Giant); 3527 return (error); 3528} 3529 3530int 3531mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3532{ 3533 struct mac_policy_conf *mpc; 3534 char target[MAC_MAX_POLICY_NAME]; 3535 int error; 3536 3537 error = copyinstr(SCARG(uap, policy), target, sizeof(target), NULL); 3538 if (error) 3539 return (error); 3540 3541 error = ENOSYS; 3542 MAC_POLICY_LIST_BUSY(); 3543 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3544 if (strcmp(mpc->mpc_name, target) == 0 && 3545 mpc->mpc_ops->mpo_syscall != NULL) { 3546 error = mpc->mpc_ops->mpo_syscall(td, 3547 SCARG(uap, call), SCARG(uap, arg)); 3548 goto out; 3549 } 3550 } 3551 3552out: 3553 MAC_POLICY_LIST_UNBUSY(); 3554 return (error); 3555} 3556 3557SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3558SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3559 3560#else /* !MAC */ 3561 3562int 3563__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3564{ 3565 3566 return (ENOSYS); 3567} 3568 3569int 3570__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3571{ 3572 3573 return (ENOSYS); 3574} 3575 3576int 3577__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3578{ 3579 3580 return (ENOSYS); 3581} 3582 3583int 3584__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3585{ 3586 3587 return (ENOSYS); 3588} 3589 3590int 3591__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3592{ 3593 3594 return (ENOSYS); 3595} 3596 3597int 3598__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3599{ 3600 3601 return (ENOSYS); 3602} 3603 3604int 3605mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3606{ 3607 3608 return (ENOSYS); 3609} 3610 3611#endif /* !MAC */ 3612