mac_syscalls.c revision 104236
1153761Swollman/*- 2192886Sedwin * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 3192886Sedwin * Copyright (c) 2001 Ilmar S. Habibulin 4153761Swollman * Copyright (c) 2001, 2002 Networks Associates Technology, Inc. 52742Swollman * All rights reserved. 686464Swollman * 72742Swollman * This software was developed by Robert Watson and Ilmar Habibulin for the 82742Swollman * TrustedBSD Project. 92742Swollman * 102742Swollman * This software was developed for the FreeBSD Project in part by NAI Labs, 112742Swollman * the Security Research Division of Network Associates, Inc. under 122742Swollman * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 1386222Swollman * CHATS research program. 1486222Swollman * 152742Swollman * Redistribution and use in source and binary forms, with or without 1658787Sru * modification, are permitted provided that the following conditions 172742Swollman * are met: 182742Swollman * 1. Redistributions of source code must retain the above copyright 192742Swollman * notice, this list of conditions and the following disclaimer. 202742Swollman * 2. Redistributions in binary form must reproduce the above copyright 212742Swollman * notice, this list of conditions and the following disclaimer in the 222742Swollman * documentation and/or other materials provided with the distribution. 2358787Sru * 3. The names of the authors may not be used to endorse or promote 2458787Sru * products derived from this software without specific prior written 2558787Sru * permission. 262742Swollman * 272742Swollman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 289908Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 292742Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3030711Swollman * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 312742Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 329908Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33169811Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34169811Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35169811Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36169811Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37169811Swollman * SUCH DAMAGE. 38169811Swollman * 39169811Swollman * $FreeBSD: head/sys/security/mac/mac_syscalls.c 104236 2002-09-30 20:50:00Z rwatson $ 40169811Swollman */ 41169811Swollman/* 42169811Swollman * Developed by the TrustedBSD Project. 43169811Swollman * 442742Swollman * Framework for extensible kernel access control. Kernel and userland 4558787Sru * interface to the framework, policy registration and composition. 46169811Swollman */ 47169811Swollman 48169811Swollman#include "opt_mac.h" 49169811Swollman 50169811Swollman#include <sys/param.h> 519908Swollman#include <sys/extattr.h> 5220094Swollman#include <sys/kernel.h> 53149514Swollman#include <sys/lock.h> 5420094Swollman#include <sys/malloc.h> 5520094Swollman#include <sys/mutex.h> 5620094Swollman#include <sys/mac.h> 5720094Swollman#include <sys/module.h> 5820094Swollman#include <sys/proc.h> 5920094Swollman#include <sys/systm.h> 6020094Swollman#include <sys/sysproto.h> 6120094Swollman#include <sys/sysent.h> 6220094Swollman#include <sys/vnode.h> 6320094Swollman#include <sys/mount.h> 6420094Swollman#include <sys/file.h> 6558787Sru#include <sys/namei.h> 6658787Sru#include <sys/socket.h> 6721217Swollman#include <sys/pipe.h> 6821217Swollman#include <sys/socketvar.h> 6958787Sru#include <sys/sysctl.h> 7058787Sru 712742Swollman#include <vm/vm.h> 7258787Sru#include <vm/pmap.h> 7321217Swollman#include <vm/vm_map.h> 7420094Swollman#include <vm/vm_object.h> 7558787Sru 7658787Sru#include <sys/mac_policy.h> 7720094Swollman 782742Swollman#include <fs/devfs/devfs.h> 799908Swollman 802742Swollman#include <net/bpfdesc.h> 8114343Swollman#include <net/if.h> 8214343Swollman#include <net/if_var.h> 83171948Sedwin 8414343Swollman#include <netinet/in.h> 8514343Swollman#include <netinet/ip_var.h> 86218122Sedwin 87218122Sedwin#ifdef MAC 88218122Sedwin 89218122Sedwin/* 90218122Sedwin * Declare that the kernel provides MAC support, version 1. This permits 91149514Swollman * modules to refuse to be loaded if the necessary support isn't present, 92218122Sedwin * even if it's pre-boot. 93171948Sedwin */ 94171948SedwinMODULE_VERSION(kernel_mac_support, 1); 95171948Sedwin 962742SwollmanSYSCTL_DECL(_security); 972742Swollman 982742SwollmanSYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0, 9958787Sru "TrustedBSD MAC policy controls"); 1002742SwollmanSYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0, 1012742Swollman "TrustedBSD MAC debug info"); 1029908Swollman 103149514Swollmanstatic int mac_debug_label_fallback = 0; 104149514SwollmanSYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW, 105149514Swollman &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label" 106149514Swollman "when label is corrupted."); 107149514SwollmanTUNABLE_INT("security.mac.debug_label_fallback", 1082742Swollman &mac_debug_label_fallback); 10958787Sru 11058787Sru#ifndef MAC_MAX_POLICIES 11114343Swollman#define MAC_MAX_POLICIES 8 11214343Swollman#endif 11358787Sru#if MAC_MAX_POLICIES > 32 11414343Swollman#error "MAC_MAX_POLICIES too large" 11514343Swollman#endif 11614343Swollmanstatic unsigned int mac_max_policies = MAC_MAX_POLICIES; 11758787Srustatic unsigned int mac_policy_offsets_free = (1 << MAC_MAX_POLICIES) - 1; 11814343SwollmanSYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD, 11958787Sru &mac_max_policies, 0, ""); 12058787Sru 12158787Srustatic int mac_late = 0; 122149514Swollman 12358787Srustatic int mac_enforce_fs = 1; 12458787SruSYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW, 125149514Swollman &mac_enforce_fs, 0, "Enforce MAC policy on file system objects"); 126171948SedwinTUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs); 127171948Sedwin 1282742Swollmanstatic int mac_enforce_network = 1; 1292742SwollmanSYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, 13058787Sru &mac_enforce_network, 0, "Enforce MAC policy on network packets"); 13158787SruTUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); 13258787Sru 1332742Swollmanstatic int mac_enforce_pipe = 1; 134149514SwollmanSYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW, 135149514Swollman &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations"); 136149514SwollmanTUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe); 137149514Swollman 138149514Swollmanstatic int mac_enforce_process = 1; 1392742SwollmanSYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW, 1409908Swollman &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations"); 1412742SwollmanTUNABLE_INT("security.mac.enforce_process", &mac_enforce_process); 14214343Swollman 14358787Srustatic int mac_enforce_socket = 1; 14414343SwollmanSYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 14514343Swollman &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 14658787SruTUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 14758787Sru 14814343Swollmanstatic int mac_enforce_vm = 1; 149149514SwollmanSYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW, 15058787Sru &mac_enforce_vm, 0, "Enforce MAC policy on vm operations"); 151171948SedwinTUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm); 152149514Swollman 153171948Sedwinstatic int mac_label_size = sizeof(struct mac); 154171948SedwinSYSCTL_INT(_security_mac, OID_AUTO, label_size, CTLFLAG_RD, 155171948Sedwin &mac_label_size, 0, "Pre-compiled MAC label size"); 1562742Swollman 1572742Swollmanstatic int mac_cache_fslabel_in_vnode = 1; 15858787SruSYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW, 1592742Swollman &mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode"); 1602742SwollmanTUNABLE_INT("security.mac.cache_fslabel_in_vnode", 1619908Swollman &mac_cache_fslabel_in_vnode); 1622742Swollman 16314343Swollmanstatic int mac_vnode_label_cache_hits = 0; 16414343SwollmanSYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_hits, CTLFLAG_RD, 16514343Swollman &mac_vnode_label_cache_hits, 0, "Cache hits on vnode labels"); 16614343Swollmanstatic int mac_vnode_label_cache_misses = 0; 16714343SwollmanSYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_misses, CTLFLAG_RD, 16814343Swollman &mac_vnode_label_cache_misses, 0, "Cache misses on vnode labels"); 16914343Swollman 17043543Swollmanstatic int mac_mmap_revocation = 1; 17114343SwollmanSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW, 172149514Swollman &mac_mmap_revocation, 0, "Revoke mmap access to files on subject " 17358787Sru "relabel"); 174171948Sedwinstatic int mac_mmap_revocation_via_cow = 0; 175149514SwollmanSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW, 176171948Sedwin &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via " 177171948Sedwin "copy-on-write semantics, or by removing all write access"); 178171948Sedwin 1792742Swollman#ifdef MAC_DEBUG 1802742Swollmanstatic unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs, 18158787Sru nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents, 1822742Swollman nmacipqs, nmacpipes; 1832742SwollmanSYSCTL_UINT(_security_mac_debug, OID_AUTO, mbufs, CTLFLAG_RD, 1842742Swollman &nmacmbufs, 0, "number of mbufs in use"); 1852742SwollmanSYSCTL_UINT(_security_mac_debug, OID_AUTO, creds, CTLFLAG_RD, 18658787Sru &nmaccreds, 0, "number of ucreds in use"); 18758787SruSYSCTL_UINT(_security_mac_debug, OID_AUTO, ifnets, CTLFLAG_RD, 18858787Sru &nmacifnets, 0, "number of ifnets in use"); 1898029SwollmanSYSCTL_UINT(_security_mac_debug, OID_AUTO, ipqs, CTLFLAG_RD, 19014343Swollman &nmacipqs, 0, "number of ipqs in use"); 19114343SwollmanSYSCTL_UINT(_security_mac_debug, OID_AUTO, bpfdescs, CTLFLAG_RD, 19275267Swollman &nmacbpfdescs, 0, "number of bpfdescs in use"); 19375267SwollmanSYSCTL_UINT(_security_mac_debug, OID_AUTO, sockets, CTLFLAG_RD, 19475267Swollman &nmacsockets, 0, "number of sockets in use"); 19575267SwollmanSYSCTL_UINT(_security_mac_debug, OID_AUTO, pipes, CTLFLAG_RD, 19675267Swollman &nmacpipes, 0, "number of pipes in use"); 19775267SwollmanSYSCTL_UINT(_security_mac_debug, OID_AUTO, mounts, CTLFLAG_RD, 19875267Swollman &nmacmounts, 0, "number of mounts in use"); 199149514SwollmanSYSCTL_UINT(_security_mac_debug, OID_AUTO, temp, CTLFLAG_RD, 20075267Swollman &nmactemp, 0, "number of temporary labels in use"); 201171948SedwinSYSCTL_UINT(_security_mac_debug, OID_AUTO, vnodes, CTLFLAG_RD, 202149514Swollman &nmacvnodes, 0, "number of vnodes in use"); 203171948SedwinSYSCTL_UINT(_security_mac_debug, OID_AUTO, devfsdirents, CTLFLAG_RD, 204171948Sedwin &nmacdevfsdirents, 0, "number of devfs dirents inuse"); 205171948Sedwin#endif 2062742Swollman 2072742Swollmanstatic int error_select(int error1, int error2); 20814343Swollmanstatic int mac_externalize(struct label *label, struct mac *mac); 2098029Swollmanstatic int mac_policy_register(struct mac_policy_conf *mpc); 21014343Swollmanstatic int mac_policy_unregister(struct mac_policy_conf *mpc); 2112742Swollman 2122742Swollmanstatic int mac_stdcreatevnode_ea(struct vnode *vp); 21314343Swollmanstatic void mac_cred_mmapped_drop_perms(struct thread *td, 214169811Swollman struct ucred *cred); 2152742Swollmanstatic void mac_cred_mmapped_drop_perms_recurse(struct thread *td, 21614343Swollman struct ucred *cred, struct vm_map *map); 21714343Swollman 218169811SwollmanMALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector"); 21914343SwollmanMALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes"); 22030711Swollman 22130711Swollman/* 22258787Sru * mac_policy_list_lock protects the consistency of 'mac_policy_list', 223169811Swollman * the linked list of attached policy modules. Read-only consumers of 2242742Swollman * the list must acquire a shared lock for the duration of their use; 22543014Swollman * writers must acquire an exclusive lock. Note that for compound 22643014Swollman * operations, locks should be held for the entire compound operation, 22743014Swollman * and that this is not yet done for relabel requests. 22843014Swollman */ 2292742Swollmanstatic struct mtx mac_policy_list_lock; 2302742Swollmanstatic LIST_HEAD(, mac_policy_conf) mac_policy_list; 231158421Swollmanstatic int mac_policy_list_busy; 2322742Swollman#define MAC_POLICY_LIST_LOCKINIT() mtx_init(&mac_policy_list_lock, \ 23319878Swollman "mac_policy_list_lock", NULL, MTX_DEF); 23443014Swollman#define MAC_POLICY_LIST_LOCK() mtx_lock(&mac_policy_list_lock); 23543014Swollman#define MAC_POLICY_LIST_UNLOCK() mtx_unlock(&mac_policy_list_lock); 2362742Swollman 2372742Swollman#define MAC_POLICY_LIST_BUSY() do { \ 23819878Swollman MAC_POLICY_LIST_LOCK(); \ 23919878Swollman mac_policy_list_busy++; \ 2402742Swollman MAC_POLICY_LIST_UNLOCK(); \ 2412742Swollman} while (0) 242149514Swollman 243149514Swollman#define MAC_POLICY_LIST_UNBUSY() do { \ 2442742Swollman MAC_POLICY_LIST_LOCK(); \ 245149514Swollman mac_policy_list_busy--; \ 246149514Swollman if (mac_policy_list_busy < 0) \ 2472742Swollman panic("Extra mac_policy_list_busy--"); \ 2482742Swollman MAC_POLICY_LIST_UNLOCK(); \ 249199336Sedwin} while (0) 250199336Sedwin 251199336Sedwin/* 252199336Sedwin * MAC_CHECK performs the designated check by walking the policy 253199336Sedwin * module list and checking with each as to how it feels about the 254199336Sedwin * request. Note that it returns its value via 'error' in the scope 255199336Sedwin * of the caller. 256199336Sedwin */ 257199336Sedwin#define MAC_CHECK(check, args...) do { \ 258199336Sedwin struct mac_policy_conf *mpc; \ 259199336Sedwin \ 260199336Sedwin error = 0; \ 261199336Sedwin MAC_POLICY_LIST_BUSY(); \ 262199336Sedwin LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 263199336Sedwin if (mpc->mpc_ops->mpo_ ## check != NULL) \ 264199336Sedwin error = error_select( \ 265199336Sedwin mpc->mpc_ops->mpo_ ## check (args), \ 266199336Sedwin error); \ 267199336Sedwin } \ 268204887Sedwin MAC_POLICY_LIST_UNBUSY(); \ 269204887Sedwin} while (0) 270204887Sedwin 271204887Sedwin/* 272204887Sedwin * MAC_BOOLEAN performs the designated boolean composition by walking 273204887Sedwin * the module list, invoking each instance of the operation, and 274204887Sedwin * combining the results using the passed C operator. Note that it 275204887Sedwin * returns its value via 'result' in the scope of the caller, which 276204887Sedwin * should be initialized by the caller in a meaningful way to get 277204887Sedwin * a meaningful result. 278204887Sedwin */ 279204887Sedwin#define MAC_BOOLEAN(operation, composition, args...) do { \ 280204887Sedwin struct mac_policy_conf *mpc; \ 281204887Sedwin \ 282204887Sedwin MAC_POLICY_LIST_BUSY(); \ 283204887Sedwin LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 284204887Sedwin if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 285214722Sedwin result = result composition \ 286240457Sedwin mpc->mpc_ops->mpo_ ## operation (args); \ 287214722Sedwin } \ 288240457Sedwin MAC_POLICY_LIST_UNBUSY(); \ 289214722Sedwin} while (0) 290214722Sedwin 291214722Sedwin/* 292214722Sedwin * MAC_PERFORM performs the designated operation by walking the policy 293214722Sedwin * module list and invoking that operation for each policy. 294214722Sedwin */ 295214722Sedwin#define MAC_PERFORM(operation, args...) do { \ 296214722Sedwin struct mac_policy_conf *mpc; \ 297214722Sedwin \ 298226289Sedwin MAC_POLICY_LIST_BUSY(); \ 299240457Sedwin LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 300226289Sedwin if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 301226289Sedwin mpc->mpc_ops->mpo_ ## operation (args); \ 302226289Sedwin } \ 303226289Sedwin MAC_POLICY_LIST_UNBUSY(); \ 304226289Sedwin} while (0) 305226289Sedwin 306240457Sedwin/* 307240457Sedwin * Initialize the MAC subsystem, including appropriate SMP locks. 308226289Sedwin */ 309226289Sedwinstatic void 310226976Sedwinmac_init(void) 311226976Sedwin{ 312226976Sedwin 313226976Sedwin LIST_INIT(&mac_policy_list); 314226976Sedwin MAC_POLICY_LIST_LOCKINIT(); 315226976Sedwin} 316226976Sedwin 317226976Sedwin/* 318226976Sedwin * For the purposes of modules that want to know if they were loaded 319226976Sedwin * "early", set the mac_late flag once we've processed modules either 320226976Sedwin * linked into the kernel, or loaded before the kernel startup. 321226976Sedwin */ 322226976Sedwinstatic void 323226976Sedwinmac_late_init(void) 324240457Sedwin{ 325240457Sedwin 326240457Sedwin mac_late = 1; 327240457Sedwin} 328240457Sedwin 329240457Sedwin/* 330240457Sedwin * Allow MAC policy modules to register during boot, etc. 331240457Sedwin */ 332240457Sedwinint 33343543Swollmanmac_policy_modevent(module_t mod, int type, void *data) 33475267Swollman{ 33575267Swollman struct mac_policy_conf *mpc; 336199336Sedwin int error; 337204887Sedwin 338240457Sedwin error = 0; 339214722Sedwin mpc = (struct mac_policy_conf *) data; 340240457Sedwin 3412742Swollman switch (type) { 3422742Swollman case MOD_LOAD: 34343543Swollman if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && 3442742Swollman mac_late) { 3452742Swollman printf("mac_policy_modevent: can't load %s policy " 3462742Swollman "after booting\n", mpc->mpc_name); 3472742Swollman error = EBUSY; 34819878Swollman break; 3492742Swollman } 35019878Swollman error = mac_policy_register(mpc); 3512742Swollman break; 35219878Swollman case MOD_UNLOAD: 35343014Swollman /* Don't unregister the module if it was never registered. */ 35443014Swollman if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) 3552742Swollman != 0) 3562742Swollman error = mac_policy_unregister(mpc); 3572742Swollman else 35875267Swollman error = 0; 35975267Swollman break; 36075267Swollman default: 36175267Swollman break; 3622742Swollman } 3632742Swollman 3642742Swollman return (error); 3652742Swollman} 36619878Swollman 3672742Swollmanstatic int 36819878Swollmanmac_policy_register(struct mac_policy_conf *mpc) 36919878Swollman{ 37019878Swollman struct mac_policy_conf *tmpc; 3712742Swollman struct mac_policy_op_entry *mpe; 37219878Swollman int slot; 37319878Swollman 37419878Swollman MALLOC(mpc->mpc_ops, struct mac_policy_ops *, sizeof(*mpc->mpc_ops), 3752742Swollman M_MACOPVEC, M_WAITOK | M_ZERO); 37614343Swollman for (mpe = mpc->mpc_entries; mpe->mpe_constant != MAC_OP_LAST; mpe++) { 37714343Swollman switch (mpe->mpe_constant) { 37875267Swollman case MAC_OP_LAST: 37975267Swollman /* 38019878Swollman * Doesn't actually happen, but this allows checking 38175267Swollman * that all enumerated values are handled. 38275267Swollman */ 38314343Swollman break; 38414343Swollman case MAC_DESTROY: 38514343Swollman mpc->mpc_ops->mpo_destroy = 38614343Swollman mpe->mpe_function; 38719878Swollman break; 38819878Swollman case MAC_INIT: 38914343Swollman mpc->mpc_ops->mpo_init = 39019878Swollman mpe->mpe_function; 39119878Swollman break; 39219878Swollman case MAC_SYSCALL: 39314343Swollman mpc->mpc_ops->mpo_syscall = 39414343Swollman mpe->mpe_function; 39514343Swollman break; 396210718Sedwin case MAC_INIT_BPFDESC: 397210718Sedwin mpc->mpc_ops->mpo_init_bpfdesc = 398210718Sedwin mpe->mpe_function; 399210718Sedwin break; 40014343Swollman case MAC_INIT_CRED: 40158787Sru mpc->mpc_ops->mpo_init_cred = 40258787Sru mpe->mpe_function; 40358787Sru break; 40414343Swollman case MAC_INIT_DEVFSDIRENT: 4052742Swollman mpc->mpc_ops->mpo_init_devfsdirent = 4062742Swollman mpe->mpe_function; 4072742Swollman break; 40819878Swollman case MAC_INIT_IFNET: 4092742Swollman mpc->mpc_ops->mpo_init_ifnet = 41019878Swollman mpe->mpe_function; 41119878Swollman break; 4122742Swollman case MAC_INIT_IPQ: 4132742Swollman mpc->mpc_ops->mpo_init_ipq = 4142742Swollman mpe->mpe_function; 41519878Swollman break; 41619878Swollman case MAC_INIT_MBUF: 41743014Swollman mpc->mpc_ops->mpo_init_mbuf = 418158421Swollman mpe->mpe_function; 41943014Swollman break; 4202742Swollman case MAC_INIT_MOUNT: 4212742Swollman mpc->mpc_ops->mpo_init_mount = 4222742Swollman mpe->mpe_function; 4232742Swollman break; 4242742Swollman case MAC_INIT_PIPE: 4252742Swollman mpc->mpc_ops->mpo_init_pipe = 4262742Swollman mpe->mpe_function; 4272742Swollman break; 4282742Swollman case MAC_INIT_SOCKET: 4292742Swollman mpc->mpc_ops->mpo_init_socket = 430121098Swollman mpe->mpe_function; 431121098Swollman break; 432121098Swollman case MAC_INIT_TEMP: 433121098Swollman mpc->mpc_ops->mpo_init_temp = 434121098Swollman mpe->mpe_function; 435121098Swollman break; 436121098Swollman case MAC_INIT_VNODE: 437121098Swollman mpc->mpc_ops->mpo_init_vnode = 438121098Swollman mpe->mpe_function; 439114173Swollman break; 440121098Swollman case MAC_DESTROY_BPFDESC: 441114173Swollman mpc->mpc_ops->mpo_destroy_bpfdesc = 442121098Swollman mpe->mpe_function; 4439908Swollman break; 444121098Swollman case MAC_DESTROY_CRED: 445114173Swollman mpc->mpc_ops->mpo_destroy_cred = 446121098Swollman mpe->mpe_function; 447114173Swollman break; 448121098Swollman case MAC_DESTROY_DEVFSDIRENT: 449169811Swollman mpc->mpc_ops->mpo_destroy_devfsdirent = 450169811Swollman mpe->mpe_function; 451169811Swollman break; 452169811Swollman case MAC_DESTROY_IFNET: 453169811Swollman mpc->mpc_ops->mpo_destroy_ifnet = 454169811Swollman mpe->mpe_function; 455169811Swollman break; 456169811Swollman case MAC_DESTROY_IPQ: 4572742Swollman mpc->mpc_ops->mpo_destroy_ipq = 458114173Swollman mpe->mpe_function; 459121098Swollman break; 4602742Swollman case MAC_DESTROY_MBUF: 461121098Swollman mpc->mpc_ops->mpo_destroy_mbuf = 462121098Swollman mpe->mpe_function; 4632742Swollman break; 4648029Swollman case MAC_DESTROY_MOUNT: 46530711Swollman mpc->mpc_ops->mpo_destroy_mount = 46658787Sru mpe->mpe_function; 46758787Sru break; 4682742Swollman case MAC_DESTROY_PIPE: 46930711Swollman mpc->mpc_ops->mpo_destroy_pipe = 47058787Sru mpe->mpe_function; 47158787Sru break; 47258787Sru case MAC_DESTROY_SOCKET: 47330711Swollman mpc->mpc_ops->mpo_destroy_socket = 47430711Swollman mpe->mpe_function; 4752742Swollman break; 4762742Swollman case MAC_DESTROY_TEMP: 4772742Swollman mpc->mpc_ops->mpo_destroy_temp = 4782742Swollman mpe->mpe_function; 4792742Swollman break; 4802742Swollman case MAC_DESTROY_VNODE: 48119878Swollman mpc->mpc_ops->mpo_destroy_vnode = 48219878Swollman mpe->mpe_function; 48319878Swollman break; 4842742Swollman case MAC_EXTERNALIZE: 4852742Swollman mpc->mpc_ops->mpo_externalize = 4862742Swollman mpe->mpe_function; 4872742Swollman break; 48819878Swollman case MAC_INTERNALIZE: 48919878Swollman mpc->mpc_ops->mpo_internalize = 4902742Swollman mpe->mpe_function; 49158787Sru break; 4929908Swollman case MAC_CREATE_DEVFS_DEVICE: 4939908Swollman mpc->mpc_ops->mpo_create_devfs_device = 49419878Swollman mpe->mpe_function; 4959908Swollman break; 4962742Swollman case MAC_CREATE_DEVFS_DIRECTORY: 4972742Swollman mpc->mpc_ops->mpo_create_devfs_directory = 4982742Swollman mpe->mpe_function; 49986222Swollman break; 50019878Swollman case MAC_CREATE_DEVFS_VNODE: 5012742Swollman mpc->mpc_ops->mpo_create_devfs_vnode = 5022742Swollman mpe->mpe_function; 5032742Swollman break; 5042742Swollman case MAC_STDCREATEVNODE_EA: 50558787Sru mpc->mpc_ops->mpo_stdcreatevnode_ea = 50658787Sru mpe->mpe_function; 5072742Swollman break; 50814343Swollman case MAC_CREATE_VNODE: 50914343Swollman mpc->mpc_ops->mpo_create_vnode = 51014343Swollman mpe->mpe_function; 51119878Swollman break; 51214343Swollman case MAC_CREATE_MOUNT: 51314343Swollman mpc->mpc_ops->mpo_create_mount = 51414343Swollman mpe->mpe_function; 51514343Swollman break; 516149514Swollman case MAC_CREATE_ROOT_MOUNT: 517196582Sedwin mpc->mpc_ops->mpo_create_root_mount = 518204887Sedwin mpe->mpe_function; 519204887Sedwin break; 520204887Sedwin case MAC_RELABEL_VNODE: 521197000Sedwin mpc->mpc_ops->mpo_relabel_vnode = 522204887Sedwin mpe->mpe_function; 523204887Sedwin break; 524204887Sedwin case MAC_UPDATE_DEVFSDIRENT: 525204887Sedwin mpc->mpc_ops->mpo_update_devfsdirent = 526204887Sedwin mpe->mpe_function; 527197000Sedwin break; 528197000Sedwin case MAC_UPDATE_PROCFSVNODE: 529197000Sedwin mpc->mpc_ops->mpo_update_procfsvnode = 530198270Sedwin mpe->mpe_function; 531204887Sedwin break; 532204887Sedwin case MAC_UPDATE_VNODE_FROM_EXTATTR: 533204887Sedwin mpc->mpc_ops->mpo_update_vnode_from_extattr = 534204887Sedwin mpe->mpe_function; 535204887Sedwin break; 536198270Sedwin case MAC_UPDATE_VNODE_FROM_EXTERNALIZED: 537226289Sedwin mpc->mpc_ops->mpo_update_vnode_from_externalized = 538214722Sedwin mpe->mpe_function; 539214722Sedwin break; 540214722Sedwin case MAC_UPDATE_VNODE_FROM_MOUNT: 541214722Sedwin mpc->mpc_ops->mpo_update_vnode_from_mount = 542214722Sedwin mpe->mpe_function; 543214722Sedwin break; 544214722Sedwin case MAC_CREATE_MBUF_FROM_SOCKET: 545214722Sedwin mpc->mpc_ops->mpo_create_mbuf_from_socket = 546214722Sedwin mpe->mpe_function; 547226289Sedwin break; 548219687Sedwin case MAC_CREATE_PIPE: 549219687Sedwin mpc->mpc_ops->mpo_create_pipe = 550219687Sedwin mpe->mpe_function; 551219687Sedwin break; 552219687Sedwin case MAC_CREATE_SOCKET: 553219687Sedwin mpc->mpc_ops->mpo_create_socket = 554219687Sedwin mpe->mpe_function; 555219687Sedwin break; 556219687Sedwin case MAC_CREATE_SOCKET_FROM_SOCKET: 557219687Sedwin mpc->mpc_ops->mpo_create_socket_from_socket = 558219687Sedwin mpe->mpe_function; 559219687Sedwin break; 560219687Sedwin case MAC_RELABEL_PIPE: 561219687Sedwin mpc->mpc_ops->mpo_relabel_pipe = 562219687Sedwin mpe->mpe_function; 563219687Sedwin break; 564219687Sedwin case MAC_RELABEL_SOCKET: 565219687Sedwin mpc->mpc_ops->mpo_relabel_socket = 566219687Sedwin mpe->mpe_function; 567226289Sedwin break; 568226289Sedwin case MAC_SET_SOCKET_PEER_FROM_MBUF: 569240457Sedwin mpc->mpc_ops->mpo_set_socket_peer_from_mbuf = 570226289Sedwin mpe->mpe_function; 571226289Sedwin break; 572226289Sedwin case MAC_SET_SOCKET_PEER_FROM_SOCKET: 573226289Sedwin mpc->mpc_ops->mpo_set_socket_peer_from_socket = 574226289Sedwin mpe->mpe_function; 575226289Sedwin break; 576226289Sedwin case MAC_CREATE_BPFDESC: 577226289Sedwin mpc->mpc_ops->mpo_create_bpfdesc = 578226289Sedwin mpe->mpe_function; 579226289Sedwin break; 580226289Sedwin case MAC_CREATE_DATAGRAM_FROM_IPQ: 581226289Sedwin mpc->mpc_ops->mpo_create_datagram_from_ipq = 582226289Sedwin mpe->mpe_function; 583226289Sedwin break; 584226289Sedwin case MAC_CREATE_FRAGMENT: 585226289Sedwin mpc->mpc_ops->mpo_create_fragment = 586226289Sedwin mpe->mpe_function; 587226289Sedwin break; 588226289Sedwin case MAC_CREATE_IFNET: 589226289Sedwin mpc->mpc_ops->mpo_create_ifnet = 590226289Sedwin mpe->mpe_function; 591226289Sedwin break; 592226289Sedwin case MAC_CREATE_IPQ: 593226289Sedwin mpc->mpc_ops->mpo_create_ipq = 594226289Sedwin mpe->mpe_function; 595226289Sedwin break; 596226289Sedwin case MAC_CREATE_MBUF_FROM_MBUF: 597226289Sedwin mpc->mpc_ops->mpo_create_mbuf_from_mbuf = 598226289Sedwin mpe->mpe_function; 599226289Sedwin break; 600226289Sedwin case MAC_CREATE_MBUF_LINKLAYER: 601226289Sedwin mpc->mpc_ops->mpo_create_mbuf_linklayer = 602226289Sedwin mpe->mpe_function; 603226289Sedwin break; 604226289Sedwin case MAC_CREATE_MBUF_FROM_BPFDESC: 605226289Sedwin mpc->mpc_ops->mpo_create_mbuf_from_bpfdesc = 606226289Sedwin mpe->mpe_function; 607226289Sedwin break; 608226289Sedwin case MAC_CREATE_MBUF_FROM_IFNET: 609226289Sedwin mpc->mpc_ops->mpo_create_mbuf_from_ifnet = 610226289Sedwin mpe->mpe_function; 611226289Sedwin break; 612226289Sedwin case MAC_CREATE_MBUF_MULTICAST_ENCAP: 613226289Sedwin mpc->mpc_ops->mpo_create_mbuf_multicast_encap = 614226289Sedwin mpe->mpe_function; 615226289Sedwin break; 616226289Sedwin case MAC_CREATE_MBUF_NETLAYER: 617226289Sedwin mpc->mpc_ops->mpo_create_mbuf_netlayer = 618226289Sedwin mpe->mpe_function; 619226289Sedwin break; 620226289Sedwin case MAC_FRAGMENT_MATCH: 621226289Sedwin mpc->mpc_ops->mpo_fragment_match = 622226289Sedwin mpe->mpe_function; 623226289Sedwin break; 624226289Sedwin case MAC_RELABEL_IFNET: 625226289Sedwin mpc->mpc_ops->mpo_relabel_ifnet = 626233445Sedwin mpe->mpe_function; 627233445Sedwin break; 628233445Sedwin case MAC_UPDATE_IPQ: 629233445Sedwin mpc->mpc_ops->mpo_update_ipq = 630233445Sedwin mpe->mpe_function; 63114343Swollman break; 63214343Swollman case MAC_CREATE_CRED: 63319878Swollman mpc->mpc_ops->mpo_create_cred = 634205475Sedwin mpe->mpe_function; 635219687Sedwin break; 636226289Sedwin case MAC_EXECVE_TRANSITION: 637226289Sedwin mpc->mpc_ops->mpo_execve_transition = 638226289Sedwin mpe->mpe_function; 639226289Sedwin break; 64014343Swollman case MAC_EXECVE_WILL_TRANSITION: 6412742Swollman mpc->mpc_ops->mpo_execve_will_transition = 6422742Swollman mpe->mpe_function; 6432742Swollman break; 6442742Swollman case MAC_CREATE_PROC0: 64519878Swollman mpc->mpc_ops->mpo_create_proc0 = mpe->mpe_function; 6462742Swollman break; 6472742Swollman case MAC_CREATE_PROC1: 648233445Sedwin mpc->mpc_ops->mpo_create_proc1 = mpe->mpe_function; 649233445Sedwin break; 650233445Sedwin case MAC_RELABEL_CRED: 651240457Sedwin mpc->mpc_ops->mpo_relabel_cred = 652233445Sedwin mpe->mpe_function; 653240457Sedwin break; 654240457Sedwin case MAC_CHECK_BPFDESC_RECEIVE: 655240457Sedwin mpc->mpc_ops->mpo_check_bpfdesc_receive = 656240457Sedwin mpe->mpe_function; 657240457Sedwin break; 658233445Sedwin case MAC_CHECK_CRED_RELABEL: 659240457Sedwin mpc->mpc_ops->mpo_check_cred_relabel = 660240457Sedwin mpe->mpe_function; 661240457Sedwin break; 662240457Sedwin case MAC_CHECK_CRED_VISIBLE: 663240457Sedwin mpc->mpc_ops->mpo_check_cred_visible = 664240457Sedwin mpe->mpe_function; 665233445Sedwin break; 6662742Swollman case MAC_CHECK_IFNET_RELABEL: 6672742Swollman mpc->mpc_ops->mpo_check_ifnet_relabel = 668240457Sedwin mpe->mpe_function; 669240457Sedwin break; 6702742Swollman case MAC_CHECK_IFNET_TRANSMIT: 6712742Swollman mpc->mpc_ops->mpo_check_ifnet_transmit = 67258787Sru mpe->mpe_function; 67375267Swollman break; 67475267Swollman case MAC_CHECK_MOUNT_STAT: 675114173Swollman mpc->mpc_ops->mpo_check_mount_stat = 676114173Swollman mpe->mpe_function; 6772742Swollman break; 6782742Swollman case MAC_CHECK_PIPE_IOCTL: 67958787Sru mpc->mpc_ops->mpo_check_pipe_ioctl = 68058787Sru mpe->mpe_function; 68158787Sru break; 6822742Swollman case MAC_CHECK_PIPE_POLL: 6832742Swollman mpc->mpc_ops->mpo_check_pipe_poll = 6842742Swollman mpe->mpe_function; 6852742Swollman break; 68619878Swollman case MAC_CHECK_PIPE_READ: 6872742Swollman mpc->mpc_ops->mpo_check_pipe_read = 68843014Swollman mpe->mpe_function; 68943014Swollman break; 69043014Swollman case MAC_CHECK_PIPE_RELABEL: 69143014Swollman mpc->mpc_ops->mpo_check_pipe_relabel = 692171948Sedwin mpe->mpe_function; 693171948Sedwin break; 694171948Sedwin case MAC_CHECK_PIPE_STAT: 695171948Sedwin mpc->mpc_ops->mpo_check_pipe_stat = 696171948Sedwin mpe->mpe_function; 697171948Sedwin break; 698171948Sedwin case MAC_CHECK_PIPE_WRITE: 699171948Sedwin mpc->mpc_ops->mpo_check_pipe_write = 700171948Sedwin mpe->mpe_function; 70143014Swollman break; 70243014Swollman case MAC_CHECK_PROC_DEBUG: 703171948Sedwin mpc->mpc_ops->mpo_check_proc_debug = 704171948Sedwin mpe->mpe_function; 705171948Sedwin break; 70643014Swollman case MAC_CHECK_PROC_SCHED: 70743014Swollman mpc->mpc_ops->mpo_check_proc_sched = 70843014Swollman mpe->mpe_function; 70943014Swollman break; 71043014Swollman case MAC_CHECK_PROC_SIGNAL: 71143014Swollman mpc->mpc_ops->mpo_check_proc_signal = 71243014Swollman mpe->mpe_function; 71343014Swollman break; 71443014Swollman case MAC_CHECK_SOCKET_BIND: 71543014Swollman mpc->mpc_ops->mpo_check_socket_bind = 716149514Swollman mpe->mpe_function; 717149514Swollman break; 718149514Swollman case MAC_CHECK_SOCKET_CONNECT: 719149514Swollman mpc->mpc_ops->mpo_check_socket_connect = 720149514Swollman mpe->mpe_function; 721149514Swollman break; 722149514Swollman case MAC_CHECK_SOCKET_DELIVER: 723149514Swollman mpc->mpc_ops->mpo_check_socket_deliver = 724149514Swollman mpe->mpe_function; 725149514Swollman break; 726149514Swollman case MAC_CHECK_SOCKET_LISTEN: 72743014Swollman mpc->mpc_ops->mpo_check_socket_listen = 728121098Swollman mpe->mpe_function; 729121098Swollman break; 73043014Swollman case MAC_CHECK_SOCKET_RELABEL: 73143014Swollman mpc->mpc_ops->mpo_check_socket_relabel = 73243014Swollman mpe->mpe_function; 73343014Swollman break; 73443014Swollman case MAC_CHECK_SOCKET_VISIBLE: 73543014Swollman mpc->mpc_ops->mpo_check_socket_visible = 73643014Swollman mpe->mpe_function; 73743014Swollman break; 73843014Swollman case MAC_CHECK_VNODE_ACCESS: 73943014Swollman mpc->mpc_ops->mpo_check_vnode_access = 74043014Swollman mpe->mpe_function; 74143014Swollman break; 74243014Swollman case MAC_CHECK_VNODE_CHDIR: 7432742Swollman mpc->mpc_ops->mpo_check_vnode_chdir = 7442742Swollman mpe->mpe_function; 74519878Swollman break; 74619878Swollman case MAC_CHECK_VNODE_CHROOT: 74719878Swollman mpc->mpc_ops->mpo_check_vnode_chroot = 74820094Swollman mpe->mpe_function; 74920094Swollman break; 75020094Swollman case MAC_CHECK_VNODE_CREATE: 7512742Swollman mpc->mpc_ops->mpo_check_vnode_create = 7522742Swollman mpe->mpe_function; 75319878Swollman break; 7542742Swollman case MAC_CHECK_VNODE_DELETE: 7552742Swollman mpc->mpc_ops->mpo_check_vnode_delete = 7562742Swollman mpe->mpe_function; 7572742Swollman break; 75819878Swollman case MAC_CHECK_VNODE_DELETEACL: 7592742Swollman mpc->mpc_ops->mpo_check_vnode_deleteacl = 7602742Swollman mpe->mpe_function; 7612742Swollman break; 7622742Swollman case MAC_CHECK_VNODE_EXEC: 7632742Swollman mpc->mpc_ops->mpo_check_vnode_exec = 7642742Swollman mpe->mpe_function; 7652742Swollman break; 7662742Swollman case MAC_CHECK_VNODE_GETACL: 7672742Swollman mpc->mpc_ops->mpo_check_vnode_getacl = 768158421Swollman mpe->mpe_function; 7692742Swollman break; 770158421Swollman case MAC_CHECK_VNODE_GETEXTATTR: 771158421Swollman mpc->mpc_ops->mpo_check_vnode_getextattr = 7722742Swollman mpe->mpe_function; 77386222Swollman break; 77420094Swollman case MAC_CHECK_VNODE_LOOKUP: 77520094Swollman mpc->mpc_ops->mpo_check_vnode_lookup = 77620094Swollman mpe->mpe_function; 77720094Swollman break; 77820094Swollman case MAC_CHECK_VNODE_MMAP_PERMS: 779158421Swollman mpc->mpc_ops->mpo_check_vnode_mmap_perms = 780158421Swollman mpe->mpe_function; 78120094Swollman break; 7822742Swollman case MAC_CHECK_VNODE_OPEN: 7832742Swollman mpc->mpc_ops->mpo_check_vnode_open = 7842742Swollman mpe->mpe_function; 7852742Swollman break; 7862742Swollman case MAC_CHECK_VNODE_POLL: 78758787Sru mpc->mpc_ops->mpo_check_vnode_poll = 7882742Swollman mpe->mpe_function; 7892742Swollman break; 7902742Swollman case MAC_CHECK_VNODE_READ: 7912742Swollman mpc->mpc_ops->mpo_check_vnode_read = 7922742Swollman mpe->mpe_function; 7932742Swollman break; 7942742Swollman case MAC_CHECK_VNODE_READDIR: 795169811Swollman mpc->mpc_ops->mpo_check_vnode_readdir = 7962742Swollman mpe->mpe_function; 7972742Swollman break; 7982742Swollman case MAC_CHECK_VNODE_READLINK: 79975267Swollman mpc->mpc_ops->mpo_check_vnode_readlink = 8002742Swollman mpe->mpe_function; 801121098Swollman break; 802121098Swollman case MAC_CHECK_VNODE_RELABEL: 80319878Swollman mpc->mpc_ops->mpo_check_vnode_relabel = 8042742Swollman mpe->mpe_function; 80514343Swollman break; 80658787Sru case MAC_CHECK_VNODE_RENAME_FROM: 8072742Swollman mpc->mpc_ops->mpo_check_vnode_rename_from = 80814343Swollman mpe->mpe_function; 8099908Swollman break; 8102742Swollman case MAC_CHECK_VNODE_RENAME_TO: 8112742Swollman mpc->mpc_ops->mpo_check_vnode_rename_to = 8122742Swollman mpe->mpe_function; 8132742Swollman break; 8142742Swollman case MAC_CHECK_VNODE_REVOKE: 815153670Swollman mpc->mpc_ops->mpo_check_vnode_revoke = 816153670Swollman mpe->mpe_function; 817153670Swollman break; 818153670Swollman case MAC_CHECK_VNODE_SETACL: 81958787Sru mpc->mpc_ops->mpo_check_vnode_setacl = 820153670Swollman mpe->mpe_function; 821153670Swollman break; 822153670Swollman case MAC_CHECK_VNODE_SETEXTATTR: 823153670Swollman mpc->mpc_ops->mpo_check_vnode_setextattr = 824153670Swollman mpe->mpe_function; 82519878Swollman break; 8262742Swollman case MAC_CHECK_VNODE_SETFLAGS: 8272742Swollman mpc->mpc_ops->mpo_check_vnode_setflags = 8282742Swollman mpe->mpe_function; 8292742Swollman break; 8302742Swollman case MAC_CHECK_VNODE_SETMODE: 8312742Swollman mpc->mpc_ops->mpo_check_vnode_setmode = 8322742Swollman mpe->mpe_function; 8332742Swollman break; 8342742Swollman case MAC_CHECK_VNODE_SETOWNER: 8352742Swollman mpc->mpc_ops->mpo_check_vnode_setowner = 8362742Swollman mpe->mpe_function; 8372742Swollman break; 8382742Swollman case MAC_CHECK_VNODE_SETUTIMES: 8392742Swollman mpc->mpc_ops->mpo_check_vnode_setutimes = 8402742Swollman mpe->mpe_function; 8412742Swollman break; 8422742Swollman case MAC_CHECK_VNODE_STAT: 84386222Swollman mpc->mpc_ops->mpo_check_vnode_stat = 8442742Swollman mpe->mpe_function; 8452742Swollman break; 8462742Swollman case MAC_CHECK_VNODE_WRITE: 8472742Swollman mpc->mpc_ops->mpo_check_vnode_write = 8482742Swollman mpe->mpe_function; 849163302Sru break; 850163302Sru/* 851163302Sru default: 852163302Sru printf("MAC policy `%s': unknown operation %d\n", 853163302Sru mpc->mpc_name, mpe->mpe_constant); 854163302Sru return (EINVAL); 85586222Swollman*/ 85686222Swollman } 85786222Swollman } 85886222Swollman MAC_POLICY_LIST_LOCK(); 85986222Swollman if (mac_policy_list_busy > 0) { 86086222Swollman MAC_POLICY_LIST_UNLOCK(); 86186222Swollman FREE(mpc->mpc_ops, M_MACOPVEC); 86286222Swollman mpc->mpc_ops = NULL; 86386222Swollman return (EBUSY); 86486222Swollman } 86586222Swollman LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 86686222Swollman if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 86786222Swollman MAC_POLICY_LIST_UNLOCK(); 86886222Swollman FREE(mpc->mpc_ops, M_MACOPVEC); 86986222Swollman mpc->mpc_ops = NULL; 87086222Swollman return (EEXIST); 87186222Swollman } 87286222Swollman } 87386222Swollman if (mpc->mpc_field_off != NULL) { 87486222Swollman slot = ffs(mac_policy_offsets_free); 87586222Swollman if (slot == 0) { 87686222Swollman MAC_POLICY_LIST_UNLOCK(); 87786222Swollman FREE(mpc->mpc_ops, M_MACOPVEC); 87886222Swollman mpc->mpc_ops = NULL; 87986222Swollman return (ENOMEM); 88086222Swollman } 88186222Swollman slot--; 88286222Swollman mac_policy_offsets_free &= ~(1 << slot); 88386222Swollman *mpc->mpc_field_off = slot; 88486222Swollman } 88586222Swollman mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; 88686222Swollman LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); 88786222Swollman 88886222Swollman /* Per-policy initialization. */ 88986222Swollman if (mpc->mpc_ops->mpo_init != NULL) 89086222Swollman (*(mpc->mpc_ops->mpo_init))(mpc); 89186222Swollman MAC_POLICY_LIST_UNLOCK(); 89286222Swollman 89386222Swollman printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, 89486222Swollman mpc->mpc_name); 89586222Swollman 89686222Swollman return (0); 89786222Swollman} 89886222Swollman 89986222Swollmanstatic int 90086222Swollmanmac_policy_unregister(struct mac_policy_conf *mpc) 90186222Swollman{ 90286222Swollman 90386222Swollman#if 0 90486222Swollman /* 90586222Swollman * Don't allow unloading modules with private data. 90686222Swollman */ 90786222Swollman if (mpc->mpc_field_off != NULL) 90886222Swollman return (EBUSY); 90986222Swollman#endif 91086222Swollman if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) 91186222Swollman return (EBUSY); 91286222Swollman MAC_POLICY_LIST_LOCK(); 91386222Swollman if (mac_policy_list_busy > 0) { 91486222Swollman MAC_POLICY_LIST_UNLOCK(); 91586222Swollman return (EBUSY); 91686222Swollman } 91786222Swollman if (mpc->mpc_ops->mpo_destroy != NULL) 91886222Swollman (*(mpc->mpc_ops->mpo_destroy))(mpc); 91986222Swollman 92086222Swollman LIST_REMOVE(mpc, mpc_list); 92186222Swollman MAC_POLICY_LIST_UNLOCK(); 92286222Swollman 92386222Swollman FREE(mpc->mpc_ops, M_MACOPVEC); 92486222Swollman mpc->mpc_ops = NULL; 92586222Swollman 92686222Swollman printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, 92786222Swollman mpc->mpc_name); 92886222Swollman 92986222Swollman return (0); 93086222Swollman} 93186222Swollman 93286222Swollman/* 93386222Swollman * Define an error value precedence, and given two arguments, selects the 93486222Swollman * value with the higher precedence. 93586222Swollman */ 93614343Swollmanstatic int 937158421Swollmanerror_select(int error1, int error2) 938149514Swollman{ 9399908Swollman 9409908Swollman /* Certain decision-making errors take top priority. */ 9419908Swollman if (error1 == EDEADLK || error2 == EDEADLK) 94214343Swollman return (EDEADLK); 9432742Swollman 944149514Swollman /* Invalid arguments should be reported where possible. */ 94575267Swollman if (error1 == EINVAL || error2 == EINVAL) 94643014Swollman return (EINVAL); 94743014Swollman 94843014Swollman /* Precedence goes to "visibility", with both process and file. */ 94975267Swollman if (error1 == ESRCH || error2 == ESRCH) 95043014Swollman return (ESRCH); 95143014Swollman 95243014Swollman if (error1 == ENOENT || error2 == ENOENT) 95343014Swollman return (ENOENT); 95443014Swollman 95558787Sru /* Precedence goes to DAC/MAC protections. */ 95643014Swollman if (error1 == EACCES || error2 == EACCES) 95743014Swollman return (EACCES); 95843014Swollman 95943014Swollman /* Precedence goes to privilege. */ 96043014Swollman if (error1 == EPERM || error2 == EPERM) 96143014Swollman return (EPERM); 96243014Swollman 963149514Swollman /* Precedence goes to error over success; otherwise, arbitrary. */ 964149514Swollman if (error1 != 0) 965149514Swollman return (error1); 966149514Swollman return (error2); 967149514Swollman} 968149514Swollman 969149514Swollmanvoid 970149514Swollmanmac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp) 971149514Swollman{ 972149514Swollman 973149514Swollman MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label); 974149514Swollman} 975149514Swollman 976149514Swollmanvoid 977149514Swollmanmac_update_procfsvnode(struct vnode *vp, struct ucred *cred) 978149514Swollman{ 979149514Swollman 980149514Swollman MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred); 9819908Swollman} 9829908Swollman 98319878Swollman/* 9842742Swollman * Support callout for policies that manage their own externalization 9852742Swollman * using extended attributes. 9862742Swollman */ 9872742Swollmanstatic int 9889908Swollmanmac_update_vnode_from_extattr(struct vnode *vp, struct mount *mp) 9892742Swollman{ 99019878Swollman int error; 9912742Swollman 9922742Swollman MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp, 9932742Swollman &mp->mnt_fslabel); 9949908Swollman 9952742Swollman return (error); 99619878Swollman} 9972742Swollman 9982742Swollman/* 9992742Swollman * Given an externalized mac label, internalize it and stamp it on a 10002742Swollman * vnode. 10012742Swollman */ 10022742Swollmanstatic int 10032742Swollmanmac_update_vnode_from_externalized(struct vnode *vp, struct mac *extmac) 10042742Swollman{ 10052742Swollman int error; 10062742Swollman 10072742Swollman MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac); 10082742Swollman 10092742Swollman return (error); 10102742Swollman} 101119878Swollman 10122742Swollman/* 10132742Swollman * Call out to individual policies to update the label in a vnode from 10142742Swollman * the mountpoint. 101519878Swollman */ 10162742Swollmanvoid 10172742Swollmanmac_update_vnode_from_mount(struct vnode *vp, struct mount *mp) 10182742Swollman{ 10192742Swollman 10202742Swollman MAC_PERFORM(update_vnode_from_mount, vp, &vp->v_label, mp, 10212742Swollman &mp->mnt_fslabel); 102219878Swollman 10232742Swollman ASSERT_VOP_LOCKED(vp, "mac_update_vnode_from_mount"); 10242742Swollman if (mac_cache_fslabel_in_vnode) 10252742Swollman vp->v_vflag |= VV_CACHEDLABEL; 102658787Sru} 102758787Sru 102858787Sru/* 102958787Sru * Implementation of VOP_REFRESHLABEL() that relies on extended attributes 103058787Sru * to store label data. Can be referenced by filesystems supporting 10319908Swollman * extended attributes. 103219878Swollman */ 10332742Swollmanint 10342742Swollmanvop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap) 10352742Swollman{ 10362742Swollman struct vnode *vp = ap->a_vp; 10372742Swollman struct mac extmac; 10382742Swollman int buflen, error; 10392742Swollman 10402742Swollman ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea"); 10412742Swollman 10422742Swollman /* 104319878Swollman * Call out to external policies first. Order doesn't really 10442742Swollman * matter, as long as failure of one assures failure of all. 10452742Swollman */ 10462742Swollman error = mac_update_vnode_from_extattr(vp, vp->v_mount); 104719878Swollman if (error) 10482742Swollman return (error); 10492742Swollman 10502742Swollman buflen = sizeof(extmac); 10512742Swollman error = vn_extattr_get(vp, IO_NODELOCKED, 105219878Swollman FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, &buflen, 10532742Swollman (char *)&extmac, curthread); 10542742Swollman switch (error) { 10552742Swollman case 0: 10562742Swollman /* Got it */ 105719878Swollman break; 10582742Swollman 10592742Swollman case ENOATTR: 10602742Swollman /* 10612742Swollman * Use the label from the mount point. 10622742Swollman */ 10632742Swollman mac_update_vnode_from_mount(vp, vp->v_mount); 10642742Swollman return (0); 106519878Swollman 10662742Swollman case EOPNOTSUPP: 10672742Swollman default: 1068169811Swollman /* Fail horribly. */ 1069169811Swollman return (error); 1070169811Swollman } 1071169811Swollman 1072169811Swollman if (buflen != sizeof(extmac)) 1073105196Swollman error = EPERM; /* Fail very closed. */ 1074114173Swollman if (error == 0) 1075169811Swollman error = mac_update_vnode_from_externalized(vp, &extmac); 1076114173Swollman if (error == 0) 1077114173Swollman vp->v_vflag |= VV_CACHEDLABEL; 1078114173Swollman else { 1079114173Swollman struct vattr va; 1080169811Swollman 1081105196Swollman printf("Corrupted label on %s", 1082105196Swollman vp->v_mount->mnt_stat.f_mntonname); 1083105196Swollman if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread) == 0) 1084105196Swollman printf(" inum %ld", va.va_fileid); 1085169811Swollman if (mac_debug_label_fallback) { 1086105196Swollman printf(", falling back.\n"); 1087169811Swollman mac_update_vnode_from_mount(vp, vp->v_mount); 1088169811Swollman error = 0; 1089169811Swollman } else { 1090169811Swollman printf(".\n"); 1091105196Swollman error = EPERM; 1092169811Swollman } 1093169811Swollman } 1094169811Swollman 1095169811Swollman return (error); 1096169811Swollman} 1097169811Swollman 1098169811Swollman/* 1099169811Swollman * Make sure the vnode label is up-to-date. If EOPNOTSUPP, then we handle 1100169811Swollman * the labeling activity outselves. Filesystems should be careful not 1101169811Swollman * to change their minds regarding whether they support vop_refreshlabel() 1102169811Swollman * for a vnode or not. Don't cache the vnode here, allow the file 1103169811Swollman * system code to determine if it's safe to cache. If we update from 1104169811Swollman * the mount, don't cache since a change to the mount label should affect 1105169811Swollman * all vnodes. 1106169811Swollman */ 1107169811Swollmanstatic int 1108105196Swollmanvn_refreshlabel(struct vnode *vp, struct ucred *cred) 1109169811Swollman{ 1110169811Swollman int error; 1111169811Swollman 1112169811Swollman ASSERT_VOP_LOCKED(vp, "vn_refreshlabel"); 1113169811Swollman 1114171948Sedwin if (vp->v_mount == NULL) { 11152742Swollman/* 1116171948Sedwin Eventually, we probably want to special-case refreshing 1117171948Sedwin of deadfs vnodes, and if there's a lock-free race somewhere, 1118171948Sedwin that case might be handled here. 1119171948Sedwin 11202742Swollman mac_update_vnode_deadfs(vp); 11212742Swollman return (0); 11229908Swollman */ 11232742Swollman /* printf("vn_refreshlabel: null v_mount\n"); */ 112419878Swollman if (vp->v_type != VNON) 11252742Swollman printf( 11262742Swollman "vn_refreshlabel: null v_mount with non-VNON\n"); 11272742Swollman return (EBADF); 11282742Swollman } 112919878Swollman 11302742Swollman if (vp->v_vflag & VV_CACHEDLABEL) { 11312742Swollman mac_vnode_label_cache_hits++; 11322742Swollman return (0); 11332742Swollman } else 11342742Swollman mac_vnode_label_cache_misses++; 11352742Swollman 11362742Swollman if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) { 1137158421Swollman mac_update_vnode_from_mount(vp, vp->v_mount); 11382742Swollman return (0); 11392742Swollman } 114019878Swollman 11412742Swollman error = VOP_REFRESHLABEL(vp, cred, curthread); 11422742Swollman switch (error) { 11432742Swollman case EOPNOTSUPP: 11442742Swollman /* 114519878Swollman * If labels are not supported on this vnode, fall back to 11462742Swollman * the label in the mount and propagate it to the vnode. 11472742Swollman * There should probably be some sort of policy/flag/decision 11482742Swollman * about doing this. 11492742Swollman */ 11502742Swollman mac_update_vnode_from_mount(vp, vp->v_mount); 115119878Swollman error = 0; 11522742Swollman default: 11532742Swollman return (error); 11542742Swollman } 11552742Swollman} 115619878Swollman 11572742Swollman/* 11582742Swollman * Helper function for file systems using the vop_std*_ea() calls. This 11592742Swollman * function must be called after EA service is available for the vnode, 11602742Swollman * but before it's hooked up to the namespace so that the node persists 1161149514Swollman * if there's a crash, or before it can be accessed. On successful 11629908Swollman * commit of the label to disk (etc), do cache the label. 11639908Swollman */ 11649908Swollmanint 11652742Swollmanvop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp, struct ucred *cred) 1166171948Sedwin{ 1167171948Sedwin struct mac extmac; 1168171948Sedwin int error; 11699908Swollman 11709908Swollman ASSERT_VOP_LOCKED(tvp, "vop_stdcreatevnode_ea"); 117158787Sru if ((dvp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) { 117258787Sru mac_update_vnode_from_mount(tvp, tvp->v_mount); 11732742Swollman } else { 11742742Swollman error = vn_refreshlabel(dvp, cred); 11752742Swollman if (error) 117619878Swollman return (error); 11772742Swollman 11782742Swollman /* 11792742Swollman * Stick the label in the vnode. Then try to write to 11802742Swollman * disk. If we fail, return a failure to abort the 118158787Sru * create operation. Really, this failure shouldn't 118258787Sru * happen except in fairly unusual circumstances (out 118358787Sru * of disk, etc). 118458787Sru */ 118558787Sru mac_create_vnode(cred, dvp, tvp); 118658787Sru 118758787Sru error = mac_stdcreatevnode_ea(tvp); 118864499Swollman if (error) 118964499Swollman return (error); 119064499Swollman 1191171948Sedwin /* 1192171948Sedwin * XXX: Eventually this will go away and all policies will 1193171948Sedwin * directly manage their extended attributes. 11949908Swollman */ 11952742Swollman error = mac_externalize(&tvp->v_label, &extmac); 119658787Sru if (error) 119758787Sru return (error); 11982742Swollman 11992742Swollman error = vn_extattr_set(tvp, IO_NODELOCKED, 12002742Swollman FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, 120186222Swollman sizeof(extmac), (char *)&extmac, curthread); 120286222Swollman if (error == 0) 120386222Swollman tvp->v_vflag |= VV_CACHEDLABEL; 120486222Swollman else { 120586222Swollman#if 0 120686222Swollman /* 120786222Swollman * In theory, we could have fall-back behavior here. 120886222Swollman * It would probably be incorrect. 120986222Swollman */ 121086222Swollman#endif 121186222Swollman return (error); 121286222Swollman } 121386222Swollman } 121486222Swollman 121586222Swollman return (0); 121686222Swollman} 121786222Swollman 121886222Swollmanvoid 121986222Swollmanmac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp) 122086222Swollman{ 122186222Swollman int error; 122286222Swollman 1223171948Sedwin ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1224171948Sedwin 1225171948Sedwin error = vn_refreshlabel(vp, old); 12269908Swollman if (error) { 12272742Swollman printf("mac_execve_transition: vn_refreshlabel returned %d\n", 12282742Swollman error); 12292742Swollman printf("mac_execve_transition: using old vnode label\n"); 1230149514Swollman } 12312742Swollman 12322742Swollman MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label); 12332742Swollman} 12342742Swollman 12352742Swollmanint 12362742Swollmanmac_execve_will_transition(struct ucred *old, struct vnode *vp) 12372742Swollman{ 12382742Swollman int error, result; 1239149514Swollman 124058787Sru error = vn_refreshlabel(vp, old); 124158787Sru if (error) 124258787Sru return (error); 124358787Sru 124458787Sru result = 0; 124558787Sru MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label); 12462742Swollman 124758787Sru return (result); 124858787Sru} 124958787Sru 125058787Srustatic void 125158787Srumac_init_label(struct label *label) 125258787Sru{ 125358787Sru 125458787Sru bzero(label, sizeof(*label)); 125558787Sru label->l_flags = MAC_FLAG_INITIALIZED; 125658787Sru} 125758787Sru 125858787Srustatic void 125958787Srumac_init_structmac(struct mac *mac) 126058787Sru{ 126158787Sru 126258787Sru bzero(mac, sizeof(*mac)); 126358787Sru mac->m_macflags = MAC_FLAG_INITIALIZED; 126458787Sru} 126558787Sru 126658787Srustatic void 126758787Srumac_destroy_label(struct label *label) 126858787Sru{ 126958787Sru 127058787Sru KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 127158787Sru ("destroying uninitialized label")); 127258787Sru 127358787Sru bzero(label, sizeof(*label)); 127458787Sru /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 127558787Sru} 127675267Swollman 127758787Sruint 127858787Srumac_init_mbuf(struct mbuf *m, int how) 127958787Sru{ 128058787Sru KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf")); 128158787Sru 128258787Sru /* "how" is one of M_(TRY|DONT)WAIT */ 12832742Swollman mac_init_label(&m->m_pkthdr.label); 128443543Swollman MAC_PERFORM(init_mbuf, m, how, &m->m_pkthdr.label); 128543543Swollman#ifdef MAC_DEBUG 128658787Sru atomic_add_int(&nmacmbufs, 1); 128743543Swollman#endif 128867578Swollman return (0); 128975267Swollman} 129075267Swollman 129167578Swollmanvoid 1292171948Sedwinmac_destroy_mbuf(struct mbuf *m) 1293171948Sedwin{ 1294171948Sedwin 12959908Swollman MAC_PERFORM(destroy_mbuf, m, &m->m_pkthdr.label); 12962742Swollman mac_destroy_label(&m->m_pkthdr.label); 129767578Swollman#ifdef MAC_DEBUG 12982742Swollman atomic_subtract_int(&nmacmbufs, 1); 12992742Swollman#endif 130019878Swollman} 13012742Swollman 13022742Swollmanvoid 13032742Swollmanmac_init_cred(struct ucred *cr) 130443014Swollman{ 13052742Swollman 13062742Swollman mac_init_label(&cr->cr_label); 13072742Swollman MAC_PERFORM(init_cred, cr, &cr->cr_label); 13082742Swollman#ifdef MAC_DEBUG 13092742Swollman atomic_add_int(&nmaccreds, 1); 13102742Swollman#endif 13112742Swollman} 13122742Swollman 13132742Swollmanvoid 13142742Swollmanmac_destroy_cred(struct ucred *cr) 13152742Swollman{ 13169908Swollman 13172742Swollman MAC_PERFORM(destroy_cred, cr, &cr->cr_label); 131819878Swollman mac_destroy_label(&cr->cr_label); 1319153670Swollman#ifdef MAC_DEBUG 13202742Swollman atomic_subtract_int(&nmaccreds, 1); 13212742Swollman#endif 13222742Swollman} 13232742Swollman 132458787Sruvoid 132558787Srumac_init_ifnet(struct ifnet *ifp) 132658787Sru{ 132758787Sru 132858787Sru mac_init_label(&ifp->if_label); 132958787Sru MAC_PERFORM(init_ifnet, ifp, &ifp->if_label); 1330226289Sedwin#ifdef MAC_DEBUG 133158787Sru atomic_add_int(&nmacifnets, 1); 133258787Sru#endif 133358787Sru} 133414343Swollman 133575267Swollmanvoid 133675267Swollmanmac_destroy_ifnet(struct ifnet *ifp) 133775267Swollman{ 133875267Swollman 133975267Swollman MAC_PERFORM(destroy_ifnet, ifp, &ifp->if_label); 134075267Swollman mac_destroy_label(&ifp->if_label); 134158787Sru#ifdef MAC_DEBUG 1342158421Swollman atomic_subtract_int(&nmacifnets, 1); 1343158421Swollman#endif 1344158421Swollman} 134567578Swollman 1346171948Sedwinvoid 1347171948Sedwinmac_init_ipq(struct ipq *ipq) 1348171948Sedwin{ 1349192886Sedwin 1350240457Sedwin mac_init_label(&ipq->ipq_label); 1351240457Sedwin MAC_PERFORM(init_ipq, ipq, &ipq->ipq_label); 1352192886Sedwin#ifdef MAC_DEBUG 1353240457Sedwin atomic_add_int(&nmacipqs, 1); 1354192886Sedwin#endif 1355192886Sedwin} 1356192886Sedwin 1357192886Sedwinvoid 1358240457Sedwinmac_destroy_ipq(struct ipq *ipq) 1359192886Sedwin{ 1360240457Sedwin 1361192886Sedwin MAC_PERFORM(destroy_ipq, ipq, &ipq->ipq_label); 1362240457Sedwin mac_destroy_label(&ipq->ipq_label); 1363240457Sedwin#ifdef MAC_DEBUG 1364192886Sedwin atomic_subtract_int(&nmacipqs, 1); 1365240457Sedwin#endif 1366192886Sedwin} 1367192886Sedwin 1368192886Sedwinvoid 1369192886Sedwinmac_init_socket(struct socket *socket) 13702742Swollman{ 13712742Swollman 137258787Sru mac_init_label(&socket->so_label); 13732742Swollman mac_init_label(&socket->so_peerlabel); 137419878Swollman MAC_PERFORM(init_socket, socket, &socket->so_label, 13752742Swollman &socket->so_peerlabel); 13762742Swollman#ifdef MAC_DEBUG 13772742Swollman atomic_add_int(&nmacsockets, 1); 13782742Swollman#endif 13792742Swollman} 138019878Swollman 13812742Swollmanvoid 13822742Swollmanmac_destroy_socket(struct socket *socket) 1383153670Swollman{ 13842742Swollman 13852742Swollman MAC_PERFORM(destroy_socket, socket, &socket->so_label, 13862742Swollman &socket->so_peerlabel); 13872742Swollman mac_destroy_label(&socket->so_label); 13882742Swollman mac_destroy_label(&socket->so_peerlabel); 13892742Swollman#ifdef MAC_DEBUG 13902742Swollman atomic_subtract_int(&nmacsockets, 1); 13912742Swollman#endif 13922742Swollman} 13932742Swollman 139419878Swollmanvoid 13952742Swollmanmac_init_pipe(struct pipe *pipe) 13962742Swollman{ 13972742Swollman struct label *label; 139814343Swollman 1399158421Swollman label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 1400149514Swollman mac_init_label(label); 140114343Swollman pipe->pipe_label = label; 140214343Swollman pipe->pipe_peer->pipe_label = label; 140314343Swollman MAC_PERFORM(init_pipe, pipe, pipe->pipe_label); 140414343Swollman#ifdef MAC_DEBUG 1405158421Swollman atomic_add_int(&nmacpipes, 1); 1406121098Swollman#endif 1407121098Swollman} 1408158421Swollman 1409121098Swollmanvoid 1410121098Swollmanmac_destroy_pipe(struct pipe *pipe) 1411121098Swollman{ 1412121098Swollman 141314343Swollman MAC_PERFORM(destroy_pipe, pipe, pipe->pipe_label); 1414169811Swollman mac_destroy_label(pipe->pipe_label); 1415169811Swollman free(pipe->pipe_label, M_MACPIPELABEL); 1416169811Swollman#ifdef MAC_DEBUG 1417169811Swollman atomic_subtract_int(&nmacpipes, 1); 1418169811Swollman#endif 1419169811Swollman} 14202742Swollman 14212742Swollmanvoid 142258787Srumac_init_bpfdesc(struct bpf_d *bpf_d) 14232742Swollman{ 14242742Swollman 142558787Sru mac_init_label(&bpf_d->bd_label); 142658787Sru MAC_PERFORM(init_bpfdesc, bpf_d, &bpf_d->bd_label); 142758787Sru#ifdef MAC_DEBUG 14282742Swollman atomic_add_int(&nmacbpfdescs, 1); 142943543Swollman#endif 143043543Swollman} 143175267Swollman 143243543Swollmanvoid 143343543Swollmanmac_destroy_bpfdesc(struct bpf_d *bpf_d) 143458787Sru{ 143558787Sru 143658787Sru MAC_PERFORM(destroy_bpfdesc, bpf_d, &bpf_d->bd_label); 143743543Swollman mac_destroy_label(&bpf_d->bd_label); 143843543Swollman#ifdef MAC_DEBUG 143943543Swollman atomic_subtract_int(&nmacbpfdescs, 1); 144043543Swollman#endif 144143543Swollman} 144243543Swollman 144343543Swollmanvoid 144475267Swollmanmac_init_mount(struct mount *mp) 144575267Swollman{ 144658787Sru 144714343Swollman mac_init_label(&mp->mnt_mntlabel); 144814343Swollman mac_init_label(&mp->mnt_fslabel); 144914343Swollman MAC_PERFORM(init_mount, mp, &mp->mnt_mntlabel, &mp->mnt_fslabel); 145014343Swollman#ifdef MAC_DEBUG 145158787Sru atomic_add_int(&nmacmounts, 1); 145217200Swollman#endif 145317200Swollman} 145417200Swollman 145517200Swollmanvoid 1456226289Sedwinmac_destroy_mount(struct mount *mp) 145717200Swollman{ 145817200Swollman 145958787Sru MAC_PERFORM(destroy_mount, mp, &mp->mnt_mntlabel, &mp->mnt_fslabel); 14602742Swollman mac_destroy_label(&mp->mnt_fslabel); 14612742Swollman mac_destroy_label(&mp->mnt_mntlabel); 14622742Swollman#ifdef MAC_DEBUG 14632742Swollman atomic_subtract_int(&nmacmounts, 1); 146419878Swollman#endif 14652742Swollman} 14662742Swollman 14672742Swollmanstatic void 146858787Srumac_init_temp(struct label *label) 146914343Swollman{ 14702742Swollman 147158787Sru mac_init_label(label); 14722742Swollman MAC_PERFORM(init_temp, label); 14732742Swollman#ifdef MAC_DEBUG 147475267Swollman atomic_add_int(&nmactemp, 1); 147575267Swollman#endif 147614343Swollman} 147775267Swollman 147875267Swollmanstatic void 147975267Swollmanmac_destroy_temp(struct label *label) 148075267Swollman{ 148158787Sru 148275267Swollman MAC_PERFORM(destroy_temp, label); 148317200Swollman mac_destroy_label(label); 148417200Swollman#ifdef MAC_DEBUG 1485149514Swollman atomic_subtract_int(&nmactemp, 1); 148617200Swollman#endif 148717200Swollman} 148817200Swollman 1489158421Swollmanvoid 1490158421Swollmanmac_init_vnode(struct vnode *vp) 149117200Swollman{ 149258787Sru 149358787Sru mac_init_label(&vp->v_label); 149458787Sru MAC_PERFORM(init_vnode, vp, &vp->v_label); 149558787Sru#ifdef MAC_DEBUG 149658787Sru atomic_add_int(&nmacvnodes, 1); 149758787Sru#endif 149858787Sru} 149958787Sru 150058787Sruvoid 1501121098Swollmanmac_destroy_vnode(struct vnode *vp) 1502121098Swollman{ 1503121098Swollman 1504121098Swollman MAC_PERFORM(destroy_vnode, vp, &vp->v_label); 1505121098Swollman mac_destroy_label(&vp->v_label); 1506121098Swollman#ifdef MAC_DEBUG 1507121098Swollman atomic_subtract_int(&nmacvnodes, 1); 1508121098Swollman#endif 1509121098Swollman} 1510121098Swollman 1511121098Swollmanvoid 1512121098Swollmanmac_init_devfsdirent(struct devfs_dirent *de) 1513121098Swollman{ 1514121098Swollman 1515121098Swollman mac_init_label(&de->de_label); 1516121098Swollman MAC_PERFORM(init_devfsdirent, de, &de->de_label); 1517121098Swollman#ifdef MAC_DEBUG 151858787Sru atomic_add_int(&nmacdevfsdirents, 1); 151958787Sru#endif 152058787Sru} 152158787Sru 152258787Sruvoid 152358787Srumac_destroy_devfsdirent(struct devfs_dirent *de) 152458787Sru{ 152558787Sru 152658787Sru MAC_PERFORM(destroy_devfsdirent, de, &de->de_label); 152758787Sru mac_destroy_label(&de->de_label); 152858787Sru#ifdef MAC_DEBUG 152958787Sru atomic_subtract_int(&nmacdevfsdirents, 1); 153058787Sru#endif 153158787Sru} 153258787Sru 153358787Srustatic int 153458787Srumac_externalize(struct label *label, struct mac *mac) 153558787Sru{ 153658787Sru int error; 153758787Sru 153858787Sru mac_init_structmac(mac); 153958787Sru MAC_CHECK(externalize, label, mac); 154058787Sru 154158787Sru return (error); 154214343Swollman} 154314343Swollman 154458787Srustatic int 154558787Srumac_internalize(struct label *label, struct mac *mac) 154614343Swollman{ 154714343Swollman int error; 154814343Swollman 154917200Swollman mac_init_temp(label); 155058787Sru MAC_CHECK(internalize, label, mac); 155117200Swollman if (error) 155217200Swollman mac_destroy_temp(label); 155317200Swollman 155417200Swollman return (error); 155517200Swollman} 155617200Swollman 155758787Sru/* 155858787Sru * Initialize MAC label for the first kernel process, from which other 155958787Sru * kernel processes and threads are spawned. 156058787Sru */ 156158787Sruvoid 156258787Srumac_create_proc0(struct ucred *cred) 156358787Sru{ 156458787Sru 156558787Sru MAC_PERFORM(create_proc0, cred); 156658787Sru} 156758787Sru 156858787Sru/* 156958787Sru * Initialize MAC label for the first userland process, from which other 157058787Sru * userland processes and threads are spawned. 157158787Sru */ 157258787Sruvoid 157358787Srumac_create_proc1(struct ucred *cred) 157458787Sru{ 157558787Sru 157658787Sru MAC_PERFORM(create_proc1, cred); 157758787Sru} 157858787Sru 157958787Sru/* 158058787Sru * When a new process is created, its label must be initialized. Generally, 158158787Sru * this involves inheritence from the parent process, modulo possible 158258787Sru * deltas. This function allows that processing to take place. 1583158421Swollman */ 1584158421Swollmanvoid 158558787Srumac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 158658787Sru{ 158758787Sru 158858787Sru MAC_PERFORM(create_cred, parent_cred, child_cred); 158958787Sru} 159058787Sru 159158787Sruint 159258787Srumac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags) 1593149514Swollman{ 159458787Sru int error; 159575267Swollman 1596149514Swollman ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1597181421Sedwin 159858787Sru if (!mac_enforce_fs) 159958787Sru return (0); 160075267Swollman 160158787Sru error = vn_refreshlabel(vp, cred); 160258787Sru if (error) 160358787Sru return (error); 160458787Sru 160558787Sru MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags); 1606149514Swollman return (error); 1607181421Sedwin} 160858787Sru 160958787Sruint 161075267Swollmanmac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 161175267Swollman{ 161275267Swollman int error; 161375267Swollman 161458787Sru ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 161558787Sru 161658787Sru if (!mac_enforce_fs) 161758787Sru return (0); 161858787Sru 161958787Sru error = vn_refreshlabel(dvp, cred); 162058787Sru if (error) 162175267Swollman return (error); 162275267Swollman 162375267Swollman MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 162475267Swollman return (error); 162575267Swollman} 162675267Swollman 162775267Swollmanint 162858787Srumac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 162975267Swollman{ 163075267Swollman int error; 163175267Swollman 163293799Swollman ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 163393799Swollman 163493799Swollman if (!mac_enforce_fs) 163593799Swollman return (0); 163693799Swollman 163786222Swollman error = vn_refreshlabel(dvp, cred); 1638114173Swollman if (error) 1639114173Swollman return (error); 164086222Swollman 1641121098Swollman MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1642121098Swollman return (error); 1643121098Swollman} 1644121098Swollman 1645121098Swollmanint 1646121098Swollmanmac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1647121098Swollman struct componentname *cnp, struct vattr *vap) 1648121098Swollman{ 1649121098Swollman int error; 1650121098Swollman 1651121098Swollman ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1652121098Swollman 1653121098Swollman if (!mac_enforce_fs) 1654121098Swollman return (0); 1655121098Swollman 1656121098Swollman error = vn_refreshlabel(dvp, cred); 1657121098Swollman if (error) 1658121098Swollman return (error); 165958787Sru 166058787Sru MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 166158787Sru return (error); 166258787Sru} 166358787Sru 166475267Swollmanint 166558787Srumac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 166658787Sru struct componentname *cnp) 166758787Sru{ 166858787Sru int error; 166958787Sru 167058787Sru ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 167158787Sru ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 167258787Sru 167358787Sru if (!mac_enforce_fs) 167458787Sru return (0); 167558787Sru 1676153670Swollman error = vn_refreshlabel(dvp, cred); 167758787Sru if (error) 167858787Sru return (error); 167958787Sru error = vn_refreshlabel(vp, cred); 168058787Sru if (error) 1681149514Swollman return (error); 1682153670Swollman 1683153670Swollman MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1684153670Swollman &vp->v_label, cnp); 1685153670Swollman return (error); 1686153670Swollman} 1687153670Swollman 1688153670Swollmanint 1689153670Swollmanmac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1690153670Swollman acl_type_t type) 1691153670Swollman{ 1692153670Swollman int error; 1693153670Swollman 1694153670Swollman ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1695153670Swollman 1696149514Swollman if (!mac_enforce_fs) 1697149514Swollman return (0); 1698149514Swollman 1699149514Swollman error = vn_refreshlabel(vp, cred); 1700149514Swollman if (error) 1701149514Swollman return (error); 1702149514Swollman 1703 MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1704 return (error); 1705} 1706 1707int 1708mac_check_vnode_exec(struct ucred *cred, struct vnode *vp) 1709{ 1710 int error; 1711 1712 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1713 1714 if (!mac_enforce_process && !mac_enforce_fs) 1715 return (0); 1716 1717 error = vn_refreshlabel(vp, cred); 1718 if (error) 1719 return (error); 1720 MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label); 1721 1722 return (error); 1723} 1724 1725int 1726mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1727{ 1728 int error; 1729 1730 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1731 1732 if (!mac_enforce_fs) 1733 return (0); 1734 1735 error = vn_refreshlabel(vp, cred); 1736 if (error) 1737 return (error); 1738 1739 MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1740 return (error); 1741} 1742 1743int 1744mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1745 int attrnamespace, const char *name, struct uio *uio) 1746{ 1747 int error; 1748 1749 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1750 1751 if (!mac_enforce_fs) 1752 return (0); 1753 1754 error = vn_refreshlabel(vp, cred); 1755 if (error) 1756 return (error); 1757 1758 MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1759 attrnamespace, name, uio); 1760 return (error); 1761} 1762 1763int 1764mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1765 struct componentname *cnp) 1766{ 1767 int error; 1768 1769 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 1770 1771 if (!mac_enforce_fs) 1772 return (0); 1773 1774 error = vn_refreshlabel(dvp, cred); 1775 if (error) 1776 return (error); 1777 1778 MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 1779 return (error); 1780} 1781 1782vm_prot_t 1783mac_check_vnode_mmap_prot(struct ucred *cred, struct vnode *vp, int newmapping) 1784{ 1785 vm_prot_t result = VM_PROT_ALL; 1786 1787 if (!mac_enforce_vm) 1788 return (result); 1789 1790 /* 1791 * This should be some sort of MAC_BITWISE, maybe :) 1792 */ 1793 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_perms"); 1794 MAC_BOOLEAN(check_vnode_mmap_perms, &, cred, vp, &vp->v_label, 1795 newmapping); 1796 return (result); 1797} 1798 1799int 1800mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode) 1801{ 1802 int error; 1803 1804 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 1805 1806 if (!mac_enforce_fs) 1807 return (0); 1808 1809 error = vn_refreshlabel(vp, cred); 1810 if (error) 1811 return (error); 1812 1813 MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 1814 return (error); 1815} 1816 1817int 1818mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1819 struct vnode *vp) 1820{ 1821 int error; 1822 1823 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 1824 1825 if (!mac_enforce_fs) 1826 return (0); 1827 1828 error = vn_refreshlabel(vp, active_cred); 1829 if (error) 1830 return (error); 1831 1832 MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 1833 &vp->v_label); 1834 1835 return (error); 1836} 1837 1838int 1839mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1840 struct vnode *vp) 1841{ 1842 int error; 1843 1844 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 1845 1846 if (!mac_enforce_fs) 1847 return (0); 1848 1849 error = vn_refreshlabel(vp, active_cred); 1850 if (error) 1851 return (error); 1852 1853 MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 1854 &vp->v_label); 1855 1856 return (error); 1857} 1858 1859int 1860mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 1861{ 1862 int error; 1863 1864 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 1865 1866 if (!mac_enforce_fs) 1867 return (0); 1868 1869 error = vn_refreshlabel(dvp, cred); 1870 if (error) 1871 return (error); 1872 1873 MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 1874 return (error); 1875} 1876 1877int 1878mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 1879{ 1880 int error; 1881 1882 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 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_readlink, cred, vp, &vp->v_label); 1892 return (error); 1893} 1894 1895static int 1896mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1897 struct label *newlabel) 1898{ 1899 int error; 1900 1901 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 1902 1903 error = vn_refreshlabel(vp, cred); 1904 if (error) 1905 return (error); 1906 1907 MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 1908 1909 return (error); 1910} 1911 1912int 1913mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1914 struct vnode *vp, struct componentname *cnp) 1915{ 1916 int error; 1917 1918 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 1919 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 1920 1921 if (!mac_enforce_fs) 1922 return (0); 1923 1924 error = vn_refreshlabel(dvp, cred); 1925 if (error) 1926 return (error); 1927 error = vn_refreshlabel(vp, cred); 1928 if (error) 1929 return (error); 1930 1931 MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 1932 &vp->v_label, cnp); 1933 return (error); 1934} 1935 1936int 1937mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1938 struct vnode *vp, int samedir, struct componentname *cnp) 1939{ 1940 int error; 1941 1942 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 1943 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 1944 1945 if (!mac_enforce_fs) 1946 return (0); 1947 1948 error = vn_refreshlabel(dvp, cred); 1949 if (error) 1950 return (error); 1951 if (vp != NULL) { 1952 error = vn_refreshlabel(vp, cred); 1953 if (error) 1954 return (error); 1955 } 1956 MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 1957 vp != NULL ? &vp->v_label : NULL, samedir, cnp); 1958 return (error); 1959} 1960 1961int 1962mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 1963{ 1964 int error; 1965 1966 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 1967 1968 if (!mac_enforce_fs) 1969 return (0); 1970 1971 error = vn_refreshlabel(vp, cred); 1972 if (error) 1973 return (error); 1974 1975 MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 1976 return (error); 1977} 1978 1979int 1980mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 1981 struct acl *acl) 1982{ 1983 int error; 1984 1985 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 1986 1987 if (!mac_enforce_fs) 1988 return (0); 1989 1990 error = vn_refreshlabel(vp, cred); 1991 if (error) 1992 return (error); 1993 1994 MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 1995 return (error); 1996} 1997 1998int 1999mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2000 int attrnamespace, const char *name, struct uio *uio) 2001{ 2002 int error; 2003 2004 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 2005 2006 if (!mac_enforce_fs) 2007 return (0); 2008 2009 error = vn_refreshlabel(vp, cred); 2010 if (error) 2011 return (error); 2012 2013 MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 2014 attrnamespace, name, uio); 2015 return (error); 2016} 2017 2018int 2019mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 2020{ 2021 int error; 2022 2023 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 2024 2025 if (!mac_enforce_fs) 2026 return (0); 2027 2028 error = vn_refreshlabel(vp, cred); 2029 if (error) 2030 return (error); 2031 2032 MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 2033 return (error); 2034} 2035 2036int 2037mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 2038{ 2039 int error; 2040 2041 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 2042 2043 if (!mac_enforce_fs) 2044 return (0); 2045 2046 error = vn_refreshlabel(vp, cred); 2047 if (error) 2048 return (error); 2049 2050 MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 2051 return (error); 2052} 2053 2054int 2055mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 2056 gid_t gid) 2057{ 2058 int error; 2059 2060 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 2061 2062 if (!mac_enforce_fs) 2063 return (0); 2064 2065 error = vn_refreshlabel(vp, cred); 2066 if (error) 2067 return (error); 2068 2069 MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 2070 return (error); 2071} 2072 2073int 2074mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2075 struct timespec atime, struct timespec mtime) 2076{ 2077 int error; 2078 2079 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 2080 2081 if (!mac_enforce_fs) 2082 return (0); 2083 2084 error = vn_refreshlabel(vp, cred); 2085 if (error) 2086 return (error); 2087 2088 MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 2089 mtime); 2090 return (error); 2091} 2092 2093int 2094mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2095 struct vnode *vp) 2096{ 2097 int error; 2098 2099 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 2100 2101 if (!mac_enforce_fs) 2102 return (0); 2103 2104 error = vn_refreshlabel(vp, active_cred); 2105 if (error) 2106 return (error); 2107 2108 MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 2109 &vp->v_label); 2110 return (error); 2111} 2112 2113int 2114mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 2115 struct vnode *vp) 2116{ 2117 int error; 2118 2119 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 2120 2121 if (!mac_enforce_fs) 2122 return (0); 2123 2124 error = vn_refreshlabel(vp, active_cred); 2125 if (error) 2126 return (error); 2127 2128 MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 2129 &vp->v_label); 2130 2131 return (error); 2132} 2133 2134/* 2135 * When relabeling a process, call out to the policies for the maximum 2136 * permission allowed for each object type we know about in its 2137 * memory space, and revoke access (in the least surprising ways we 2138 * know) when necessary. The process lock is not held here. 2139 */ 2140static void 2141mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 2142{ 2143 2144 /* XXX freeze all other threads */ 2145 mac_cred_mmapped_drop_perms_recurse(td, cred, 2146 &td->td_proc->p_vmspace->vm_map); 2147 /* XXX allow other threads to continue */ 2148} 2149 2150static __inline const char * 2151prot2str(vm_prot_t prot) 2152{ 2153 2154 switch (prot & VM_PROT_ALL) { 2155 case VM_PROT_READ: 2156 return ("r--"); 2157 case VM_PROT_READ | VM_PROT_WRITE: 2158 return ("rw-"); 2159 case VM_PROT_READ | VM_PROT_EXECUTE: 2160 return ("r-x"); 2161 case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 2162 return ("rwx"); 2163 case VM_PROT_WRITE: 2164 return ("-w-"); 2165 case VM_PROT_EXECUTE: 2166 return ("--x"); 2167 case VM_PROT_WRITE | VM_PROT_EXECUTE: 2168 return ("-wx"); 2169 default: 2170 return ("---"); 2171 } 2172} 2173 2174static void 2175mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 2176 struct vm_map *map) 2177{ 2178 struct vm_map_entry *vme; 2179 vm_prot_t result, revokeperms; 2180 vm_object_t object; 2181 vm_ooffset_t offset; 2182 struct vnode *vp; 2183 2184 if (!mac_mmap_revocation) 2185 return; 2186 2187 vm_map_lock_read(map); 2188 for (vme = map->header.next; vme != &map->header; vme = vme->next) { 2189 if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 2190 mac_cred_mmapped_drop_perms_recurse(td, cred, 2191 vme->object.sub_map); 2192 continue; 2193 } 2194 /* 2195 * Skip over entries that obviously are not shared. 2196 */ 2197 if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 2198 !vme->max_protection) 2199 continue; 2200 /* 2201 * Drill down to the deepest backing object. 2202 */ 2203 offset = vme->offset; 2204 object = vme->object.vm_object; 2205 if (object == NULL) 2206 continue; 2207 while (object->backing_object != NULL) { 2208 object = object->backing_object; 2209 offset += object->backing_object_offset; 2210 } 2211 /* 2212 * At the moment, vm_maps and objects aren't considered 2213 * by the MAC system, so only things with backing by a 2214 * normal object (read: vnodes) are checked. 2215 */ 2216 if (object->type != OBJT_VNODE) 2217 continue; 2218 vp = (struct vnode *)object->handle; 2219 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2220 result = mac_check_vnode_mmap_prot(cred, vp, 0); 2221 VOP_UNLOCK(vp, 0, td); 2222 /* 2223 * Find out what maximum protection we may be allowing 2224 * now but a policy needs to get removed. 2225 */ 2226 revokeperms = vme->max_protection & ~result; 2227 if (!revokeperms) 2228 continue; 2229 printf("pid %ld: revoking %s perms from %#lx:%ld " 2230 "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 2231 prot2str(revokeperms), (u_long)vme->start, 2232 (long)(vme->end - vme->start), 2233 prot2str(vme->max_protection), prot2str(vme->protection)); 2234 vm_map_lock_upgrade(map); 2235 /* 2236 * This is the really simple case: if a map has more 2237 * max_protection than is allowed, but it's not being 2238 * actually used (that is, the current protection is 2239 * still allowed), we can just wipe it out and do 2240 * nothing more. 2241 */ 2242 if ((vme->protection & revokeperms) == 0) { 2243 vme->max_protection -= revokeperms; 2244 } else { 2245 if (revokeperms & VM_PROT_WRITE) { 2246 /* 2247 * In the more complicated case, flush out all 2248 * pending changes to the object then turn it 2249 * copy-on-write. 2250 */ 2251 vm_object_reference(object); 2252 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2253 vm_object_page_clean(object, 2254 OFF_TO_IDX(offset), 2255 OFF_TO_IDX(offset + vme->end - vme->start + 2256 PAGE_MASK), 2257 OBJPC_SYNC); 2258 VOP_UNLOCK(vp, 0, td); 2259 vm_object_deallocate(object); 2260 /* 2261 * Why bother if there's no read permissions 2262 * anymore? For the rest, we need to leave 2263 * the write permissions on for COW, or 2264 * remove them entirely if configured to. 2265 */ 2266 if (!mac_mmap_revocation_via_cow) { 2267 vme->max_protection &= ~VM_PROT_WRITE; 2268 vme->protection &= ~VM_PROT_WRITE; 2269 } if ((revokeperms & VM_PROT_READ) == 0) 2270 vme->eflags |= MAP_ENTRY_COW | 2271 MAP_ENTRY_NEEDS_COPY; 2272 } 2273 if (revokeperms & VM_PROT_EXECUTE) { 2274 vme->max_protection &= ~VM_PROT_EXECUTE; 2275 vme->protection &= ~VM_PROT_EXECUTE; 2276 } 2277 if (revokeperms & VM_PROT_READ) { 2278 vme->max_protection = 0; 2279 vme->protection = 0; 2280 } 2281 pmap_protect(map->pmap, vme->start, vme->end, 2282 vme->protection & ~revokeperms); 2283 vm_map_simplify_entry(map, vme); 2284 } 2285 vm_map_lock_downgrade(map); 2286 } 2287 vm_map_unlock_read(map); 2288} 2289 2290/* 2291 * When the subject's label changes, it may require revocation of privilege 2292 * to mapped objects. This can't be done on-the-fly later with a unified 2293 * buffer cache. 2294 */ 2295static void 2296mac_relabel_cred(struct ucred *cred, struct label *newlabel) 2297{ 2298 2299 MAC_PERFORM(relabel_cred, cred, newlabel); 2300} 2301 2302void 2303mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 2304{ 2305 2306 MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 2307} 2308 2309void 2310mac_create_ifnet(struct ifnet *ifnet) 2311{ 2312 2313 MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2314} 2315 2316void 2317mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2318{ 2319 2320 MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2321} 2322 2323void 2324mac_create_socket(struct ucred *cred, struct socket *socket) 2325{ 2326 2327 MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2328} 2329 2330void 2331mac_create_pipe(struct ucred *cred, struct pipe *pipe) 2332{ 2333 2334 MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2335} 2336 2337void 2338mac_create_socket_from_socket(struct socket *oldsocket, 2339 struct socket *newsocket) 2340{ 2341 2342 MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2343 newsocket, &newsocket->so_label); 2344} 2345 2346static void 2347mac_relabel_socket(struct ucred *cred, struct socket *socket, 2348 struct label *newlabel) 2349{ 2350 2351 MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2352} 2353 2354static void 2355mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2356{ 2357 2358 MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2359} 2360 2361void 2362mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2363{ 2364 2365 MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label, 2366 socket, &socket->so_peerlabel); 2367} 2368 2369void 2370mac_set_socket_peer_from_socket(struct socket *oldsocket, 2371 struct socket *newsocket) 2372{ 2373 2374 MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2375 &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2376} 2377 2378void 2379mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2380{ 2381 2382 MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2383 datagram, &datagram->m_pkthdr.label); 2384} 2385 2386void 2387mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2388{ 2389 2390 MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label, 2391 fragment, &fragment->m_pkthdr.label); 2392} 2393 2394void 2395mac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2396{ 2397 2398 MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2399 &ipq->ipq_label); 2400} 2401 2402void 2403mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2404{ 2405 2406 MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label, 2407 newmbuf, &newmbuf->m_pkthdr.label); 2408} 2409 2410void 2411mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2412{ 2413 2414 MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2415 &mbuf->m_pkthdr.label); 2416} 2417 2418void 2419mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2420{ 2421 2422 MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2423 &mbuf->m_pkthdr.label); 2424} 2425 2426void 2427mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2428{ 2429 2430 MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2431 &mbuf->m_pkthdr.label); 2432} 2433 2434void 2435mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2436 struct mbuf *newmbuf) 2437{ 2438 2439 MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, 2440 &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf, 2441 &newmbuf->m_pkthdr.label); 2442} 2443 2444void 2445mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2446{ 2447 2448 MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label, 2449 newmbuf, &newmbuf->m_pkthdr.label); 2450} 2451 2452int 2453mac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2454{ 2455 int result; 2456 2457 result = 1; 2458 MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label, 2459 ipq, &ipq->ipq_label); 2460 2461 return (result); 2462} 2463 2464void 2465mac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2466{ 2467 2468 MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2469 &ipq->ipq_label); 2470} 2471 2472void 2473mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2474{ 2475 2476 MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2477 &mbuf->m_pkthdr.label); 2478} 2479 2480void 2481mac_create_mount(struct ucred *cred, struct mount *mp) 2482{ 2483 2484 MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2485 &mp->mnt_fslabel); 2486} 2487 2488void 2489mac_create_root_mount(struct ucred *cred, struct mount *mp) 2490{ 2491 2492 MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2493 &mp->mnt_fslabel); 2494} 2495 2496int 2497mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2498{ 2499 int error; 2500 2501 if (!mac_enforce_network) 2502 return (0); 2503 2504 MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2505 &ifnet->if_label); 2506 2507 return (error); 2508} 2509 2510static int 2511mac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2512{ 2513 int error; 2514 2515 MAC_CHECK(check_cred_relabel, cred, newlabel); 2516 2517 return (error); 2518} 2519 2520int 2521mac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2522{ 2523 int error; 2524 2525 if (!mac_enforce_process) 2526 return (0); 2527 2528 MAC_CHECK(check_cred_visible, u1, u2); 2529 2530 return (error); 2531} 2532 2533int 2534mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2535{ 2536 int error; 2537 2538 if (!mac_enforce_network) 2539 return (0); 2540 2541 KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr")); 2542 if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED)) 2543 printf("%s%d: not initialized\n", ifnet->if_name, 2544 ifnet->if_unit); 2545 2546 MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2547 &mbuf->m_pkthdr.label); 2548 2549 return (error); 2550} 2551 2552int 2553mac_check_mount_stat(struct ucred *cred, struct mount *mount) 2554{ 2555 int error; 2556 2557 if (!mac_enforce_fs) 2558 return (0); 2559 2560 MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2561 2562 return (error); 2563} 2564 2565int 2566mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2567 void *data) 2568{ 2569 int error; 2570 2571 MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2572 2573 return (error); 2574} 2575 2576int 2577mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2578{ 2579 int error; 2580 2581 MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2582 2583 return (error); 2584} 2585 2586int 2587mac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2588{ 2589 int error; 2590 2591 MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2592 2593 return (error); 2594} 2595 2596static int 2597mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2598 struct label *newlabel) 2599{ 2600 int error; 2601 2602 MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2603 2604 return (error); 2605} 2606 2607int 2608mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2609{ 2610 int error; 2611 2612 MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2613 2614 return (error); 2615} 2616 2617int 2618mac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2619{ 2620 int error; 2621 2622 MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2623 2624 return (error); 2625} 2626 2627int 2628mac_check_proc_debug(struct ucred *cred, struct proc *proc) 2629{ 2630 int error; 2631 2632 PROC_LOCK_ASSERT(proc, MA_OWNED); 2633 2634 if (!mac_enforce_process) 2635 return (0); 2636 2637 MAC_CHECK(check_proc_debug, cred, proc); 2638 2639 return (error); 2640} 2641 2642int 2643mac_check_proc_sched(struct ucred *cred, struct proc *proc) 2644{ 2645 int error; 2646 2647 PROC_LOCK_ASSERT(proc, MA_OWNED); 2648 2649 if (!mac_enforce_process) 2650 return (0); 2651 2652 MAC_CHECK(check_proc_sched, cred, proc); 2653 2654 return (error); 2655} 2656 2657int 2658mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2659{ 2660 int error; 2661 2662 PROC_LOCK_ASSERT(proc, MA_OWNED); 2663 2664 if (!mac_enforce_process) 2665 return (0); 2666 2667 MAC_CHECK(check_proc_signal, cred, proc, signum); 2668 2669 return (error); 2670} 2671 2672int 2673mac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2674 struct sockaddr *sockaddr) 2675{ 2676 int error; 2677 2678 if (!mac_enforce_socket) 2679 return (0); 2680 2681 MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2682 sockaddr); 2683 2684 return (error); 2685} 2686 2687int 2688mac_check_socket_connect(struct ucred *cred, struct socket *socket, 2689 struct sockaddr *sockaddr) 2690{ 2691 int error; 2692 2693 if (!mac_enforce_socket) 2694 return (0); 2695 2696 MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2697 sockaddr); 2698 2699 return (error); 2700} 2701 2702int 2703mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2704{ 2705 int error; 2706 2707 if (!mac_enforce_socket) 2708 return (0); 2709 2710 MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2711 &mbuf->m_pkthdr.label); 2712 2713 return (error); 2714} 2715 2716int 2717mac_check_socket_listen(struct ucred *cred, struct socket *socket) 2718{ 2719 int error; 2720 2721 if (!mac_enforce_socket) 2722 return (0); 2723 2724 MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2725 return (error); 2726} 2727 2728static int 2729mac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2730 struct label *newlabel) 2731{ 2732 int error; 2733 2734 MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2735 newlabel); 2736 2737 return (error); 2738} 2739 2740int 2741mac_check_socket_visible(struct ucred *cred, struct socket *socket) 2742{ 2743 int error; 2744 2745 if (!mac_enforce_socket) 2746 return (0); 2747 2748 MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 2749 2750 return (error); 2751} 2752 2753int 2754mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 2755 struct ifnet *ifnet) 2756{ 2757 struct mac label; 2758 int error; 2759 2760 error = mac_externalize(&ifnet->if_label, &label); 2761 if (error) 2762 return (error); 2763 2764 return (copyout(&label, ifr->ifr_ifru.ifru_data, sizeof(label))); 2765} 2766 2767int 2768mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 2769 struct ifnet *ifnet) 2770{ 2771 struct mac newlabel; 2772 struct label intlabel; 2773 int error; 2774 2775 error = copyin(ifr->ifr_ifru.ifru_data, &newlabel, sizeof(newlabel)); 2776 if (error) 2777 return (error); 2778 2779 error = mac_internalize(&intlabel, &newlabel); 2780 if (error) 2781 return (error); 2782 2783 /* 2784 * XXX: Note that this is a redundant privilege check, since 2785 * policies impose this check themselves if required by the 2786 * policy. Eventually, this should go away. 2787 */ 2788 error = suser_cred(cred, 0); 2789 if (error) 2790 goto out; 2791 2792 MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 2793 &intlabel); 2794 if (error) 2795 goto out; 2796 2797 MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 2798 2799out: 2800 mac_destroy_temp(&intlabel); 2801 return (error); 2802} 2803 2804void 2805mac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp) 2806{ 2807 2808 MAC_PERFORM(create_devfs_vnode, de, &de->de_label, vp, &vp->v_label); 2809} 2810 2811void 2812mac_create_devfs_device(dev_t dev, struct devfs_dirent *de) 2813{ 2814 2815 MAC_PERFORM(create_devfs_device, dev, de, &de->de_label); 2816} 2817 2818static int 2819mac_stdcreatevnode_ea(struct vnode *vp) 2820{ 2821 int error; 2822 2823 MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label); 2824 2825 return (error); 2826} 2827 2828void 2829mac_create_devfs_directory(char *dirname, int dirnamelen, 2830 struct devfs_dirent *de) 2831{ 2832 2833 MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de, 2834 &de->de_label); 2835} 2836 2837/* 2838 * When a new vnode is created, this call will initialize its label. 2839 */ 2840void 2841mac_create_vnode(struct ucred *cred, struct vnode *parent, 2842 struct vnode *child) 2843{ 2844 int error; 2845 2846 ASSERT_VOP_LOCKED(parent, "mac_create_vnode"); 2847 ASSERT_VOP_LOCKED(child, "mac_create_vnode"); 2848 2849 error = vn_refreshlabel(parent, cred); 2850 if (error) { 2851 printf("mac_create_vnode: vn_refreshlabel returned %d\n", 2852 error); 2853 printf("mac_create_vnode: using old vnode label\n"); 2854 } 2855 2856 MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child, 2857 &child->v_label); 2858} 2859 2860int 2861mac_setsockopt_label_set(struct ucred *cred, struct socket *so, 2862 struct mac *extmac) 2863{ 2864 struct label intlabel; 2865 int error; 2866 2867 error = mac_internalize(&intlabel, extmac); 2868 if (error) 2869 return (error); 2870 2871 mac_check_socket_relabel(cred, so, &intlabel); 2872 if (error) { 2873 mac_destroy_temp(&intlabel); 2874 return (error); 2875 } 2876 2877 mac_relabel_socket(cred, so, &intlabel); 2878 2879 mac_destroy_temp(&intlabel); 2880 return (0); 2881} 2882 2883int 2884mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 2885{ 2886 int error; 2887 2888 error = mac_check_pipe_relabel(cred, pipe, label); 2889 if (error) 2890 return (error); 2891 2892 mac_relabel_pipe(cred, pipe, label); 2893 2894 return (0); 2895} 2896 2897int 2898mac_getsockopt_label_get(struct ucred *cred, struct socket *so, 2899 struct mac *extmac) 2900{ 2901 2902 return (mac_externalize(&so->so_label, extmac)); 2903} 2904 2905int 2906mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 2907 struct mac *extmac) 2908{ 2909 2910 return (mac_externalize(&so->so_peerlabel, extmac)); 2911} 2912 2913/* 2914 * Implementation of VOP_SETLABEL() that relies on extended attributes 2915 * to store label data. Can be referenced by filesystems supporting 2916 * extended attributes. 2917 */ 2918int 2919vop_stdsetlabel_ea(struct vop_setlabel_args *ap) 2920{ 2921 struct vnode *vp = ap->a_vp; 2922 struct label *intlabel = ap->a_label; 2923 struct mac extmac; 2924 int error; 2925 2926 ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 2927 2928 /* 2929 * XXX: Eventually call out to EA check/set calls here. 2930 * Be particularly careful to avoid race conditions, 2931 * consistency problems, and stability problems when 2932 * dealing with multiple EAs. In particular, we require 2933 * the ability to write multiple EAs on the same file in 2934 * a single transaction, which the current EA interface 2935 * does not provide. 2936 */ 2937 2938 error = mac_externalize(intlabel, &extmac); 2939 if (error) 2940 return (error); 2941 2942 error = vn_extattr_set(vp, IO_NODELOCKED, 2943 FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, 2944 sizeof(extmac), (char *)&extmac, curthread); 2945 if (error) 2946 return (error); 2947 2948 mac_relabel_vnode(ap->a_cred, vp, intlabel); 2949 2950 vp->v_vflag |= VV_CACHEDLABEL; 2951 2952 return (0); 2953} 2954 2955static int 2956vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 2957{ 2958 int error; 2959 2960 if (vp->v_mount == NULL) { 2961 /* printf("vn_setlabel: null v_mount\n"); */ 2962 if (vp->v_type != VNON) 2963 printf("vn_setlabel: null v_mount with non-VNON\n"); 2964 return (EBADF); 2965 } 2966 2967 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 2968 return (EOPNOTSUPP); 2969 2970 /* 2971 * Multi-phase commit. First check the policies to confirm the 2972 * change is OK. Then commit via the filesystem. Finally, 2973 * update the actual vnode label. Question: maybe the filesystem 2974 * should update the vnode at the end as part of VOP_SETLABEL()? 2975 */ 2976 error = mac_check_vnode_relabel(cred, vp, intlabel); 2977 if (error) 2978 return (error); 2979 2980 /* 2981 * VADMIN provides the opportunity for the filesystem to make 2982 * decisions about who is and is not able to modify labels 2983 * and protections on files. This might not be right. We can't 2984 * assume VOP_SETLABEL() will do it, because we might implement 2985 * that as part of vop_stdsetlabel_ea(). 2986 */ 2987 error = VOP_ACCESS(vp, VADMIN, cred, curthread); 2988 if (error) 2989 return (error); 2990 2991 error = VOP_SETLABEL(vp, intlabel, cred, curthread); 2992 if (error) 2993 return (error); 2994 2995 return (0); 2996} 2997 2998/* 2999 * MPSAFE 3000 */ 3001int 3002__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3003{ 3004 struct mac extmac; 3005 int error; 3006 3007 error = mac_externalize(&td->td_ucred->cr_label, &extmac); 3008 if (error == 0) 3009 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac)); 3010 3011 return (error); 3012} 3013 3014/* 3015 * MPSAFE 3016 */ 3017int 3018__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3019{ 3020 struct ucred *newcred, *oldcred; 3021 struct proc *p; 3022 struct mac extmac; 3023 struct label intlabel; 3024 int error; 3025 3026 error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac)); 3027 if (error) 3028 return (error); 3029 3030 error = mac_internalize(&intlabel, &extmac); 3031 if (error) 3032 return (error); 3033 3034 newcred = crget(); 3035 3036 p = td->td_proc; 3037 PROC_LOCK(p); 3038 oldcred = p->p_ucred; 3039 3040 error = mac_check_cred_relabel(oldcred, &intlabel); 3041 if (error) { 3042 PROC_UNLOCK(p); 3043 mac_destroy_temp(&intlabel); 3044 crfree(newcred); 3045 return (error); 3046 } 3047 3048 setsugid(p); 3049 crcopy(newcred, oldcred); 3050 mac_relabel_cred(newcred, &intlabel); 3051 p->p_ucred = newcred; 3052 3053 /* 3054 * Grab additional reference for use while revoking mmaps, prior 3055 * to releasing the proc lock and sharing the cred. 3056 */ 3057 crhold(newcred); 3058 PROC_UNLOCK(p); 3059 3060 mtx_lock(&Giant); 3061 mac_cred_mmapped_drop_perms(td, newcred); 3062 mtx_unlock(&Giant); 3063 3064 crfree(newcred); /* Free revocation reference. */ 3065 crfree(oldcred); 3066 mac_destroy_temp(&intlabel); 3067 return (0); 3068} 3069 3070/* 3071 * MPSAFE 3072 */ 3073int 3074__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3075{ 3076 struct file *fp; 3077 struct mac extmac; 3078 struct vnode *vp; 3079 struct pipe *pipe; 3080 int error; 3081 3082 mtx_lock(&Giant); 3083 3084 error = fget(td, SCARG(uap, fd), &fp); 3085 if (error) 3086 goto out; 3087 3088 switch (fp->f_type) { 3089 case DTYPE_FIFO: 3090 case DTYPE_VNODE: 3091 vp = (struct vnode *)fp->f_data; 3092 3093 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3094 error = vn_refreshlabel(vp, td->td_ucred); 3095 if (error == 0) 3096 error = mac_externalize(&vp->v_label, &extmac); 3097 VOP_UNLOCK(vp, 0, td); 3098 break; 3099 case DTYPE_PIPE: 3100 pipe = (struct pipe *)fp->f_data; 3101 error = mac_externalize(pipe->pipe_label, &extmac); 3102 break; 3103 default: 3104 error = EINVAL; 3105 } 3106 3107 if (error == 0) 3108 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac)); 3109 3110 fdrop(fp, td); 3111 3112out: 3113 mtx_unlock(&Giant); 3114 return (error); 3115} 3116 3117/* 3118 * MPSAFE 3119 */ 3120int 3121__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3122{ 3123 struct nameidata nd; 3124 struct mac extmac; 3125 int error; 3126 3127 mtx_lock(&Giant); 3128 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, 3129 SCARG(uap, path_p), td); 3130 error = namei(&nd); 3131 if (error) 3132 goto out; 3133 3134 error = vn_refreshlabel(nd.ni_vp, td->td_ucred); 3135 if (error == 0) 3136 error = mac_externalize(&nd.ni_vp->v_label, &extmac); 3137 NDFREE(&nd, 0); 3138 if (error) 3139 goto out; 3140 3141 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac)); 3142 3143out: 3144 mtx_unlock(&Giant); 3145 return (error); 3146} 3147 3148/* 3149 * MPSAFE 3150 */ 3151int 3152__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3153{ 3154 struct file *fp; 3155 struct mac extmac; 3156 struct label intlabel; 3157 struct mount *mp; 3158 struct vnode *vp; 3159 struct pipe *pipe; 3160 int error; 3161 3162 mtx_lock(&Giant); 3163 error = fget(td, SCARG(uap, fd), &fp); 3164 if (error) 3165 goto out1; 3166 3167 error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac)); 3168 if (error) 3169 goto out2; 3170 3171 error = mac_internalize(&intlabel, &extmac); 3172 if (error) 3173 goto out2; 3174 3175 switch (fp->f_type) { 3176 case DTYPE_FIFO: 3177 case DTYPE_VNODE: 3178 vp = (struct vnode *)fp->f_data; 3179 error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3180 if (error != 0) 3181 break; 3182 3183 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3184 error = vn_setlabel(vp, &intlabel, td->td_ucred); 3185 VOP_UNLOCK(vp, 0, td); 3186 vn_finished_write(mp); 3187 mac_destroy_temp(&intlabel); 3188 break; 3189 case DTYPE_PIPE: 3190 pipe = (struct pipe *)fp->f_data; 3191 error = mac_pipe_label_set(td->td_ucred, pipe, &intlabel); 3192 break; 3193 default: 3194 error = EINVAL; 3195 } 3196 3197out2: 3198 fdrop(fp, td); 3199out1: 3200 mtx_unlock(&Giant); 3201 return (error); 3202} 3203 3204/* 3205 * MPSAFE 3206 */ 3207int 3208__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3209{ 3210 struct nameidata nd; 3211 struct mac extmac; 3212 struct label intlabel; 3213 struct mount *mp; 3214 int error; 3215 3216 mtx_lock(&Giant); 3217 3218 error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac)); 3219 if (error) 3220 goto out; 3221 3222 error = mac_internalize(&intlabel, &extmac); 3223 if (error) 3224 goto out; 3225 3226 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, 3227 SCARG(uap, path_p), td); 3228 error = namei(&nd); 3229 if (error) 3230 goto out2; 3231 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3232 if (error) 3233 goto out2; 3234 3235 error = vn_setlabel(nd.ni_vp, &intlabel, td->td_ucred); 3236 3237 vn_finished_write(mp); 3238out2: 3239 mac_destroy_temp(&intlabel); 3240 NDFREE(&nd, 0); 3241out: 3242 mtx_unlock(&Giant); 3243 return (error); 3244} 3245 3246int 3247mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3248{ 3249 struct mac_policy_conf *mpc; 3250 char target[MAC_MAX_POLICY_NAME]; 3251 int error; 3252 3253 error = copyinstr(SCARG(uap, policy), target, sizeof(target), NULL); 3254 if (error) 3255 return (error); 3256 3257 error = ENOSYS; 3258 MAC_POLICY_LIST_BUSY(); 3259 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3260 if (strcmp(mpc->mpc_name, target) == 0 && 3261 mpc->mpc_ops->mpo_syscall != NULL) { 3262 error = mpc->mpc_ops->mpo_syscall(td, 3263 SCARG(uap, call), SCARG(uap, arg)); 3264 goto out; 3265 } 3266 } 3267 3268out: 3269 MAC_POLICY_LIST_UNBUSY(); 3270 return (error); 3271} 3272 3273SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3274SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3275 3276#else /* !MAC */ 3277 3278int 3279__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3280{ 3281 3282 return (ENOSYS); 3283} 3284 3285int 3286__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3287{ 3288 3289 return (ENOSYS); 3290} 3291 3292int 3293__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3294{ 3295 3296 return (ENOSYS); 3297} 3298 3299int 3300__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3301{ 3302 3303 return (ENOSYS); 3304} 3305 3306int 3307__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3308{ 3309 3310 return (ENOSYS); 3311} 3312 3313int 3314__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3315{ 3316 3317 return (ENOSYS); 3318} 3319 3320int 3321mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3322{ 3323 3324 return (ENOSYS); 3325} 3326 3327#endif /* !MAC */ 3328