mac_vfs.c revision 104268
117680Spst/*- 239300Sfenner * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 317680Spst * Copyright (c) 2001 Ilmar S. Habibulin 417680Spst * Copyright (c) 2001, 2002 Networks Associates Technology, Inc. 517680Spst * All rights reserved. 617680Spst * 717680Spst * This software was developed by Robert Watson and Ilmar Habibulin for the 817680Spst * TrustedBSD Project. 917680Spst * 1017680Spst * This software was developed for the FreeBSD Project in part by NAI Labs, 1117680Spst * the Security Research Division of Network Associates, Inc. under 1217680Spst * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 1317680Spst * CHATS research program. 1417680Spst * 1517680Spst * Redistribution and use in source and binary forms, with or without 1617680Spst * modification, are permitted provided that the following conditions 1717680Spst * are met: 1817680Spst * 1. Redistributions of source code must retain the above copyright 1917680Spst * notice, this list of conditions and the following disclaimer. 2056896Sfenner * 2. Redistributions in binary form must reproduce the above copyright 2156896Sfenner * notice, this list of conditions and the following disclaimer in the 2217680Spst * documentation and/or other materials provided with the distribution. 2317680Spst * 3. The names of the authors may not be used to endorse or promote 2417680Spst * products derived from this software without specific prior written 25127675Sbms * permission. 26214478Srpaulo * 2717680Spst * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2817680Spst * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2956896Sfenner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3056896Sfenner * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 3156896Sfenner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3256896Sfenner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33127675Sbms * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3417680Spst * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3575118Sfenner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3617680Spst * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3717680Spst * SUCH DAMAGE. 3856896Sfenner * 3917680Spst * $FreeBSD: head/sys/security/mac/mac_vfs.c 104268 2002-10-01 03:24:20Z rwatson $ 4017680Spst */ 4117680Spst/* 4217680Spst * Developed by the TrustedBSD Project. 4317680Spst * 4498527Sfenner * Framework for extensible kernel access control. Kernel and userland 4598527Sfenner * interface to the framework, policy registration and composition. 4617680Spst */ 4717680Spst 4817680Spst#include "opt_mac.h" 4917680Spst 5098527Sfenner#include <sys/param.h> 5117680Spst#include <sys/extattr.h> 5298527Sfenner#include <sys/kernel.h> 5398527Sfenner#include <sys/lock.h> 5417680Spst#include <sys/malloc.h> 5517680Spst#include <sys/mutex.h> 5617680Spst#include <sys/mac.h> 5717680Spst#include <sys/module.h> 5817680Spst#include <sys/proc.h> 59127675Sbms#include <sys/systm.h> 6017680Spst#include <sys/sysproto.h> 6117680Spst#include <sys/sysent.h> 6217680Spst#include <sys/vnode.h> 6398527Sfenner#include <sys/mount.h> 6498527Sfenner#include <sys/file.h> 65127675Sbms#include <sys/namei.h> 6698527Sfenner#include <sys/socket.h> 67127675Sbms#include <sys/pipe.h> 68127675Sbms#include <sys/socketvar.h> 6975118Sfenner#include <sys/sysctl.h> 7075118Sfenner 7175118Sfenner#include <vm/vm.h> 7275118Sfenner#include <vm/pmap.h> 7375118Sfenner#include <vm/vm_map.h> 7498527Sfenner#include <vm/vm_object.h> 7598527Sfenner 7675118Sfenner#include <sys/mac_policy.h> 7775118Sfenner 7875118Sfenner#include <fs/devfs/devfs.h> 7975118Sfenner 8075118Sfenner#include <net/bpfdesc.h> 8175118Sfenner#include <net/if.h> 8298527Sfenner#include <net/if_var.h> 8398527Sfenner 8417680Spst#include <netinet/in.h> 8517680Spst#include <netinet/ip_var.h> 8617680Spst 8717680Spst#ifdef MAC 8817680Spst 8917680Spst/* 9017680Spst * Declare that the kernel provides MAC support, version 1. This permits 9175118Sfenner * modules to refuse to be loaded if the necessary support isn't present, 9217680Spst * even if it's pre-boot. 9375118Sfenner */ 9475118SfennerMODULE_VERSION(kernel_mac_support, 1); 9575118Sfenner 9675118SfennerSYSCTL_DECL(_security); 9798527Sfenner 9875118SfennerSYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0, 9975118Sfenner "TrustedBSD MAC policy controls"); 10075118Sfenner#ifndef MAC_MAX_POLICIES 10175118Sfenner#define MAC_MAX_POLICIES 8 102127675Sbms#endif 10375118Sfenner#if MAC_MAX_POLICIES > 32 10475118Sfenner#error "MAC_MAX_POLICIES too large" 10575118Sfenner#endif 106127675Sbmsstatic unsigned int mac_max_policies = MAC_MAX_POLICIES; 107127675Sbmsstatic unsigned int mac_policy_offsets_free = (1 << MAC_MAX_POLICIES) - 1; 10875118SfennerSYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD, 109127675Sbms &mac_max_policies, 0, ""); 110127675Sbms 111127675Sbmsstatic int mac_late = 0; 11275118Sfenner 11375118Sfennerstatic int mac_enforce_fs = 1; 11475118SfennerSYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW, 115127675Sbms &mac_enforce_fs, 0, "Enforce MAC policy on file system objects"); 11675118SfennerTUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs); 11775118Sfenner 11875118Sfennerstatic int mac_enforce_network = 1; 11975118SfennerSYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, 120127675Sbms &mac_enforce_network, 0, "Enforce MAC policy on network packets"); 121127675SbmsTUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); 122127675Sbms 123127675Sbmsstatic int mac_enforce_pipe = 1; 12475118SfennerSYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW, 12575118Sfenner &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations"); 12675118SfennerTUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe); 12775118Sfenner 12875118Sfennerstatic int mac_enforce_process = 1; 12917680SpstSYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW, 13017680Spst &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations"); 13198527SfennerTUNABLE_INT("security.mac.enforce_process", &mac_enforce_process); 13275118Sfenner 13375118Sfennerstatic int mac_enforce_socket = 1; 13475118SfennerSYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 13575118Sfenner &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 136147904SsamTUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 137147904Ssam 13875118Sfennerstatic int mac_enforce_vm = 1; 139147904SsamSYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW, 14098527Sfenner &mac_enforce_vm, 0, "Enforce MAC policy on vm operations"); 14175118SfennerTUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm); 14275118Sfenner 14375118Sfennerstatic int mac_label_size = sizeof(struct mac); 14475118SfennerSYSCTL_INT(_security_mac, OID_AUTO, label_size, CTLFLAG_RD, 14517680Spst &mac_label_size, 0, "Pre-compiled MAC label size"); 14675118Sfenner 14775118Sfennerstatic int mac_cache_fslabel_in_vnode = 1; 14875118SfennerSYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW, 149251158Sdelphij &mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode"); 15075118SfennerTUNABLE_INT("security.mac.cache_fslabel_in_vnode", 15175118Sfenner &mac_cache_fslabel_in_vnode); 15275118Sfenner 15375118Sfennerstatic int mac_vnode_label_cache_hits = 0; 15475118SfennerSYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_hits, CTLFLAG_RD, 15575118Sfenner &mac_vnode_label_cache_hits, 0, "Cache hits on vnode labels"); 15675118Sfennerstatic int mac_vnode_label_cache_misses = 0; 15775118SfennerSYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_misses, CTLFLAG_RD, 15875118Sfenner &mac_vnode_label_cache_misses, 0, "Cache misses on vnode labels"); 159127675Sbms 16075118Sfennerstatic int mac_mmap_revocation = 1; 16198527SfennerSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW, 16275118Sfenner &mac_mmap_revocation, 0, "Revoke mmap access to files on subject " 16375118Sfenner "relabel"); 16475118Sfennerstatic int mac_mmap_revocation_via_cow = 0; 16517680SpstSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW, 16675118Sfenner &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via " 16775118Sfenner "copy-on-write semantics, or by removing all write access"); 16875118Sfenner 16917680Spst#ifdef MAC_DEBUG 17017680SpstSYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0, 17117680Spst "TrustedBSD MAC debug info"); 17275118Sfenner 17375118Sfennerstatic int mac_debug_label_fallback = 0; 17475118SfennerSYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW, 17575118Sfenner &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label" 17698527Sfenner "when label is corrupted."); 17798527SfennerTUNABLE_INT("security.mac.debug_label_fallback", 17817680Spst &mac_debug_label_fallback); 179127675Sbms 18075118Sfennerstatic unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs, 18198527Sfenner nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents, 18298527Sfenner nmacipqs, nmacpipes; 18317680SpstSYSCTL_UINT(_security_mac_debug, OID_AUTO, mbufs, CTLFLAG_RD, 18475118Sfenner &nmacmbufs, 0, "number of mbufs in use"); 18575118SfennerSYSCTL_UINT(_security_mac_debug, OID_AUTO, creds, CTLFLAG_RD, 18675118Sfenner &nmaccreds, 0, "number of ucreds in use"); 18775118SfennerSYSCTL_UINT(_security_mac_debug, OID_AUTO, ifnets, CTLFLAG_RD, 18875118Sfenner &nmacifnets, 0, "number of ifnets in use"); 18975118SfennerSYSCTL_UINT(_security_mac_debug, OID_AUTO, ipqs, CTLFLAG_RD, 19075118Sfenner &nmacipqs, 0, "number of ipqs in use"); 19175118SfennerSYSCTL_UINT(_security_mac_debug, OID_AUTO, bpfdescs, CTLFLAG_RD, 19275118Sfenner &nmacbpfdescs, 0, "number of bpfdescs in use"); 19375118SfennerSYSCTL_UINT(_security_mac_debug, OID_AUTO, sockets, CTLFLAG_RD, 19475118Sfenner &nmacsockets, 0, "number of sockets in use"); 19575118SfennerSYSCTL_UINT(_security_mac_debug, OID_AUTO, pipes, CTLFLAG_RD, 19617680Spst &nmacpipes, 0, "number of pipes in use"); 19717680SpstSYSCTL_UINT(_security_mac_debug, OID_AUTO, mounts, CTLFLAG_RD, 19875118Sfenner &nmacmounts, 0, "number of mounts in use"); 19975118SfennerSYSCTL_UINT(_security_mac_debug, OID_AUTO, temp, CTLFLAG_RD, 20075118Sfenner &nmactemp, 0, "number of temporary labels in use"); 20175118SfennerSYSCTL_UINT(_security_mac_debug, OID_AUTO, vnodes, CTLFLAG_RD, 20298527Sfenner &nmacvnodes, 0, "number of vnodes in use"); 20398527SfennerSYSCTL_UINT(_security_mac_debug, OID_AUTO, devfsdirents, CTLFLAG_RD, 20475118Sfenner &nmacdevfsdirents, 0, "number of devfs dirents inuse"); 20575118Sfenner#endif 20675118Sfenner 20775118Sfennerstatic int error_select(int error1, int error2); 20875118Sfennerstatic int mac_externalize(struct label *label, struct mac *mac); 20975118Sfennerstatic int mac_policy_register(struct mac_policy_conf *mpc); 21075118Sfennerstatic int mac_policy_unregister(struct mac_policy_conf *mpc); 21175118Sfenner 21298527Sfennerstatic int mac_stdcreatevnode_ea(struct vnode *vp); 21375118Sfennerstatic void mac_cred_mmapped_drop_perms(struct thread *td, 21475118Sfenner struct ucred *cred); 21575118Sfennerstatic void mac_cred_mmapped_drop_perms_recurse(struct thread *td, 21675118Sfenner struct ucred *cred, struct vm_map *map); 21717680Spst 218127675SbmsMALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector"); 21975118SfennerMALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes"); 22098527Sfenner 22198527Sfenner/* 22217680Spst * mac_policy_list_lock protects the consistency of 'mac_policy_list', 22375118Sfenner * the linked list of attached policy modules. Read-only consumers of 22417680Spst * the list must acquire a shared lock for the duration of their use; 22575118Sfenner * writers must acquire an exclusive lock. Note that for compound 22617680Spst * operations, locks should be held for the entire compound operation, 22717680Spst * and that this is not yet done for relabel requests. 22817680Spst */ 22917680Spststatic struct mtx mac_policy_list_lock; 23017680Spststatic LIST_HEAD(, mac_policy_conf) mac_policy_list; 23117680Spststatic int mac_policy_list_busy; 23217680Spst#define MAC_POLICY_LIST_LOCKINIT() mtx_init(&mac_policy_list_lock, \ 23317680Spst "mac_policy_list_lock", NULL, MTX_DEF); 234127675Sbms#define MAC_POLICY_LIST_LOCK() mtx_lock(&mac_policy_list_lock); 23517680Spst#define MAC_POLICY_LIST_UNLOCK() mtx_unlock(&mac_policy_list_lock); 23617680Spst 23717680Spst#define MAC_POLICY_LIST_BUSY() do { \ 23898527Sfenner MAC_POLICY_LIST_LOCK(); \ 23998527Sfenner mac_policy_list_busy++; \ 24017680Spst MAC_POLICY_LIST_UNLOCK(); \ 24198527Sfenner} while (0) 24298527Sfenner 24317680Spst#define MAC_POLICY_LIST_UNBUSY() do { \ 24417680Spst MAC_POLICY_LIST_LOCK(); \ 24517680Spst mac_policy_list_busy--; \ 246127675Sbms if (mac_policy_list_busy < 0) \ 24798527Sfenner panic("Extra mac_policy_list_busy--"); \ 248127675Sbms MAC_POLICY_LIST_UNLOCK(); \ 249127675Sbms} while (0) 250127675Sbms 251127675Sbms/* 252127675Sbms * MAC_CHECK performs the designated check by walking the policy 253127675Sbms * module list and checking with each as to how it feels about the 254127675Sbms * request. Note that it returns its value via 'error' in the scope 255127675Sbms * of the caller. 256127675Sbms */ 257127675Sbms#define MAC_CHECK(check, args...) do { \ 258127675Sbms struct mac_policy_conf *mpc; \ 259127675Sbms \ 260127675Sbms error = 0; \ 261127675Sbms MAC_POLICY_LIST_BUSY(); \ 262127675Sbms LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 263127675Sbms if (mpc->mpc_ops->mpo_ ## check != NULL) \ 264127675Sbms error = error_select( \ 265127675Sbms mpc->mpc_ops->mpo_ ## check (args), \ 266127675Sbms error); \ 267127675Sbms } \ 268127675Sbms MAC_POLICY_LIST_UNBUSY(); \ 269127675Sbms} while (0) 27017680Spst 271127675Sbms/* 272127675Sbms * MAC_BOOLEAN performs the designated boolean composition by walking 273127675Sbms * the module list, invoking each instance of the operation, and 274127675Sbms * combining the results using the passed C operator. Note that it 275127675Sbms * returns its value via 'result' in the scope of the caller, which 276127675Sbms * should be initialized by the caller in a meaningful way to get 277127675Sbms * a meaningful result. 278127675Sbms */ 279127675Sbms#define MAC_BOOLEAN(operation, composition, args...) do { \ 280127675Sbms struct mac_policy_conf *mpc; \ 281127675Sbms \ 282127675Sbms MAC_POLICY_LIST_BUSY(); \ 283172686Smlaier LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 284172686Smlaier if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 285127675Sbms result = result composition \ 286127675Sbms mpc->mpc_ops->mpo_ ## operation (args); \ 287172686Smlaier } \ 288127675Sbms MAC_POLICY_LIST_UNBUSY(); \ 289172686Smlaier} while (0) 290172686Smlaier 291172686Smlaier/* 292172686Smlaier * MAC_PERFORM performs the designated operation by walking the policy 293172686Smlaier * module list and invoking that operation for each policy. 294172686Smlaier */ 295172686Smlaier#define MAC_PERFORM(operation, args...) do { \ 296172686Smlaier struct mac_policy_conf *mpc; \ 29739300Sfenner \ 29839300Sfenner MAC_POLICY_LIST_BUSY(); \ 29939300Sfenner LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 30017680Spst if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 30117680Spst mpc->mpc_ops->mpo_ ## operation (args); \ 302127675Sbms } \ 303127675Sbms MAC_POLICY_LIST_UNBUSY(); \ 304127675Sbms} while (0) 305127675Sbms 306127675Sbms/* 307127675Sbms * Initialize the MAC subsystem, including appropriate SMP locks. 30817680Spst */ 30917680Spststatic void 31017680Spstmac_init(void) 31117680Spst{ 31298527Sfenner 31317680Spst LIST_INIT(&mac_policy_list); 31498527Sfenner MAC_POLICY_LIST_LOCKINIT(); 31517680Spst} 31617680Spst 31717680Spst/* 31817680Spst * For the purposes of modules that want to know if they were loaded 31917680Spst * "early", set the mac_late flag once we've processed modules either 32017680Spst * linked into the kernel, or loaded before the kernel startup. 32175118Sfenner */ 322127675Sbmsstatic void 32317680Spstmac_late_init(void) 32417680Spst{ 325172686Smlaier 32617680Spst mac_late = 1; 327127675Sbms} 32817680Spst 32998527Sfenner/* 33075118Sfenner * Allow MAC policy modules to register during boot, etc. 33117680Spst */ 332172686Smlaierint 333127675Sbmsmac_policy_modevent(module_t mod, int type, void *data) 334127675Sbms{ 33598527Sfenner struct mac_policy_conf *mpc; 336172686Smlaier int error; 337127675Sbms 338127675Sbms error = 0; 339172686Smlaier mpc = (struct mac_policy_conf *) data; 340172686Smlaier 341172686Smlaier switch (type) { 342172686Smlaier case MOD_LOAD: 343172686Smlaier if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && 344172686Smlaier mac_late) { 345172686Smlaier printf("mac_policy_modevent: can't load %s policy " 346172686Smlaier "after booting\n", mpc->mpc_name); 347172686Smlaier error = EBUSY; 348172686Smlaier break; 349172686Smlaier } 350172686Smlaier error = mac_policy_register(mpc); 35117680Spst break; 35217680Spst case MOD_UNLOAD: 35375118Sfenner /* Don't unregister the module if it was never registered. */ 35475118Sfenner if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) 35517680Spst != 0) 35617680Spst error = mac_policy_unregister(mpc); 35717680Spst else 35817680Spst error = 0; 359127675Sbms break; 36017680Spst default: 361172686Smlaier break; 36217680Spst } 36317680Spst 36417680Spst return (error); 36517680Spst} 36617680Spst 36775118Sfennerstatic int 36875118Sfennermac_policy_register(struct mac_policy_conf *mpc) 36917680Spst{ 370127675Sbms struct mac_policy_conf *tmpc; 37117680Spst struct mac_policy_op_entry *mpe; 37298527Sfenner int slot; 37317680Spst 37417680Spst MALLOC(mpc->mpc_ops, struct mac_policy_ops *, sizeof(*mpc->mpc_ops), 375172686Smlaier M_MACOPVEC, M_WAITOK | M_ZERO); 376127675Sbms for (mpe = mpc->mpc_entries; mpe->mpe_constant != MAC_OP_LAST; mpe++) { 377127675Sbms switch (mpe->mpe_constant) { 378172686Smlaier case MAC_OP_LAST: 379172686Smlaier /* 380127675Sbms * Doesn't actually happen, but this allows checking 381172686Smlaier * that all enumerated values are handled. 382172686Smlaier */ 383172686Smlaier break; 384172686Smlaier case MAC_DESTROY: 385172686Smlaier mpc->mpc_ops->mpo_destroy = 38698527Sfenner mpe->mpe_function; 387172686Smlaier break; 388172686Smlaier case MAC_INIT: 389172686Smlaier mpc->mpc_ops->mpo_init = 390172686Smlaier mpe->mpe_function; 39117680Spst break; 392190207Srpaulo case MAC_SYSCALL: 393190207Srpaulo mpc->mpc_ops->mpo_syscall = 394190207Srpaulo mpe->mpe_function; 395172686Smlaier break; 396190207Srpaulo case MAC_INIT_BPFDESC: 397190207Srpaulo mpc->mpc_ops->mpo_init_bpfdesc = 398190207Srpaulo mpe->mpe_function; 399190207Srpaulo break; 400190207Srpaulo case MAC_INIT_CRED: 401190207Srpaulo mpc->mpc_ops->mpo_init_cred = 402190207Srpaulo mpe->mpe_function; 403190207Srpaulo break; 404190207Srpaulo case MAC_INIT_DEVFSDIRENT: 405190207Srpaulo mpc->mpc_ops->mpo_init_devfsdirent = 406190207Srpaulo mpe->mpe_function; 407190207Srpaulo break; 40817680Spst case MAC_INIT_IFNET: 409127675Sbms mpc->mpc_ops->mpo_init_ifnet = 410127675Sbms mpe->mpe_function; 41117680Spst break; 41217680Spst case MAC_INIT_IPQ: 41317680Spst mpc->mpc_ops->mpo_init_ipq = 41498527Sfenner mpe->mpe_function; 41575118Sfenner break; 41675118Sfenner case MAC_INIT_MBUF: 41775118Sfenner mpc->mpc_ops->mpo_init_mbuf = 41817680Spst mpe->mpe_function; 41917680Spst break; 42098527Sfenner case MAC_INIT_MOUNT: 42175118Sfenner mpc->mpc_ops->mpo_init_mount = 422190207Srpaulo mpe->mpe_function; 42317680Spst break; 42417680Spst case MAC_INIT_PIPE: 42517680Spst mpc->mpc_ops->mpo_init_pipe = 42617680Spst mpe->mpe_function; 42717680Spst break; 42856896Sfenner case MAC_INIT_SOCKET: 42975118Sfenner mpc->mpc_ops->mpo_init_socket = 43056896Sfenner mpe->mpe_function; 43117680Spst break; 43275118Sfenner case MAC_INIT_TEMP: 43375118Sfenner mpc->mpc_ops->mpo_init_temp = 43417680Spst mpe->mpe_function; 43517680Spst break; 43675118Sfenner case MAC_INIT_VNODE: 43775118Sfenner mpc->mpc_ops->mpo_init_vnode = 43875118Sfenner mpe->mpe_function; 43975118Sfenner break; 44075118Sfenner case MAC_DESTROY_BPFDESC: 44175118Sfenner mpc->mpc_ops->mpo_destroy_bpfdesc = 44275118Sfenner mpe->mpe_function; 44375118Sfenner break; 44475118Sfenner case MAC_DESTROY_CRED: 44598527Sfenner mpc->mpc_ops->mpo_destroy_cred = 44675118Sfenner mpe->mpe_function; 44775118Sfenner break; 44875118Sfenner case MAC_DESTROY_DEVFSDIRENT: 44975118Sfenner mpc->mpc_ops->mpo_destroy_devfsdirent = 45075118Sfenner mpe->mpe_function; 45175118Sfenner break; 45275118Sfenner case MAC_DESTROY_IFNET: 45375118Sfenner mpc->mpc_ops->mpo_destroy_ifnet = 45475118Sfenner mpe->mpe_function; 45575118Sfenner break; 45675118Sfenner case MAC_DESTROY_IPQ: 45775118Sfenner mpc->mpc_ops->mpo_destroy_ipq = 45817680Spst mpe->mpe_function; 45917680Spst break; 46098527Sfenner case MAC_DESTROY_MBUF: 46175118Sfenner mpc->mpc_ops->mpo_destroy_mbuf = 46275118Sfenner mpe->mpe_function; 46375118Sfenner break; 46417680Spst case MAC_DESTROY_MOUNT: 46517680Spst mpc->mpc_ops->mpo_destroy_mount = 46617680Spst mpe->mpe_function; 46717680Spst break; 468127675Sbms case MAC_DESTROY_PIPE: 469127675Sbms mpc->mpc_ops->mpo_destroy_pipe = 470127675Sbms mpe->mpe_function; 471127675Sbms break; 472127675Sbms case MAC_DESTROY_SOCKET: 473127675Sbms mpc->mpc_ops->mpo_destroy_socket = 474127675Sbms mpe->mpe_function; 475127675Sbms break; 476127675Sbms case MAC_DESTROY_TEMP: 477127675Sbms mpc->mpc_ops->mpo_destroy_temp = 47817680Spst mpe->mpe_function; 479127675Sbms break; 480127675Sbms case MAC_DESTROY_VNODE: 481127675Sbms mpc->mpc_ops->mpo_destroy_vnode = 482127675Sbms mpe->mpe_function; 483127675Sbms break; 484127675Sbms case MAC_EXTERNALIZE: 48517680Spst mpc->mpc_ops->mpo_externalize = 48617680Spst mpe->mpe_function; 48756896Sfenner break; 48856896Sfenner case MAC_INTERNALIZE: 489190207Srpaulo mpc->mpc_ops->mpo_internalize = 490190207Srpaulo mpe->mpe_function; 491190207Srpaulo break; 492190207Srpaulo case MAC_CREATE_DEVFS_DEVICE: 49398527Sfenner mpc->mpc_ops->mpo_create_devfs_device = 49475118Sfenner mpe->mpe_function; 495190207Srpaulo break; 496190207Srpaulo case MAC_CREATE_DEVFS_DIRECTORY: 497190207Srpaulo mpc->mpc_ops->mpo_create_devfs_directory = 498190207Srpaulo mpe->mpe_function; 49956896Sfenner break; 500190207Srpaulo case MAC_CREATE_DEVFS_VNODE: 50156896Sfenner mpc->mpc_ops->mpo_create_devfs_vnode = 50275118Sfenner mpe->mpe_function; 50356896Sfenner break; 50456896Sfenner case MAC_STDCREATEVNODE_EA: 50575118Sfenner mpc->mpc_ops->mpo_stdcreatevnode_ea = 506190207Srpaulo mpe->mpe_function; 50756896Sfenner break; 50898527Sfenner case MAC_CREATE_VNODE: 50998527Sfenner mpc->mpc_ops->mpo_create_vnode = 51075118Sfenner mpe->mpe_function; 51175118Sfenner break; 51275118Sfenner case MAC_CREATE_MOUNT: 51375118Sfenner mpc->mpc_ops->mpo_create_mount = 51475118Sfenner mpe->mpe_function; 51575118Sfenner break; 51698527Sfenner case MAC_CREATE_ROOT_MOUNT: 51798527Sfenner mpc->mpc_ops->mpo_create_root_mount = 51875118Sfenner mpe->mpe_function; 51975118Sfenner break; 520190207Srpaulo case MAC_RELABEL_VNODE: 521190207Srpaulo mpc->mpc_ops->mpo_relabel_vnode = 52275118Sfenner mpe->mpe_function; 52375118Sfenner break; 52475118Sfenner case MAC_UPDATE_DEVFSDIRENT: 52575118Sfenner mpc->mpc_ops->mpo_update_devfsdirent = 52675118Sfenner mpe->mpe_function; 52775118Sfenner break; 52856896Sfenner case MAC_UPDATE_PROCFSVNODE: 52956896Sfenner mpc->mpc_ops->mpo_update_procfsvnode = 53056896Sfenner mpe->mpe_function; 53156896Sfenner break; 53275118Sfenner case MAC_UPDATE_VNODE_FROM_EXTATTR: 53375118Sfenner mpc->mpc_ops->mpo_update_vnode_from_extattr = 534172686Smlaier mpe->mpe_function; 535172686Smlaier break; 53675118Sfenner case MAC_UPDATE_VNODE_FROM_EXTERNALIZED: 53775118Sfenner mpc->mpc_ops->mpo_update_vnode_from_externalized = 53817680Spst mpe->mpe_function; 53998527Sfenner break; 54098527Sfenner case MAC_UPDATE_VNODE_FROM_MOUNT: 54198527Sfenner mpc->mpc_ops->mpo_update_vnode_from_mount = 54298527Sfenner mpe->mpe_function; 54398527Sfenner break; 54498527Sfenner case MAC_CREATE_MBUF_FROM_SOCKET: 54598527Sfenner mpc->mpc_ops->mpo_create_mbuf_from_socket = 54698527Sfenner mpe->mpe_function; 54775118Sfenner break; 54875118Sfenner case MAC_CREATE_PIPE: 54998527Sfenner mpc->mpc_ops->mpo_create_pipe = 55098527Sfenner mpe->mpe_function; 55198527Sfenner break; 55298527Sfenner case MAC_CREATE_SOCKET: 55398527Sfenner mpc->mpc_ops->mpo_create_socket = 55498527Sfenner mpe->mpe_function; 55598527Sfenner break; 55698527Sfenner case MAC_CREATE_SOCKET_FROM_SOCKET: 55798527Sfenner mpc->mpc_ops->mpo_create_socket_from_socket = 55898527Sfenner mpe->mpe_function; 55998527Sfenner break; 56098527Sfenner case MAC_RELABEL_PIPE: 56198527Sfenner mpc->mpc_ops->mpo_relabel_pipe = 56298527Sfenner mpe->mpe_function; 56398527Sfenner break; 56498527Sfenner case MAC_RELABEL_SOCKET: 56598527Sfenner mpc->mpc_ops->mpo_relabel_socket = 56698527Sfenner mpe->mpe_function; 56798527Sfenner break; 56898527Sfenner case MAC_SET_SOCKET_PEER_FROM_MBUF: 56998527Sfenner mpc->mpc_ops->mpo_set_socket_peer_from_mbuf = 57098527Sfenner mpe->mpe_function; 57198527Sfenner break; 57298527Sfenner case MAC_SET_SOCKET_PEER_FROM_SOCKET: 57398527Sfenner mpc->mpc_ops->mpo_set_socket_peer_from_socket = 57498527Sfenner mpe->mpe_function; 57598527Sfenner break; 57617680Spst case MAC_CREATE_BPFDESC: 57726183Sfenner mpc->mpc_ops->mpo_create_bpfdesc = 57817680Spst mpe->mpe_function; 57917680Spst break; 58017680Spst case MAC_CREATE_DATAGRAM_FROM_IPQ: 581127675Sbms mpc->mpc_ops->mpo_create_datagram_from_ipq = 58217680Spst mpe->mpe_function; 58317680Spst break; 58417680Spst case MAC_CREATE_FRAGMENT: 58598527Sfenner mpc->mpc_ops->mpo_create_fragment = 586127675Sbms mpe->mpe_function; 58717680Spst break; 58817680Spst case MAC_CREATE_IFNET: 58980234Sfenner mpc->mpc_ops->mpo_create_ifnet = 59017680Spst mpe->mpe_function; 591127675Sbms break; 592127675Sbms case MAC_CREATE_IPQ: 593127675Sbms mpc->mpc_ops->mpo_create_ipq = 594127675Sbms mpe->mpe_function; 59517680Spst break; 59675118Sfenner case MAC_CREATE_MBUF_FROM_MBUF: 59717680Spst mpc->mpc_ops->mpo_create_mbuf_from_mbuf = 598172686Smlaier mpe->mpe_function; 599127675Sbms break; 60075118Sfenner case MAC_CREATE_MBUF_LINKLAYER: 60175118Sfenner mpc->mpc_ops->mpo_create_mbuf_linklayer = 60275118Sfenner mpe->mpe_function; 60375118Sfenner break; 60475118Sfenner case MAC_CREATE_MBUF_FROM_BPFDESC: 605127675Sbms mpc->mpc_ops->mpo_create_mbuf_from_bpfdesc = 60675118Sfenner mpe->mpe_function; 60717680Spst break; 60817680Spst case MAC_CREATE_MBUF_FROM_IFNET: 60917680Spst mpc->mpc_ops->mpo_create_mbuf_from_ifnet = 61098527Sfenner mpe->mpe_function; 61198527Sfenner break; 612127675Sbms case MAC_CREATE_MBUF_MULTICAST_ENCAP: 61398527Sfenner mpc->mpc_ops->mpo_create_mbuf_multicast_encap = 61498527Sfenner mpe->mpe_function; 61598527Sfenner break; 616127675Sbms case MAC_CREATE_MBUF_NETLAYER: 61798527Sfenner mpc->mpc_ops->mpo_create_mbuf_netlayer = 61898527Sfenner mpe->mpe_function; 619127675Sbms break; 62098527Sfenner case MAC_FRAGMENT_MATCH: 62198527Sfenner mpc->mpc_ops->mpo_fragment_match = 62298527Sfenner mpe->mpe_function; 62375118Sfenner break; 62417680Spst case MAC_RELABEL_IFNET: 62517680Spst mpc->mpc_ops->mpo_relabel_ifnet = 626127675Sbms mpe->mpe_function; 62775118Sfenner break; 62898527Sfenner case MAC_UPDATE_IPQ: 62917680Spst mpc->mpc_ops->mpo_update_ipq = 630127675Sbms mpe->mpe_function; 63175118Sfenner break; 63217680Spst case MAC_CREATE_CRED: 63317680Spst mpc->mpc_ops->mpo_create_cred = 63498527Sfenner mpe->mpe_function; 63598527Sfenner break; 63675118Sfenner case MAC_EXECVE_TRANSITION: 63775118Sfenner mpc->mpc_ops->mpo_execve_transition = 63898527Sfenner mpe->mpe_function; 63975118Sfenner break; 640127675Sbms case MAC_EXECVE_WILL_TRANSITION: 64175118Sfenner mpc->mpc_ops->mpo_execve_will_transition = 64298527Sfenner mpe->mpe_function; 64375118Sfenner break; 644127675Sbms case MAC_CREATE_PROC0: 64575118Sfenner mpc->mpc_ops->mpo_create_proc0 = mpe->mpe_function; 64675118Sfenner break; 64775118Sfenner case MAC_CREATE_PROC1: 64898527Sfenner mpc->mpc_ops->mpo_create_proc1 = mpe->mpe_function; 64998527Sfenner break; 65098527Sfenner case MAC_RELABEL_CRED: 65175118Sfenner mpc->mpc_ops->mpo_relabel_cred = 652127675Sbms mpe->mpe_function; 65375118Sfenner break; 65498527Sfenner case MAC_CHECK_BPFDESC_RECEIVE: 65575118Sfenner mpc->mpc_ops->mpo_check_bpfdesc_receive = 656127675Sbms mpe->mpe_function; 65775118Sfenner break; 65875118Sfenner case MAC_CHECK_CRED_RELABEL: 65975118Sfenner mpc->mpc_ops->mpo_check_cred_relabel = 66098527Sfenner mpe->mpe_function; 66198527Sfenner break; 66275118Sfenner case MAC_CHECK_CRED_VISIBLE: 66317680Spst mpc->mpc_ops->mpo_check_cred_visible = 66417680Spst mpe->mpe_function; 66517680Spst break; 666172686Smlaier case MAC_CHECK_IFNET_RELABEL: 66775118Sfenner mpc->mpc_ops->mpo_check_ifnet_relabel = 668127675Sbms mpe->mpe_function; 66917680Spst break; 67017680Spst case MAC_CHECK_IFNET_TRANSMIT: 671127675Sbms mpc->mpc_ops->mpo_check_ifnet_transmit = 672127675Sbms mpe->mpe_function; 673127675Sbms break; 67417680Spst case MAC_CHECK_MOUNT_STAT: 67575118Sfenner mpc->mpc_ops->mpo_check_mount_stat = 67617680Spst mpe->mpe_function; 67717680Spst break; 67817680Spst case MAC_CHECK_PIPE_IOCTL: 67917680Spst mpc->mpc_ops->mpo_check_pipe_ioctl = 68017680Spst mpe->mpe_function; 68117680Spst break; 68217680Spst case MAC_CHECK_PIPE_POLL: 68317680Spst mpc->mpc_ops->mpo_check_pipe_poll = 68417680Spst mpe->mpe_function; 68517680Spst break; 68617680Spst case MAC_CHECK_PIPE_READ: 68717680Spst mpc->mpc_ops->mpo_check_pipe_read = 68817680Spst mpe->mpe_function; 68917680Spst break; 69017680Spst case MAC_CHECK_PIPE_RELABEL: 69117680Spst mpc->mpc_ops->mpo_check_pipe_relabel = 69298527Sfenner mpe->mpe_function; 69375118Sfenner break; 694127675Sbms case MAC_CHECK_PIPE_STAT: 69575118Sfenner mpc->mpc_ops->mpo_check_pipe_stat = 69675118Sfenner mpe->mpe_function; 69798527Sfenner break; 69875118Sfenner case MAC_CHECK_PIPE_WRITE: 699127675Sbms mpc->mpc_ops->mpo_check_pipe_write = 700127675Sbms mpe->mpe_function; 70175118Sfenner break; 70275118Sfenner case MAC_CHECK_PROC_DEBUG: 70375118Sfenner mpc->mpc_ops->mpo_check_proc_debug = 70475118Sfenner mpe->mpe_function; 70598527Sfenner break; 70698527Sfenner case MAC_CHECK_PROC_SCHED: 70775118Sfenner mpc->mpc_ops->mpo_check_proc_sched = 70875118Sfenner mpe->mpe_function; 70975118Sfenner break; 71075118Sfenner case MAC_CHECK_PROC_SIGNAL: 711127675Sbms mpc->mpc_ops->mpo_check_proc_signal = 71275118Sfenner mpe->mpe_function; 71398527Sfenner break; 71475118Sfenner case MAC_CHECK_SOCKET_BIND: 715127675Sbms mpc->mpc_ops->mpo_check_socket_bind = 71675118Sfenner mpe->mpe_function; 71775118Sfenner break; 71875118Sfenner case MAC_CHECK_SOCKET_CONNECT: 71998527Sfenner mpc->mpc_ops->mpo_check_socket_connect = 72098527Sfenner mpe->mpe_function; 72198527Sfenner break; 72275118Sfenner case MAC_CHECK_SOCKET_DELIVER: 723127675Sbms mpc->mpc_ops->mpo_check_socket_deliver = 72475118Sfenner mpe->mpe_function; 72575118Sfenner break; 72675118Sfenner case MAC_CHECK_SOCKET_LISTEN: 727127675Sbms mpc->mpc_ops->mpo_check_socket_listen = 72875118Sfenner mpe->mpe_function; 72975118Sfenner break; 73075118Sfenner case MAC_CHECK_SOCKET_RELABEL: 73198527Sfenner mpc->mpc_ops->mpo_check_socket_relabel = 73298527Sfenner mpe->mpe_function; 73398527Sfenner break; 73475118Sfenner case MAC_CHECK_SOCKET_VISIBLE: 735127675Sbms mpc->mpc_ops->mpo_check_socket_visible = 73675118Sfenner mpe->mpe_function; 73798527Sfenner break; 73875118Sfenner case MAC_CHECK_VNODE_ACCESS: 739127675Sbms mpc->mpc_ops->mpo_check_vnode_access = 74075118Sfenner mpe->mpe_function; 74175118Sfenner break; 74275118Sfenner case MAC_CHECK_VNODE_CHDIR: 74398527Sfenner mpc->mpc_ops->mpo_check_vnode_chdir = 74498527Sfenner mpe->mpe_function; 74575118Sfenner break; 74617680Spst case MAC_CHECK_VNODE_CHROOT: 74717680Spst mpc->mpc_ops->mpo_check_vnode_chroot = 74875118Sfenner mpe->mpe_function; 74975118Sfenner break; 75075118Sfenner case MAC_CHECK_VNODE_CREATE: 75175118Sfenner mpc->mpc_ops->mpo_check_vnode_create = 75275118Sfenner mpe->mpe_function; 75317680Spst break; 754 case MAC_CHECK_VNODE_DELETE: 755 mpc->mpc_ops->mpo_check_vnode_delete = 756 mpe->mpe_function; 757 break; 758 case MAC_CHECK_VNODE_DELETEACL: 759 mpc->mpc_ops->mpo_check_vnode_deleteacl = 760 mpe->mpe_function; 761 break; 762 case MAC_CHECK_VNODE_EXEC: 763 mpc->mpc_ops->mpo_check_vnode_exec = 764 mpe->mpe_function; 765 break; 766 case MAC_CHECK_VNODE_GETACL: 767 mpc->mpc_ops->mpo_check_vnode_getacl = 768 mpe->mpe_function; 769 break; 770 case MAC_CHECK_VNODE_GETEXTATTR: 771 mpc->mpc_ops->mpo_check_vnode_getextattr = 772 mpe->mpe_function; 773 break; 774 case MAC_CHECK_VNODE_LOOKUP: 775 mpc->mpc_ops->mpo_check_vnode_lookup = 776 mpe->mpe_function; 777 break; 778 case MAC_CHECK_VNODE_MMAP_PERMS: 779 mpc->mpc_ops->mpo_check_vnode_mmap_perms = 780 mpe->mpe_function; 781 break; 782 case MAC_CHECK_VNODE_OPEN: 783 mpc->mpc_ops->mpo_check_vnode_open = 784 mpe->mpe_function; 785 break; 786 case MAC_CHECK_VNODE_POLL: 787 mpc->mpc_ops->mpo_check_vnode_poll = 788 mpe->mpe_function; 789 break; 790 case MAC_CHECK_VNODE_READ: 791 mpc->mpc_ops->mpo_check_vnode_read = 792 mpe->mpe_function; 793 break; 794 case MAC_CHECK_VNODE_READDIR: 795 mpc->mpc_ops->mpo_check_vnode_readdir = 796 mpe->mpe_function; 797 break; 798 case MAC_CHECK_VNODE_READLINK: 799 mpc->mpc_ops->mpo_check_vnode_readlink = 800 mpe->mpe_function; 801 break; 802 case MAC_CHECK_VNODE_RELABEL: 803 mpc->mpc_ops->mpo_check_vnode_relabel = 804 mpe->mpe_function; 805 break; 806 case MAC_CHECK_VNODE_RENAME_FROM: 807 mpc->mpc_ops->mpo_check_vnode_rename_from = 808 mpe->mpe_function; 809 break; 810 case MAC_CHECK_VNODE_RENAME_TO: 811 mpc->mpc_ops->mpo_check_vnode_rename_to = 812 mpe->mpe_function; 813 break; 814 case MAC_CHECK_VNODE_REVOKE: 815 mpc->mpc_ops->mpo_check_vnode_revoke = 816 mpe->mpe_function; 817 break; 818 case MAC_CHECK_VNODE_SETACL: 819 mpc->mpc_ops->mpo_check_vnode_setacl = 820 mpe->mpe_function; 821 break; 822 case MAC_CHECK_VNODE_SETEXTATTR: 823 mpc->mpc_ops->mpo_check_vnode_setextattr = 824 mpe->mpe_function; 825 break; 826 case MAC_CHECK_VNODE_SETFLAGS: 827 mpc->mpc_ops->mpo_check_vnode_setflags = 828 mpe->mpe_function; 829 break; 830 case MAC_CHECK_VNODE_SETMODE: 831 mpc->mpc_ops->mpo_check_vnode_setmode = 832 mpe->mpe_function; 833 break; 834 case MAC_CHECK_VNODE_SETOWNER: 835 mpc->mpc_ops->mpo_check_vnode_setowner = 836 mpe->mpe_function; 837 break; 838 case MAC_CHECK_VNODE_SETUTIMES: 839 mpc->mpc_ops->mpo_check_vnode_setutimes = 840 mpe->mpe_function; 841 break; 842 case MAC_CHECK_VNODE_STAT: 843 mpc->mpc_ops->mpo_check_vnode_stat = 844 mpe->mpe_function; 845 break; 846 case MAC_CHECK_VNODE_WRITE: 847 mpc->mpc_ops->mpo_check_vnode_write = 848 mpe->mpe_function; 849 break; 850/* 851 default: 852 printf("MAC policy `%s': unknown operation %d\n", 853 mpc->mpc_name, mpe->mpe_constant); 854 return (EINVAL); 855*/ 856 } 857 } 858 MAC_POLICY_LIST_LOCK(); 859 if (mac_policy_list_busy > 0) { 860 MAC_POLICY_LIST_UNLOCK(); 861 FREE(mpc->mpc_ops, M_MACOPVEC); 862 mpc->mpc_ops = NULL; 863 return (EBUSY); 864 } 865 LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 866 if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 867 MAC_POLICY_LIST_UNLOCK(); 868 FREE(mpc->mpc_ops, M_MACOPVEC); 869 mpc->mpc_ops = NULL; 870 return (EEXIST); 871 } 872 } 873 if (mpc->mpc_field_off != NULL) { 874 slot = ffs(mac_policy_offsets_free); 875 if (slot == 0) { 876 MAC_POLICY_LIST_UNLOCK(); 877 FREE(mpc->mpc_ops, M_MACOPVEC); 878 mpc->mpc_ops = NULL; 879 return (ENOMEM); 880 } 881 slot--; 882 mac_policy_offsets_free &= ~(1 << slot); 883 *mpc->mpc_field_off = slot; 884 } 885 mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; 886 LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); 887 888 /* Per-policy initialization. */ 889 if (mpc->mpc_ops->mpo_init != NULL) 890 (*(mpc->mpc_ops->mpo_init))(mpc); 891 MAC_POLICY_LIST_UNLOCK(); 892 893 printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, 894 mpc->mpc_name); 895 896 return (0); 897} 898 899static int 900mac_policy_unregister(struct mac_policy_conf *mpc) 901{ 902 903#if 0 904 /* 905 * Don't allow unloading modules with private data. 906 */ 907 if (mpc->mpc_field_off != NULL) 908 return (EBUSY); 909#endif 910 if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) 911 return (EBUSY); 912 MAC_POLICY_LIST_LOCK(); 913 if (mac_policy_list_busy > 0) { 914 MAC_POLICY_LIST_UNLOCK(); 915 return (EBUSY); 916 } 917 if (mpc->mpc_ops->mpo_destroy != NULL) 918 (*(mpc->mpc_ops->mpo_destroy))(mpc); 919 920 LIST_REMOVE(mpc, mpc_list); 921 MAC_POLICY_LIST_UNLOCK(); 922 923 FREE(mpc->mpc_ops, M_MACOPVEC); 924 mpc->mpc_ops = NULL; 925 926 printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, 927 mpc->mpc_name); 928 929 return (0); 930} 931 932/* 933 * Define an error value precedence, and given two arguments, selects the 934 * value with the higher precedence. 935 */ 936static int 937error_select(int error1, int error2) 938{ 939 940 /* Certain decision-making errors take top priority. */ 941 if (error1 == EDEADLK || error2 == EDEADLK) 942 return (EDEADLK); 943 944 /* Invalid arguments should be reported where possible. */ 945 if (error1 == EINVAL || error2 == EINVAL) 946 return (EINVAL); 947 948 /* Precedence goes to "visibility", with both process and file. */ 949 if (error1 == ESRCH || error2 == ESRCH) 950 return (ESRCH); 951 952 if (error1 == ENOENT || error2 == ENOENT) 953 return (ENOENT); 954 955 /* Precedence goes to DAC/MAC protections. */ 956 if (error1 == EACCES || error2 == EACCES) 957 return (EACCES); 958 959 /* Precedence goes to privilege. */ 960 if (error1 == EPERM || error2 == EPERM) 961 return (EPERM); 962 963 /* Precedence goes to error over success; otherwise, arbitrary. */ 964 if (error1 != 0) 965 return (error1); 966 return (error2); 967} 968 969void 970mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp) 971{ 972 973 MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label); 974} 975 976void 977mac_update_procfsvnode(struct vnode *vp, struct ucred *cred) 978{ 979 980 MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred); 981} 982 983/* 984 * Support callout for policies that manage their own externalization 985 * using extended attributes. 986 */ 987static int 988mac_update_vnode_from_extattr(struct vnode *vp, struct mount *mp) 989{ 990 int error; 991 992 MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp, 993 &mp->mnt_fslabel); 994 995 return (error); 996} 997 998/* 999 * Given an externalized mac label, internalize it and stamp it on a 1000 * vnode. 1001 */ 1002static int 1003mac_update_vnode_from_externalized(struct vnode *vp, struct mac *extmac) 1004{ 1005 int error; 1006 1007 MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac); 1008 1009 return (error); 1010} 1011 1012/* 1013 * Call out to individual policies to update the label in a vnode from 1014 * the mountpoint. 1015 */ 1016void 1017mac_update_vnode_from_mount(struct vnode *vp, struct mount *mp) 1018{ 1019 1020 MAC_PERFORM(update_vnode_from_mount, vp, &vp->v_label, mp, 1021 &mp->mnt_fslabel); 1022 1023 ASSERT_VOP_LOCKED(vp, "mac_update_vnode_from_mount"); 1024 if (mac_cache_fslabel_in_vnode) 1025 vp->v_vflag |= VV_CACHEDLABEL; 1026} 1027 1028/* 1029 * Implementation of VOP_REFRESHLABEL() that relies on extended attributes 1030 * to store label data. Can be referenced by filesystems supporting 1031 * extended attributes. 1032 */ 1033int 1034vop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap) 1035{ 1036 struct vnode *vp = ap->a_vp; 1037 struct mac extmac; 1038 int buflen, error; 1039 1040 ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea"); 1041 1042 /* 1043 * Call out to external policies first. Order doesn't really 1044 * matter, as long as failure of one assures failure of all. 1045 */ 1046 error = mac_update_vnode_from_extattr(vp, vp->v_mount); 1047 if (error) 1048 return (error); 1049 1050 buflen = sizeof(extmac); 1051 error = vn_extattr_get(vp, IO_NODELOCKED, 1052 FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, &buflen, 1053 (char *)&extmac, curthread); 1054 switch (error) { 1055 case 0: 1056 /* Got it */ 1057 break; 1058 1059 case ENOATTR: 1060 /* 1061 * Use the label from the mount point. 1062 */ 1063 mac_update_vnode_from_mount(vp, vp->v_mount); 1064 return (0); 1065 1066 case EOPNOTSUPP: 1067 default: 1068 /* Fail horribly. */ 1069 return (error); 1070 } 1071 1072 if (buflen != sizeof(extmac)) 1073 error = EPERM; /* Fail very closed. */ 1074 if (error == 0) 1075 error = mac_update_vnode_from_externalized(vp, &extmac); 1076 if (error == 0) 1077 vp->v_vflag |= VV_CACHEDLABEL; 1078 else { 1079 struct vattr va; 1080 1081 printf("Corrupted label on %s", 1082 vp->v_mount->mnt_stat.f_mntonname); 1083 if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread) == 0) 1084 printf(" inum %ld", va.va_fileid); 1085#ifdef MAC_DEBUG 1086 if (mac_debug_label_fallback) { 1087 printf(", falling back.\n"); 1088 mac_update_vnode_from_mount(vp, vp->v_mount); 1089 error = 0; 1090 } else { 1091#endif 1092 printf(".\n"); 1093 error = EPERM; 1094#ifdef MAC_DEBUG 1095 } 1096#endif 1097 } 1098 1099 return (error); 1100} 1101 1102/* 1103 * Make sure the vnode label is up-to-date. If EOPNOTSUPP, then we handle 1104 * the labeling activity outselves. Filesystems should be careful not 1105 * to change their minds regarding whether they support vop_refreshlabel() 1106 * for a vnode or not. Don't cache the vnode here, allow the file 1107 * system code to determine if it's safe to cache. If we update from 1108 * the mount, don't cache since a change to the mount label should affect 1109 * all vnodes. 1110 */ 1111static int 1112vn_refreshlabel(struct vnode *vp, struct ucred *cred) 1113{ 1114 int error; 1115 1116 ASSERT_VOP_LOCKED(vp, "vn_refreshlabel"); 1117 1118 if (vp->v_mount == NULL) { 1119/* 1120 Eventually, we probably want to special-case refreshing 1121 of deadfs vnodes, and if there's a lock-free race somewhere, 1122 that case might be handled here. 1123 1124 mac_update_vnode_deadfs(vp); 1125 return (0); 1126 */ 1127 /* printf("vn_refreshlabel: null v_mount\n"); */ 1128 if (vp->v_type != VNON) 1129 printf( 1130 "vn_refreshlabel: null v_mount with non-VNON\n"); 1131 return (EBADF); 1132 } 1133 1134 if (vp->v_vflag & VV_CACHEDLABEL) { 1135 mac_vnode_label_cache_hits++; 1136 return (0); 1137 } else 1138 mac_vnode_label_cache_misses++; 1139 1140 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) { 1141 mac_update_vnode_from_mount(vp, vp->v_mount); 1142 return (0); 1143 } 1144 1145 error = VOP_REFRESHLABEL(vp, cred, curthread); 1146 switch (error) { 1147 case EOPNOTSUPP: 1148 /* 1149 * If labels are not supported on this vnode, fall back to 1150 * the label in the mount and propagate it to the vnode. 1151 * There should probably be some sort of policy/flag/decision 1152 * about doing this. 1153 */ 1154 mac_update_vnode_from_mount(vp, vp->v_mount); 1155 error = 0; 1156 default: 1157 return (error); 1158 } 1159} 1160 1161/* 1162 * Helper function for file systems using the vop_std*_ea() calls. This 1163 * function must be called after EA service is available for the vnode, 1164 * but before it's hooked up to the namespace so that the node persists 1165 * if there's a crash, or before it can be accessed. On successful 1166 * commit of the label to disk (etc), do cache the label. 1167 */ 1168int 1169vop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp, struct ucred *cred) 1170{ 1171 struct mac extmac; 1172 int error; 1173 1174 ASSERT_VOP_LOCKED(tvp, "vop_stdcreatevnode_ea"); 1175 if ((dvp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) { 1176 mac_update_vnode_from_mount(tvp, tvp->v_mount); 1177 } else { 1178 error = vn_refreshlabel(dvp, cred); 1179 if (error) 1180 return (error); 1181 1182 /* 1183 * Stick the label in the vnode. Then try to write to 1184 * disk. If we fail, return a failure to abort the 1185 * create operation. Really, this failure shouldn't 1186 * happen except in fairly unusual circumstances (out 1187 * of disk, etc). 1188 */ 1189 mac_create_vnode(cred, dvp, tvp); 1190 1191 error = mac_stdcreatevnode_ea(tvp); 1192 if (error) 1193 return (error); 1194 1195 /* 1196 * XXX: Eventually this will go away and all policies will 1197 * directly manage their extended attributes. 1198 */ 1199 error = mac_externalize(&tvp->v_label, &extmac); 1200 if (error) 1201 return (error); 1202 1203 error = vn_extattr_set(tvp, IO_NODELOCKED, 1204 FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, 1205 sizeof(extmac), (char *)&extmac, curthread); 1206 if (error == 0) 1207 tvp->v_vflag |= VV_CACHEDLABEL; 1208 else { 1209#if 0 1210 /* 1211 * In theory, we could have fall-back behavior here. 1212 * It would probably be incorrect. 1213 */ 1214#endif 1215 return (error); 1216 } 1217 } 1218 1219 return (0); 1220} 1221 1222void 1223mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp) 1224{ 1225 int error; 1226 1227 ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1228 1229 error = vn_refreshlabel(vp, old); 1230 if (error) { 1231 printf("mac_execve_transition: vn_refreshlabel returned %d\n", 1232 error); 1233 printf("mac_execve_transition: using old vnode label\n"); 1234 } 1235 1236 MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label); 1237} 1238 1239int 1240mac_execve_will_transition(struct ucred *old, struct vnode *vp) 1241{ 1242 int error, result; 1243 1244 error = vn_refreshlabel(vp, old); 1245 if (error) 1246 return (error); 1247 1248 result = 0; 1249 MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label); 1250 1251 return (result); 1252} 1253 1254static void 1255mac_init_label(struct label *label) 1256{ 1257 1258 bzero(label, sizeof(*label)); 1259 label->l_flags = MAC_FLAG_INITIALIZED; 1260} 1261 1262static void 1263mac_init_structmac(struct mac *mac) 1264{ 1265 1266 bzero(mac, sizeof(*mac)); 1267 mac->m_macflags = MAC_FLAG_INITIALIZED; 1268} 1269 1270static void 1271mac_destroy_label(struct label *label) 1272{ 1273 1274 KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 1275 ("destroying uninitialized label")); 1276 1277 bzero(label, sizeof(*label)); 1278 /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 1279} 1280 1281int 1282mac_init_mbuf(struct mbuf *m, int how) 1283{ 1284 KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf")); 1285 1286 /* "how" is one of M_(TRY|DONT)WAIT */ 1287 mac_init_label(&m->m_pkthdr.label); 1288 MAC_PERFORM(init_mbuf, m, how, &m->m_pkthdr.label); 1289#ifdef MAC_DEBUG 1290 atomic_add_int(&nmacmbufs, 1); 1291#endif 1292 return (0); 1293} 1294 1295void 1296mac_destroy_mbuf(struct mbuf *m) 1297{ 1298 1299 MAC_PERFORM(destroy_mbuf, m, &m->m_pkthdr.label); 1300 mac_destroy_label(&m->m_pkthdr.label); 1301#ifdef MAC_DEBUG 1302 atomic_subtract_int(&nmacmbufs, 1); 1303#endif 1304} 1305 1306void 1307mac_init_cred(struct ucred *cr) 1308{ 1309 1310 mac_init_label(&cr->cr_label); 1311 MAC_PERFORM(init_cred, cr, &cr->cr_label); 1312#ifdef MAC_DEBUG 1313 atomic_add_int(&nmaccreds, 1); 1314#endif 1315} 1316 1317void 1318mac_destroy_cred(struct ucred *cr) 1319{ 1320 1321 MAC_PERFORM(destroy_cred, cr, &cr->cr_label); 1322 mac_destroy_label(&cr->cr_label); 1323#ifdef MAC_DEBUG 1324 atomic_subtract_int(&nmaccreds, 1); 1325#endif 1326} 1327 1328void 1329mac_init_ifnet(struct ifnet *ifp) 1330{ 1331 1332 mac_init_label(&ifp->if_label); 1333 MAC_PERFORM(init_ifnet, ifp, &ifp->if_label); 1334#ifdef MAC_DEBUG 1335 atomic_add_int(&nmacifnets, 1); 1336#endif 1337} 1338 1339void 1340mac_destroy_ifnet(struct ifnet *ifp) 1341{ 1342 1343 MAC_PERFORM(destroy_ifnet, ifp, &ifp->if_label); 1344 mac_destroy_label(&ifp->if_label); 1345#ifdef MAC_DEBUG 1346 atomic_subtract_int(&nmacifnets, 1); 1347#endif 1348} 1349 1350void 1351mac_init_ipq(struct ipq *ipq) 1352{ 1353 1354 mac_init_label(&ipq->ipq_label); 1355 MAC_PERFORM(init_ipq, ipq, &ipq->ipq_label); 1356#ifdef MAC_DEBUG 1357 atomic_add_int(&nmacipqs, 1); 1358#endif 1359} 1360 1361void 1362mac_destroy_ipq(struct ipq *ipq) 1363{ 1364 1365 MAC_PERFORM(destroy_ipq, ipq, &ipq->ipq_label); 1366 mac_destroy_label(&ipq->ipq_label); 1367#ifdef MAC_DEBUG 1368 atomic_subtract_int(&nmacipqs, 1); 1369#endif 1370} 1371 1372void 1373mac_init_socket(struct socket *socket) 1374{ 1375 1376 mac_init_label(&socket->so_label); 1377 mac_init_label(&socket->so_peerlabel); 1378 MAC_PERFORM(init_socket, socket, &socket->so_label, 1379 &socket->so_peerlabel); 1380#ifdef MAC_DEBUG 1381 atomic_add_int(&nmacsockets, 1); 1382#endif 1383} 1384 1385void 1386mac_destroy_socket(struct socket *socket) 1387{ 1388 1389 MAC_PERFORM(destroy_socket, socket, &socket->so_label, 1390 &socket->so_peerlabel); 1391 mac_destroy_label(&socket->so_label); 1392 mac_destroy_label(&socket->so_peerlabel); 1393#ifdef MAC_DEBUG 1394 atomic_subtract_int(&nmacsockets, 1); 1395#endif 1396} 1397 1398void 1399mac_init_pipe(struct pipe *pipe) 1400{ 1401 struct label *label; 1402 1403 label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 1404 mac_init_label(label); 1405 pipe->pipe_label = label; 1406 pipe->pipe_peer->pipe_label = label; 1407 MAC_PERFORM(init_pipe, pipe, pipe->pipe_label); 1408#ifdef MAC_DEBUG 1409 atomic_add_int(&nmacpipes, 1); 1410#endif 1411} 1412 1413void 1414mac_destroy_pipe(struct pipe *pipe) 1415{ 1416 1417 MAC_PERFORM(destroy_pipe, pipe, pipe->pipe_label); 1418 mac_destroy_label(pipe->pipe_label); 1419 free(pipe->pipe_label, M_MACPIPELABEL); 1420#ifdef MAC_DEBUG 1421 atomic_subtract_int(&nmacpipes, 1); 1422#endif 1423} 1424 1425void 1426mac_init_bpfdesc(struct bpf_d *bpf_d) 1427{ 1428 1429 mac_init_label(&bpf_d->bd_label); 1430 MAC_PERFORM(init_bpfdesc, bpf_d, &bpf_d->bd_label); 1431#ifdef MAC_DEBUG 1432 atomic_add_int(&nmacbpfdescs, 1); 1433#endif 1434} 1435 1436void 1437mac_destroy_bpfdesc(struct bpf_d *bpf_d) 1438{ 1439 1440 MAC_PERFORM(destroy_bpfdesc, bpf_d, &bpf_d->bd_label); 1441 mac_destroy_label(&bpf_d->bd_label); 1442#ifdef MAC_DEBUG 1443 atomic_subtract_int(&nmacbpfdescs, 1); 1444#endif 1445} 1446 1447void 1448mac_init_mount(struct mount *mp) 1449{ 1450 1451 mac_init_label(&mp->mnt_mntlabel); 1452 mac_init_label(&mp->mnt_fslabel); 1453 MAC_PERFORM(init_mount, mp, &mp->mnt_mntlabel, &mp->mnt_fslabel); 1454#ifdef MAC_DEBUG 1455 atomic_add_int(&nmacmounts, 1); 1456#endif 1457} 1458 1459void 1460mac_destroy_mount(struct mount *mp) 1461{ 1462 1463 MAC_PERFORM(destroy_mount, mp, &mp->mnt_mntlabel, &mp->mnt_fslabel); 1464 mac_destroy_label(&mp->mnt_fslabel); 1465 mac_destroy_label(&mp->mnt_mntlabel); 1466#ifdef MAC_DEBUG 1467 atomic_subtract_int(&nmacmounts, 1); 1468#endif 1469} 1470 1471static void 1472mac_init_temp(struct label *label) 1473{ 1474 1475 mac_init_label(label); 1476 MAC_PERFORM(init_temp, label); 1477#ifdef MAC_DEBUG 1478 atomic_add_int(&nmactemp, 1); 1479#endif 1480} 1481 1482static void 1483mac_destroy_temp(struct label *label) 1484{ 1485 1486 MAC_PERFORM(destroy_temp, label); 1487 mac_destroy_label(label); 1488#ifdef MAC_DEBUG 1489 atomic_subtract_int(&nmactemp, 1); 1490#endif 1491} 1492 1493void 1494mac_init_vnode(struct vnode *vp) 1495{ 1496 1497 mac_init_label(&vp->v_label); 1498 MAC_PERFORM(init_vnode, vp, &vp->v_label); 1499#ifdef MAC_DEBUG 1500 atomic_add_int(&nmacvnodes, 1); 1501#endif 1502} 1503 1504void 1505mac_destroy_vnode(struct vnode *vp) 1506{ 1507 1508 MAC_PERFORM(destroy_vnode, vp, &vp->v_label); 1509 mac_destroy_label(&vp->v_label); 1510#ifdef MAC_DEBUG 1511 atomic_subtract_int(&nmacvnodes, 1); 1512#endif 1513} 1514 1515void 1516mac_init_devfsdirent(struct devfs_dirent *de) 1517{ 1518 1519 mac_init_label(&de->de_label); 1520 MAC_PERFORM(init_devfsdirent, de, &de->de_label); 1521#ifdef MAC_DEBUG 1522 atomic_add_int(&nmacdevfsdirents, 1); 1523#endif 1524} 1525 1526void 1527mac_destroy_devfsdirent(struct devfs_dirent *de) 1528{ 1529 1530 MAC_PERFORM(destroy_devfsdirent, de, &de->de_label); 1531 mac_destroy_label(&de->de_label); 1532#ifdef MAC_DEBUG 1533 atomic_subtract_int(&nmacdevfsdirents, 1); 1534#endif 1535} 1536 1537static int 1538mac_externalize(struct label *label, struct mac *mac) 1539{ 1540 int error; 1541 1542 mac_init_structmac(mac); 1543 MAC_CHECK(externalize, label, mac); 1544 1545 return (error); 1546} 1547 1548static int 1549mac_internalize(struct label *label, struct mac *mac) 1550{ 1551 int error; 1552 1553 mac_init_temp(label); 1554 MAC_CHECK(internalize, label, mac); 1555 if (error) 1556 mac_destroy_temp(label); 1557 1558 return (error); 1559} 1560 1561/* 1562 * Initialize MAC label for the first kernel process, from which other 1563 * kernel processes and threads are spawned. 1564 */ 1565void 1566mac_create_proc0(struct ucred *cred) 1567{ 1568 1569 MAC_PERFORM(create_proc0, cred); 1570} 1571 1572/* 1573 * Initialize MAC label for the first userland process, from which other 1574 * userland processes and threads are spawned. 1575 */ 1576void 1577mac_create_proc1(struct ucred *cred) 1578{ 1579 1580 MAC_PERFORM(create_proc1, cred); 1581} 1582 1583/* 1584 * When a new process is created, its label must be initialized. Generally, 1585 * this involves inheritence from the parent process, modulo possible 1586 * deltas. This function allows that processing to take place. 1587 */ 1588void 1589mac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 1590{ 1591 1592 MAC_PERFORM(create_cred, parent_cred, child_cred); 1593} 1594 1595int 1596mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags) 1597{ 1598 int error; 1599 1600 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1601 1602 if (!mac_enforce_fs) 1603 return (0); 1604 1605 error = vn_refreshlabel(vp, cred); 1606 if (error) 1607 return (error); 1608 1609 MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags); 1610 return (error); 1611} 1612 1613int 1614mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 1615{ 1616 int error; 1617 1618 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 1619 1620 if (!mac_enforce_fs) 1621 return (0); 1622 1623 error = vn_refreshlabel(dvp, cred); 1624 if (error) 1625 return (error); 1626 1627 MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 1628 return (error); 1629} 1630 1631int 1632mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 1633{ 1634 int error; 1635 1636 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 1637 1638 if (!mac_enforce_fs) 1639 return (0); 1640 1641 error = vn_refreshlabel(dvp, cred); 1642 if (error) 1643 return (error); 1644 1645 MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1646 return (error); 1647} 1648 1649int 1650mac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1651 struct componentname *cnp, struct vattr *vap) 1652{ 1653 int error; 1654 1655 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1656 1657 if (!mac_enforce_fs) 1658 return (0); 1659 1660 error = vn_refreshlabel(dvp, cred); 1661 if (error) 1662 return (error); 1663 1664 MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 1665 return (error); 1666} 1667 1668int 1669mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 1670 struct componentname *cnp) 1671{ 1672 int error; 1673 1674 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 1675 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 1676 1677 if (!mac_enforce_fs) 1678 return (0); 1679 1680 error = vn_refreshlabel(dvp, cred); 1681 if (error) 1682 return (error); 1683 error = vn_refreshlabel(vp, cred); 1684 if (error) 1685 return (error); 1686 1687 MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1688 &vp->v_label, cnp); 1689 return (error); 1690} 1691 1692int 1693mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1694 acl_type_t type) 1695{ 1696 int error; 1697 1698 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1699 1700 if (!mac_enforce_fs) 1701 return (0); 1702 1703 error = vn_refreshlabel(vp, cred); 1704 if (error) 1705 return (error); 1706 1707 MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1708 return (error); 1709} 1710 1711int 1712mac_check_vnode_exec(struct ucred *cred, struct vnode *vp) 1713{ 1714 int error; 1715 1716 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1717 1718 if (!mac_enforce_process && !mac_enforce_fs) 1719 return (0); 1720 1721 error = vn_refreshlabel(vp, cred); 1722 if (error) 1723 return (error); 1724 MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label); 1725 1726 return (error); 1727} 1728 1729int 1730mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1731{ 1732 int error; 1733 1734 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1735 1736 if (!mac_enforce_fs) 1737 return (0); 1738 1739 error = vn_refreshlabel(vp, cred); 1740 if (error) 1741 return (error); 1742 1743 MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1744 return (error); 1745} 1746 1747int 1748mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1749 int attrnamespace, const char *name, struct uio *uio) 1750{ 1751 int error; 1752 1753 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1754 1755 if (!mac_enforce_fs) 1756 return (0); 1757 1758 error = vn_refreshlabel(vp, cred); 1759 if (error) 1760 return (error); 1761 1762 MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1763 attrnamespace, name, uio); 1764 return (error); 1765} 1766 1767int 1768mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1769 struct componentname *cnp) 1770{ 1771 int error; 1772 1773 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 1774 1775 if (!mac_enforce_fs) 1776 return (0); 1777 1778 error = vn_refreshlabel(dvp, cred); 1779 if (error) 1780 return (error); 1781 1782 MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 1783 return (error); 1784} 1785 1786vm_prot_t 1787mac_check_vnode_mmap_prot(struct ucred *cred, struct vnode *vp, int newmapping) 1788{ 1789 vm_prot_t result = VM_PROT_ALL; 1790 1791 if (!mac_enforce_vm) 1792 return (result); 1793 1794 /* 1795 * This should be some sort of MAC_BITWISE, maybe :) 1796 */ 1797 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_perms"); 1798 MAC_BOOLEAN(check_vnode_mmap_perms, &, cred, vp, &vp->v_label, 1799 newmapping); 1800 return (result); 1801} 1802 1803int 1804mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode) 1805{ 1806 int error; 1807 1808 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 1809 1810 if (!mac_enforce_fs) 1811 return (0); 1812 1813 error = vn_refreshlabel(vp, cred); 1814 if (error) 1815 return (error); 1816 1817 MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 1818 return (error); 1819} 1820 1821int 1822mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1823 struct vnode *vp) 1824{ 1825 int error; 1826 1827 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 1828 1829 if (!mac_enforce_fs) 1830 return (0); 1831 1832 error = vn_refreshlabel(vp, active_cred); 1833 if (error) 1834 return (error); 1835 1836 MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 1837 &vp->v_label); 1838 1839 return (error); 1840} 1841 1842int 1843mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1844 struct vnode *vp) 1845{ 1846 int error; 1847 1848 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 1849 1850 if (!mac_enforce_fs) 1851 return (0); 1852 1853 error = vn_refreshlabel(vp, active_cred); 1854 if (error) 1855 return (error); 1856 1857 MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 1858 &vp->v_label); 1859 1860 return (error); 1861} 1862 1863int 1864mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 1865{ 1866 int error; 1867 1868 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 1869 1870 if (!mac_enforce_fs) 1871 return (0); 1872 1873 error = vn_refreshlabel(dvp, cred); 1874 if (error) 1875 return (error); 1876 1877 MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 1878 return (error); 1879} 1880 1881int 1882mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 1883{ 1884 int error; 1885 1886 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 1887 1888 if (!mac_enforce_fs) 1889 return (0); 1890 1891 error = vn_refreshlabel(vp, cred); 1892 if (error) 1893 return (error); 1894 1895 MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 1896 return (error); 1897} 1898 1899static int 1900mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1901 struct label *newlabel) 1902{ 1903 int error; 1904 1905 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 1906 1907 error = vn_refreshlabel(vp, cred); 1908 if (error) 1909 return (error); 1910 1911 MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 1912 1913 return (error); 1914} 1915 1916int 1917mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1918 struct vnode *vp, struct componentname *cnp) 1919{ 1920 int error; 1921 1922 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 1923 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 1924 1925 if (!mac_enforce_fs) 1926 return (0); 1927 1928 error = vn_refreshlabel(dvp, cred); 1929 if (error) 1930 return (error); 1931 error = vn_refreshlabel(vp, cred); 1932 if (error) 1933 return (error); 1934 1935 MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 1936 &vp->v_label, cnp); 1937 return (error); 1938} 1939 1940int 1941mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1942 struct vnode *vp, int samedir, struct componentname *cnp) 1943{ 1944 int error; 1945 1946 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 1947 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 1948 1949 if (!mac_enforce_fs) 1950 return (0); 1951 1952 error = vn_refreshlabel(dvp, cred); 1953 if (error) 1954 return (error); 1955 if (vp != NULL) { 1956 error = vn_refreshlabel(vp, cred); 1957 if (error) 1958 return (error); 1959 } 1960 MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 1961 vp != NULL ? &vp->v_label : NULL, samedir, cnp); 1962 return (error); 1963} 1964 1965int 1966mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 1967{ 1968 int error; 1969 1970 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 1971 1972 if (!mac_enforce_fs) 1973 return (0); 1974 1975 error = vn_refreshlabel(vp, cred); 1976 if (error) 1977 return (error); 1978 1979 MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 1980 return (error); 1981} 1982 1983int 1984mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 1985 struct acl *acl) 1986{ 1987 int error; 1988 1989 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 1990 1991 if (!mac_enforce_fs) 1992 return (0); 1993 1994 error = vn_refreshlabel(vp, cred); 1995 if (error) 1996 return (error); 1997 1998 MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 1999 return (error); 2000} 2001 2002int 2003mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2004 int attrnamespace, const char *name, struct uio *uio) 2005{ 2006 int error; 2007 2008 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 2009 2010 if (!mac_enforce_fs) 2011 return (0); 2012 2013 error = vn_refreshlabel(vp, cred); 2014 if (error) 2015 return (error); 2016 2017 MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 2018 attrnamespace, name, uio); 2019 return (error); 2020} 2021 2022int 2023mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 2024{ 2025 int error; 2026 2027 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 2028 2029 if (!mac_enforce_fs) 2030 return (0); 2031 2032 error = vn_refreshlabel(vp, cred); 2033 if (error) 2034 return (error); 2035 2036 MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 2037 return (error); 2038} 2039 2040int 2041mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 2042{ 2043 int error; 2044 2045 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 2046 2047 if (!mac_enforce_fs) 2048 return (0); 2049 2050 error = vn_refreshlabel(vp, cred); 2051 if (error) 2052 return (error); 2053 2054 MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 2055 return (error); 2056} 2057 2058int 2059mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 2060 gid_t gid) 2061{ 2062 int error; 2063 2064 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 2065 2066 if (!mac_enforce_fs) 2067 return (0); 2068 2069 error = vn_refreshlabel(vp, cred); 2070 if (error) 2071 return (error); 2072 2073 MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 2074 return (error); 2075} 2076 2077int 2078mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2079 struct timespec atime, struct timespec mtime) 2080{ 2081 int error; 2082 2083 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 2084 2085 if (!mac_enforce_fs) 2086 return (0); 2087 2088 error = vn_refreshlabel(vp, cred); 2089 if (error) 2090 return (error); 2091 2092 MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 2093 mtime); 2094 return (error); 2095} 2096 2097int 2098mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2099 struct vnode *vp) 2100{ 2101 int error; 2102 2103 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 2104 2105 if (!mac_enforce_fs) 2106 return (0); 2107 2108 error = vn_refreshlabel(vp, active_cred); 2109 if (error) 2110 return (error); 2111 2112 MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 2113 &vp->v_label); 2114 return (error); 2115} 2116 2117int 2118mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 2119 struct vnode *vp) 2120{ 2121 int error; 2122 2123 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 2124 2125 if (!mac_enforce_fs) 2126 return (0); 2127 2128 error = vn_refreshlabel(vp, active_cred); 2129 if (error) 2130 return (error); 2131 2132 MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 2133 &vp->v_label); 2134 2135 return (error); 2136} 2137 2138/* 2139 * When relabeling a process, call out to the policies for the maximum 2140 * permission allowed for each object type we know about in its 2141 * memory space, and revoke access (in the least surprising ways we 2142 * know) when necessary. The process lock is not held here. 2143 */ 2144static void 2145mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 2146{ 2147 2148 /* XXX freeze all other threads */ 2149 mac_cred_mmapped_drop_perms_recurse(td, cred, 2150 &td->td_proc->p_vmspace->vm_map); 2151 /* XXX allow other threads to continue */ 2152} 2153 2154static __inline const char * 2155prot2str(vm_prot_t prot) 2156{ 2157 2158 switch (prot & VM_PROT_ALL) { 2159 case VM_PROT_READ: 2160 return ("r--"); 2161 case VM_PROT_READ | VM_PROT_WRITE: 2162 return ("rw-"); 2163 case VM_PROT_READ | VM_PROT_EXECUTE: 2164 return ("r-x"); 2165 case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 2166 return ("rwx"); 2167 case VM_PROT_WRITE: 2168 return ("-w-"); 2169 case VM_PROT_EXECUTE: 2170 return ("--x"); 2171 case VM_PROT_WRITE | VM_PROT_EXECUTE: 2172 return ("-wx"); 2173 default: 2174 return ("---"); 2175 } 2176} 2177 2178static void 2179mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 2180 struct vm_map *map) 2181{ 2182 struct vm_map_entry *vme; 2183 vm_prot_t result, revokeperms; 2184 vm_object_t object; 2185 vm_ooffset_t offset; 2186 struct vnode *vp; 2187 2188 if (!mac_mmap_revocation) 2189 return; 2190 2191 vm_map_lock_read(map); 2192 for (vme = map->header.next; vme != &map->header; vme = vme->next) { 2193 if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 2194 mac_cred_mmapped_drop_perms_recurse(td, cred, 2195 vme->object.sub_map); 2196 continue; 2197 } 2198 /* 2199 * Skip over entries that obviously are not shared. 2200 */ 2201 if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 2202 !vme->max_protection) 2203 continue; 2204 /* 2205 * Drill down to the deepest backing object. 2206 */ 2207 offset = vme->offset; 2208 object = vme->object.vm_object; 2209 if (object == NULL) 2210 continue; 2211 while (object->backing_object != NULL) { 2212 object = object->backing_object; 2213 offset += object->backing_object_offset; 2214 } 2215 /* 2216 * At the moment, vm_maps and objects aren't considered 2217 * by the MAC system, so only things with backing by a 2218 * normal object (read: vnodes) are checked. 2219 */ 2220 if (object->type != OBJT_VNODE) 2221 continue; 2222 vp = (struct vnode *)object->handle; 2223 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2224 result = mac_check_vnode_mmap_prot(cred, vp, 0); 2225 VOP_UNLOCK(vp, 0, td); 2226 /* 2227 * Find out what maximum protection we may be allowing 2228 * now but a policy needs to get removed. 2229 */ 2230 revokeperms = vme->max_protection & ~result; 2231 if (!revokeperms) 2232 continue; 2233 printf("pid %ld: revoking %s perms from %#lx:%ld " 2234 "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 2235 prot2str(revokeperms), (u_long)vme->start, 2236 (long)(vme->end - vme->start), 2237 prot2str(vme->max_protection), prot2str(vme->protection)); 2238 vm_map_lock_upgrade(map); 2239 /* 2240 * This is the really simple case: if a map has more 2241 * max_protection than is allowed, but it's not being 2242 * actually used (that is, the current protection is 2243 * still allowed), we can just wipe it out and do 2244 * nothing more. 2245 */ 2246 if ((vme->protection & revokeperms) == 0) { 2247 vme->max_protection -= revokeperms; 2248 } else { 2249 if (revokeperms & VM_PROT_WRITE) { 2250 /* 2251 * In the more complicated case, flush out all 2252 * pending changes to the object then turn it 2253 * copy-on-write. 2254 */ 2255 vm_object_reference(object); 2256 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2257 vm_object_page_clean(object, 2258 OFF_TO_IDX(offset), 2259 OFF_TO_IDX(offset + vme->end - vme->start + 2260 PAGE_MASK), 2261 OBJPC_SYNC); 2262 VOP_UNLOCK(vp, 0, td); 2263 vm_object_deallocate(object); 2264 /* 2265 * Why bother if there's no read permissions 2266 * anymore? For the rest, we need to leave 2267 * the write permissions on for COW, or 2268 * remove them entirely if configured to. 2269 */ 2270 if (!mac_mmap_revocation_via_cow) { 2271 vme->max_protection &= ~VM_PROT_WRITE; 2272 vme->protection &= ~VM_PROT_WRITE; 2273 } if ((revokeperms & VM_PROT_READ) == 0) 2274 vme->eflags |= MAP_ENTRY_COW | 2275 MAP_ENTRY_NEEDS_COPY; 2276 } 2277 if (revokeperms & VM_PROT_EXECUTE) { 2278 vme->max_protection &= ~VM_PROT_EXECUTE; 2279 vme->protection &= ~VM_PROT_EXECUTE; 2280 } 2281 if (revokeperms & VM_PROT_READ) { 2282 vme->max_protection = 0; 2283 vme->protection = 0; 2284 } 2285 pmap_protect(map->pmap, vme->start, vme->end, 2286 vme->protection & ~revokeperms); 2287 vm_map_simplify_entry(map, vme); 2288 } 2289 vm_map_lock_downgrade(map); 2290 } 2291 vm_map_unlock_read(map); 2292} 2293 2294/* 2295 * When the subject's label changes, it may require revocation of privilege 2296 * to mapped objects. This can't be done on-the-fly later with a unified 2297 * buffer cache. 2298 */ 2299static void 2300mac_relabel_cred(struct ucred *cred, struct label *newlabel) 2301{ 2302 2303 MAC_PERFORM(relabel_cred, cred, newlabel); 2304} 2305 2306void 2307mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 2308{ 2309 2310 MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 2311} 2312 2313void 2314mac_create_ifnet(struct ifnet *ifnet) 2315{ 2316 2317 MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2318} 2319 2320void 2321mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2322{ 2323 2324 MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2325} 2326 2327void 2328mac_create_socket(struct ucred *cred, struct socket *socket) 2329{ 2330 2331 MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2332} 2333 2334void 2335mac_create_pipe(struct ucred *cred, struct pipe *pipe) 2336{ 2337 2338 MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2339} 2340 2341void 2342mac_create_socket_from_socket(struct socket *oldsocket, 2343 struct socket *newsocket) 2344{ 2345 2346 MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2347 newsocket, &newsocket->so_label); 2348} 2349 2350static void 2351mac_relabel_socket(struct ucred *cred, struct socket *socket, 2352 struct label *newlabel) 2353{ 2354 2355 MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2356} 2357 2358static void 2359mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2360{ 2361 2362 MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2363} 2364 2365void 2366mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2367{ 2368 2369 MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label, 2370 socket, &socket->so_peerlabel); 2371} 2372 2373void 2374mac_set_socket_peer_from_socket(struct socket *oldsocket, 2375 struct socket *newsocket) 2376{ 2377 2378 MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2379 &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2380} 2381 2382void 2383mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2384{ 2385 2386 MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2387 datagram, &datagram->m_pkthdr.label); 2388} 2389 2390void 2391mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2392{ 2393 2394 MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label, 2395 fragment, &fragment->m_pkthdr.label); 2396} 2397 2398void 2399mac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2400{ 2401 2402 MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2403 &ipq->ipq_label); 2404} 2405 2406void 2407mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2408{ 2409 2410 MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label, 2411 newmbuf, &newmbuf->m_pkthdr.label); 2412} 2413 2414void 2415mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2416{ 2417 2418 MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2419 &mbuf->m_pkthdr.label); 2420} 2421 2422void 2423mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2424{ 2425 2426 MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2427 &mbuf->m_pkthdr.label); 2428} 2429 2430void 2431mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2432{ 2433 2434 MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2435 &mbuf->m_pkthdr.label); 2436} 2437 2438void 2439mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2440 struct mbuf *newmbuf) 2441{ 2442 2443 MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, 2444 &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf, 2445 &newmbuf->m_pkthdr.label); 2446} 2447 2448void 2449mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2450{ 2451 2452 MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label, 2453 newmbuf, &newmbuf->m_pkthdr.label); 2454} 2455 2456int 2457mac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2458{ 2459 int result; 2460 2461 result = 1; 2462 MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label, 2463 ipq, &ipq->ipq_label); 2464 2465 return (result); 2466} 2467 2468void 2469mac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2470{ 2471 2472 MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2473 &ipq->ipq_label); 2474} 2475 2476void 2477mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2478{ 2479 2480 MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2481 &mbuf->m_pkthdr.label); 2482} 2483 2484void 2485mac_create_mount(struct ucred *cred, struct mount *mp) 2486{ 2487 2488 MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2489 &mp->mnt_fslabel); 2490} 2491 2492void 2493mac_create_root_mount(struct ucred *cred, struct mount *mp) 2494{ 2495 2496 MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2497 &mp->mnt_fslabel); 2498} 2499 2500int 2501mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2502{ 2503 int error; 2504 2505 if (!mac_enforce_network) 2506 return (0); 2507 2508 MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2509 &ifnet->if_label); 2510 2511 return (error); 2512} 2513 2514static int 2515mac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2516{ 2517 int error; 2518 2519 MAC_CHECK(check_cred_relabel, cred, newlabel); 2520 2521 return (error); 2522} 2523 2524int 2525mac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2526{ 2527 int error; 2528 2529 if (!mac_enforce_process) 2530 return (0); 2531 2532 MAC_CHECK(check_cred_visible, u1, u2); 2533 2534 return (error); 2535} 2536 2537int 2538mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2539{ 2540 int error; 2541 2542 if (!mac_enforce_network) 2543 return (0); 2544 2545 KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr")); 2546 if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED)) 2547 printf("%s%d: not initialized\n", ifnet->if_name, 2548 ifnet->if_unit); 2549 2550 MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2551 &mbuf->m_pkthdr.label); 2552 2553 return (error); 2554} 2555 2556int 2557mac_check_mount_stat(struct ucred *cred, struct mount *mount) 2558{ 2559 int error; 2560 2561 if (!mac_enforce_fs) 2562 return (0); 2563 2564 MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2565 2566 return (error); 2567} 2568 2569int 2570mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2571 void *data) 2572{ 2573 int error; 2574 2575 MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2576 2577 return (error); 2578} 2579 2580int 2581mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2582{ 2583 int error; 2584 2585 MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2586 2587 return (error); 2588} 2589 2590int 2591mac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2592{ 2593 int error; 2594 2595 MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2596 2597 return (error); 2598} 2599 2600static int 2601mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2602 struct label *newlabel) 2603{ 2604 int error; 2605 2606 MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2607 2608 return (error); 2609} 2610 2611int 2612mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2613{ 2614 int error; 2615 2616 MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2617 2618 return (error); 2619} 2620 2621int 2622mac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2623{ 2624 int error; 2625 2626 MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2627 2628 return (error); 2629} 2630 2631int 2632mac_check_proc_debug(struct ucred *cred, struct proc *proc) 2633{ 2634 int error; 2635 2636 PROC_LOCK_ASSERT(proc, MA_OWNED); 2637 2638 if (!mac_enforce_process) 2639 return (0); 2640 2641 MAC_CHECK(check_proc_debug, cred, proc); 2642 2643 return (error); 2644} 2645 2646int 2647mac_check_proc_sched(struct ucred *cred, struct proc *proc) 2648{ 2649 int error; 2650 2651 PROC_LOCK_ASSERT(proc, MA_OWNED); 2652 2653 if (!mac_enforce_process) 2654 return (0); 2655 2656 MAC_CHECK(check_proc_sched, cred, proc); 2657 2658 return (error); 2659} 2660 2661int 2662mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2663{ 2664 int error; 2665 2666 PROC_LOCK_ASSERT(proc, MA_OWNED); 2667 2668 if (!mac_enforce_process) 2669 return (0); 2670 2671 MAC_CHECK(check_proc_signal, cred, proc, signum); 2672 2673 return (error); 2674} 2675 2676int 2677mac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2678 struct sockaddr *sockaddr) 2679{ 2680 int error; 2681 2682 if (!mac_enforce_socket) 2683 return (0); 2684 2685 MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2686 sockaddr); 2687 2688 return (error); 2689} 2690 2691int 2692mac_check_socket_connect(struct ucred *cred, struct socket *socket, 2693 struct sockaddr *sockaddr) 2694{ 2695 int error; 2696 2697 if (!mac_enforce_socket) 2698 return (0); 2699 2700 MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2701 sockaddr); 2702 2703 return (error); 2704} 2705 2706int 2707mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2708{ 2709 int error; 2710 2711 if (!mac_enforce_socket) 2712 return (0); 2713 2714 MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2715 &mbuf->m_pkthdr.label); 2716 2717 return (error); 2718} 2719 2720int 2721mac_check_socket_listen(struct ucred *cred, struct socket *socket) 2722{ 2723 int error; 2724 2725 if (!mac_enforce_socket) 2726 return (0); 2727 2728 MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2729 return (error); 2730} 2731 2732static int 2733mac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2734 struct label *newlabel) 2735{ 2736 int error; 2737 2738 MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2739 newlabel); 2740 2741 return (error); 2742} 2743 2744int 2745mac_check_socket_visible(struct ucred *cred, struct socket *socket) 2746{ 2747 int error; 2748 2749 if (!mac_enforce_socket) 2750 return (0); 2751 2752 MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 2753 2754 return (error); 2755} 2756 2757int 2758mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 2759 struct ifnet *ifnet) 2760{ 2761 struct mac label; 2762 int error; 2763 2764 error = mac_externalize(&ifnet->if_label, &label); 2765 if (error) 2766 return (error); 2767 2768 return (copyout(&label, ifr->ifr_ifru.ifru_data, sizeof(label))); 2769} 2770 2771int 2772mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 2773 struct ifnet *ifnet) 2774{ 2775 struct mac newlabel; 2776 struct label intlabel; 2777 int error; 2778 2779 error = copyin(ifr->ifr_ifru.ifru_data, &newlabel, sizeof(newlabel)); 2780 if (error) 2781 return (error); 2782 2783 error = mac_internalize(&intlabel, &newlabel); 2784 if (error) 2785 return (error); 2786 2787 /* 2788 * XXX: Note that this is a redundant privilege check, since 2789 * policies impose this check themselves if required by the 2790 * policy. Eventually, this should go away. 2791 */ 2792 error = suser_cred(cred, 0); 2793 if (error) 2794 goto out; 2795 2796 MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 2797 &intlabel); 2798 if (error) 2799 goto out; 2800 2801 MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 2802 2803out: 2804 mac_destroy_temp(&intlabel); 2805 return (error); 2806} 2807 2808void 2809mac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp) 2810{ 2811 2812 MAC_PERFORM(create_devfs_vnode, de, &de->de_label, vp, &vp->v_label); 2813} 2814 2815void 2816mac_create_devfs_device(dev_t dev, struct devfs_dirent *de) 2817{ 2818 2819 MAC_PERFORM(create_devfs_device, dev, de, &de->de_label); 2820} 2821 2822static int 2823mac_stdcreatevnode_ea(struct vnode *vp) 2824{ 2825 int error; 2826 2827 MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label); 2828 2829 return (error); 2830} 2831 2832void 2833mac_create_devfs_directory(char *dirname, int dirnamelen, 2834 struct devfs_dirent *de) 2835{ 2836 2837 MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de, 2838 &de->de_label); 2839} 2840 2841/* 2842 * When a new vnode is created, this call will initialize its label. 2843 */ 2844void 2845mac_create_vnode(struct ucred *cred, struct vnode *parent, 2846 struct vnode *child) 2847{ 2848 int error; 2849 2850 ASSERT_VOP_LOCKED(parent, "mac_create_vnode"); 2851 ASSERT_VOP_LOCKED(child, "mac_create_vnode"); 2852 2853 error = vn_refreshlabel(parent, cred); 2854 if (error) { 2855 printf("mac_create_vnode: vn_refreshlabel returned %d\n", 2856 error); 2857 printf("mac_create_vnode: using old vnode label\n"); 2858 } 2859 2860 MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child, 2861 &child->v_label); 2862} 2863 2864int 2865mac_setsockopt_label_set(struct ucred *cred, struct socket *so, 2866 struct mac *extmac) 2867{ 2868 struct label intlabel; 2869 int error; 2870 2871 error = mac_internalize(&intlabel, extmac); 2872 if (error) 2873 return (error); 2874 2875 mac_check_socket_relabel(cred, so, &intlabel); 2876 if (error) { 2877 mac_destroy_temp(&intlabel); 2878 return (error); 2879 } 2880 2881 mac_relabel_socket(cred, so, &intlabel); 2882 2883 mac_destroy_temp(&intlabel); 2884 return (0); 2885} 2886 2887int 2888mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 2889{ 2890 int error; 2891 2892 error = mac_check_pipe_relabel(cred, pipe, label); 2893 if (error) 2894 return (error); 2895 2896 mac_relabel_pipe(cred, pipe, label); 2897 2898 return (0); 2899} 2900 2901int 2902mac_getsockopt_label_get(struct ucred *cred, struct socket *so, 2903 struct mac *extmac) 2904{ 2905 2906 return (mac_externalize(&so->so_label, extmac)); 2907} 2908 2909int 2910mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 2911 struct mac *extmac) 2912{ 2913 2914 return (mac_externalize(&so->so_peerlabel, extmac)); 2915} 2916 2917/* 2918 * Implementation of VOP_SETLABEL() that relies on extended attributes 2919 * to store label data. Can be referenced by filesystems supporting 2920 * extended attributes. 2921 */ 2922int 2923vop_stdsetlabel_ea(struct vop_setlabel_args *ap) 2924{ 2925 struct vnode *vp = ap->a_vp; 2926 struct label *intlabel = ap->a_label; 2927 struct mac extmac; 2928 int error; 2929 2930 ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 2931 2932 /* 2933 * XXX: Eventually call out to EA check/set calls here. 2934 * Be particularly careful to avoid race conditions, 2935 * consistency problems, and stability problems when 2936 * dealing with multiple EAs. In particular, we require 2937 * the ability to write multiple EAs on the same file in 2938 * a single transaction, which the current EA interface 2939 * does not provide. 2940 */ 2941 2942 error = mac_externalize(intlabel, &extmac); 2943 if (error) 2944 return (error); 2945 2946 error = vn_extattr_set(vp, IO_NODELOCKED, 2947 FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, 2948 sizeof(extmac), (char *)&extmac, curthread); 2949 if (error) 2950 return (error); 2951 2952 mac_relabel_vnode(ap->a_cred, vp, intlabel); 2953 2954 vp->v_vflag |= VV_CACHEDLABEL; 2955 2956 return (0); 2957} 2958 2959static int 2960vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 2961{ 2962 int error; 2963 2964 if (vp->v_mount == NULL) { 2965 /* printf("vn_setlabel: null v_mount\n"); */ 2966 if (vp->v_type != VNON) 2967 printf("vn_setlabel: null v_mount with non-VNON\n"); 2968 return (EBADF); 2969 } 2970 2971 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 2972 return (EOPNOTSUPP); 2973 2974 /* 2975 * Multi-phase commit. First check the policies to confirm the 2976 * change is OK. Then commit via the filesystem. Finally, 2977 * update the actual vnode label. Question: maybe the filesystem 2978 * should update the vnode at the end as part of VOP_SETLABEL()? 2979 */ 2980 error = mac_check_vnode_relabel(cred, vp, intlabel); 2981 if (error) 2982 return (error); 2983 2984 /* 2985 * VADMIN provides the opportunity for the filesystem to make 2986 * decisions about who is and is not able to modify labels 2987 * and protections on files. This might not be right. We can't 2988 * assume VOP_SETLABEL() will do it, because we might implement 2989 * that as part of vop_stdsetlabel_ea(). 2990 */ 2991 error = VOP_ACCESS(vp, VADMIN, cred, curthread); 2992 if (error) 2993 return (error); 2994 2995 error = VOP_SETLABEL(vp, intlabel, cred, curthread); 2996 if (error) 2997 return (error); 2998 2999 return (0); 3000} 3001 3002/* 3003 * MPSAFE 3004 */ 3005int 3006__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3007{ 3008 struct mac extmac; 3009 int error; 3010 3011 error = mac_externalize(&td->td_ucred->cr_label, &extmac); 3012 if (error == 0) 3013 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac)); 3014 3015 return (error); 3016} 3017 3018/* 3019 * MPSAFE 3020 */ 3021int 3022__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3023{ 3024 struct ucred *newcred, *oldcred; 3025 struct proc *p; 3026 struct mac extmac; 3027 struct label intlabel; 3028 int error; 3029 3030 error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac)); 3031 if (error) 3032 return (error); 3033 3034 error = mac_internalize(&intlabel, &extmac); 3035 if (error) 3036 return (error); 3037 3038 newcred = crget(); 3039 3040 p = td->td_proc; 3041 PROC_LOCK(p); 3042 oldcred = p->p_ucred; 3043 3044 error = mac_check_cred_relabel(oldcred, &intlabel); 3045 if (error) { 3046 PROC_UNLOCK(p); 3047 mac_destroy_temp(&intlabel); 3048 crfree(newcred); 3049 return (error); 3050 } 3051 3052 setsugid(p); 3053 crcopy(newcred, oldcred); 3054 mac_relabel_cred(newcred, &intlabel); 3055 p->p_ucred = newcred; 3056 3057 /* 3058 * Grab additional reference for use while revoking mmaps, prior 3059 * to releasing the proc lock and sharing the cred. 3060 */ 3061 crhold(newcred); 3062 PROC_UNLOCK(p); 3063 3064 mtx_lock(&Giant); 3065 mac_cred_mmapped_drop_perms(td, newcred); 3066 mtx_unlock(&Giant); 3067 3068 crfree(newcred); /* Free revocation reference. */ 3069 crfree(oldcred); 3070 mac_destroy_temp(&intlabel); 3071 return (0); 3072} 3073 3074/* 3075 * MPSAFE 3076 */ 3077int 3078__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3079{ 3080 struct file *fp; 3081 struct mac extmac; 3082 struct vnode *vp; 3083 struct pipe *pipe; 3084 int error; 3085 3086 mtx_lock(&Giant); 3087 3088 error = fget(td, SCARG(uap, fd), &fp); 3089 if (error) 3090 goto out; 3091 3092 switch (fp->f_type) { 3093 case DTYPE_FIFO: 3094 case DTYPE_VNODE: 3095 vp = (struct vnode *)fp->f_data; 3096 3097 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3098 error = vn_refreshlabel(vp, td->td_ucred); 3099 if (error == 0) 3100 error = mac_externalize(&vp->v_label, &extmac); 3101 VOP_UNLOCK(vp, 0, td); 3102 break; 3103 case DTYPE_PIPE: 3104 pipe = (struct pipe *)fp->f_data; 3105 error = mac_externalize(pipe->pipe_label, &extmac); 3106 break; 3107 default: 3108 error = EINVAL; 3109 } 3110 3111 if (error == 0) 3112 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac)); 3113 3114 fdrop(fp, td); 3115 3116out: 3117 mtx_unlock(&Giant); 3118 return (error); 3119} 3120 3121/* 3122 * MPSAFE 3123 */ 3124int 3125__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3126{ 3127 struct nameidata nd; 3128 struct mac extmac; 3129 int error; 3130 3131 mtx_lock(&Giant); 3132 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, 3133 SCARG(uap, path_p), td); 3134 error = namei(&nd); 3135 if (error) 3136 goto out; 3137 3138 error = vn_refreshlabel(nd.ni_vp, td->td_ucred); 3139 if (error == 0) 3140 error = mac_externalize(&nd.ni_vp->v_label, &extmac); 3141 NDFREE(&nd, 0); 3142 if (error) 3143 goto out; 3144 3145 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac)); 3146 3147out: 3148 mtx_unlock(&Giant); 3149 return (error); 3150} 3151 3152/* 3153 * MPSAFE 3154 */ 3155int 3156__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3157{ 3158 struct file *fp; 3159 struct mac extmac; 3160 struct label intlabel; 3161 struct mount *mp; 3162 struct vnode *vp; 3163 struct pipe *pipe; 3164 int error; 3165 3166 mtx_lock(&Giant); 3167 error = fget(td, SCARG(uap, fd), &fp); 3168 if (error) 3169 goto out1; 3170 3171 error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac)); 3172 if (error) 3173 goto out2; 3174 3175 error = mac_internalize(&intlabel, &extmac); 3176 if (error) 3177 goto out2; 3178 3179 switch (fp->f_type) { 3180 case DTYPE_FIFO: 3181 case DTYPE_VNODE: 3182 vp = (struct vnode *)fp->f_data; 3183 error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3184 if (error != 0) 3185 break; 3186 3187 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3188 error = vn_setlabel(vp, &intlabel, td->td_ucred); 3189 VOP_UNLOCK(vp, 0, td); 3190 vn_finished_write(mp); 3191 mac_destroy_temp(&intlabel); 3192 break; 3193 case DTYPE_PIPE: 3194 pipe = (struct pipe *)fp->f_data; 3195 error = mac_pipe_label_set(td->td_ucred, pipe, &intlabel); 3196 break; 3197 default: 3198 error = EINVAL; 3199 } 3200 3201out2: 3202 fdrop(fp, td); 3203out1: 3204 mtx_unlock(&Giant); 3205 return (error); 3206} 3207 3208/* 3209 * MPSAFE 3210 */ 3211int 3212__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3213{ 3214 struct nameidata nd; 3215 struct mac extmac; 3216 struct label intlabel; 3217 struct mount *mp; 3218 int error; 3219 3220 mtx_lock(&Giant); 3221 3222 error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac)); 3223 if (error) 3224 goto out; 3225 3226 error = mac_internalize(&intlabel, &extmac); 3227 if (error) 3228 goto out; 3229 3230 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, 3231 SCARG(uap, path_p), td); 3232 error = namei(&nd); 3233 if (error) 3234 goto out2; 3235 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3236 if (error) 3237 goto out2; 3238 3239 error = vn_setlabel(nd.ni_vp, &intlabel, td->td_ucred); 3240 3241 vn_finished_write(mp); 3242out2: 3243 mac_destroy_temp(&intlabel); 3244 NDFREE(&nd, 0); 3245out: 3246 mtx_unlock(&Giant); 3247 return (error); 3248} 3249 3250int 3251mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3252{ 3253 struct mac_policy_conf *mpc; 3254 char target[MAC_MAX_POLICY_NAME]; 3255 int error; 3256 3257 error = copyinstr(SCARG(uap, policy), target, sizeof(target), NULL); 3258 if (error) 3259 return (error); 3260 3261 error = ENOSYS; 3262 MAC_POLICY_LIST_BUSY(); 3263 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3264 if (strcmp(mpc->mpc_name, target) == 0 && 3265 mpc->mpc_ops->mpo_syscall != NULL) { 3266 error = mpc->mpc_ops->mpo_syscall(td, 3267 SCARG(uap, call), SCARG(uap, arg)); 3268 goto out; 3269 } 3270 } 3271 3272out: 3273 MAC_POLICY_LIST_UNBUSY(); 3274 return (error); 3275} 3276 3277SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3278SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3279 3280#else /* !MAC */ 3281 3282int 3283__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3284{ 3285 3286 return (ENOSYS); 3287} 3288 3289int 3290__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3291{ 3292 3293 return (ENOSYS); 3294} 3295 3296int 3297__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3298{ 3299 3300 return (ENOSYS); 3301} 3302 3303int 3304__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3305{ 3306 3307 return (ENOSYS); 3308} 3309 3310int 3311__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3312{ 3313 3314 return (ENOSYS); 3315} 3316 3317int 3318__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3319{ 3320 3321 return (ENOSYS); 3322} 3323 3324int 3325mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3326{ 3327 3328 return (ENOSYS); 3329} 3330 3331#endif /* !MAC */ 3332