mac_vfs.c revision 106024
118334Speter/*- 218334Speter * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 318334Speter * Copyright (c) 2001 Ilmar S. Habibulin 418334Speter * Copyright (c) 2001, 2002 Networks Associates Technology, Inc. 518334Speter * All rights reserved. 618334Speter * 718334Speter * This software was developed by Robert Watson and Ilmar Habibulin for the 818334Speter * TrustedBSD Project. 918334Speter * 1018334Speter * This software was developed for the FreeBSD Project in part by NAI Labs, 1118334Speter * the Security Research Division of Network Associates, Inc. under 1218334Speter * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 1318334Speter * CHATS research program. 1418334Speter * 1518334Speter * Redistribution and use in source and binary forms, with or without 1618334Speter * modification, are permitted provided that the following conditions 1718334Speter * are met: 1818334Speter * 1. Redistributions of source code must retain the above copyright 1918334Speter * notice, this list of conditions and the following disclaimer. 2018334Speter * 2. Redistributions in binary form must reproduce the above copyright 2118334Speter * notice, this list of conditions and the following disclaimer in the 2218334Speter * documentation and/or other materials provided with the distribution. 2318334Speter * 3. The names of the authors may not be used to endorse or promote 2418334Speter * products derived from this software without specific prior written 2518334Speter * permission. 2618334Speter * 2718334Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2818334Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2918334Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3018334Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 3118334Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3218334Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3318334Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3418334Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3518334Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3618334Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3718334Speter * SUCH DAMAGE. 3818334Speter * 3918334Speter * $FreeBSD: head/sys/security/mac/mac_vfs.c 106024 2002-10-27 07:03:29Z rwatson $ 4018334Speter */ 4118334Speter/* 4218334Speter * Developed by the TrustedBSD Project. 4318334Speter * 4418334Speter * Framework for extensible kernel access control. Kernel and userland 4518334Speter * interface to the framework, policy registration and composition. 4618334Speter */ 4718334Speter 4818334Speter#include "opt_mac.h" 4918334Speter#include "opt_devfs.h" 5018334Speter 5118334Speter#include <sys/param.h> 5218334Speter#include <sys/extattr.h> 5318334Speter#include <sys/kernel.h> 5418334Speter#include <sys/lock.h> 5518334Speter#include <sys/malloc.h> 5618334Speter#include <sys/mutex.h> 5718334Speter#include <sys/mac.h> 5818334Speter#include <sys/module.h> 5918334Speter#include <sys/proc.h> 6018334Speter#include <sys/systm.h> 6118334Speter#include <sys/sysproto.h> 6218334Speter#include <sys/sysent.h> 6318334Speter#include <sys/vnode.h> 6418334Speter#include <sys/mount.h> 6518334Speter#include <sys/file.h> 6618334Speter#include <sys/namei.h> 6718334Speter#include <sys/socket.h> 6818334Speter#include <sys/pipe.h> 6918334Speter#include <sys/socketvar.h> 7018334Speter#include <sys/sysctl.h> 7118334Speter 7218334Speter#include <vm/vm.h> 7318334Speter#include <vm/pmap.h> 7418334Speter#include <vm/vm_map.h> 7518334Speter#include <vm/vm_object.h> 7618334Speter 7718334Speter#include <sys/mac_policy.h> 7818334Speter 7918334Speter#include <fs/devfs/devfs.h> 8018334Speter 8118334Speter#include <net/bpfdesc.h> 8218334Speter#include <net/if.h> 8318334Speter#include <net/if_var.h> 8418334Speter 8518334Speter#include <netinet/in.h> 8618334Speter#include <netinet/ip_var.h> 8718334Speter 8818334Speter#ifdef MAC 8918334Speter 9018334Speter/* 9118334Speter * Declare that the kernel provides MAC support, version 1. This permits 9218334Speter * modules to refuse to be loaded if the necessary support isn't present, 9318334Speter * even if it's pre-boot. 9418334Speter */ 9518334SpeterMODULE_VERSION(kernel_mac_support, 1); 9618334Speter 9718334SpeterSYSCTL_DECL(_security); 9818334Speter 9918334SpeterSYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0, 10018334Speter "TrustedBSD MAC policy controls"); 10118334Speter 10218334Speter#if MAC_MAX_POLICIES > 32 10318334Speter#error "MAC_MAX_POLICIES too large" 10418334Speter#endif 10518334Speter 10618334Speterstatic unsigned int mac_max_policies = MAC_MAX_POLICIES; 10718334Speterstatic unsigned int mac_policy_offsets_free = (1 << MAC_MAX_POLICIES) - 1; 10818334SpeterSYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD, 10918334Speter &mac_max_policies, 0, ""); 11018334Speter 11118334Speter/* 11218334Speter * Has the kernel started generating labeled objects yet? All read/write 11318334Speter * access to this variable is serialized during the boot process. Following 11418334Speter * the end of serialization, we don't update this flag; no locking. 11518334Speter */ 11618334Speterstatic int mac_late = 0; 11718334Speter 11818334Speter/* 11918334Speter * Warn about EA transactions only the first time they happen. 12018334Speter * Weak coherency, no locking. 12118334Speter */ 12218334Speterstatic int ea_warn_once = 0; 12318334Speter 12418334Speterstatic int mac_enforce_fs = 1; 12518334SpeterSYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW, 12618334Speter &mac_enforce_fs, 0, "Enforce MAC policy on file system objects"); 12718334SpeterTUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs); 12818334Speter 12918334Speterstatic int mac_enforce_network = 1; 13018334SpeterSYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, 13118334Speter &mac_enforce_network, 0, "Enforce MAC policy on network packets"); 13218334SpeterTUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); 13318334Speter 13418334Speterstatic int mac_enforce_pipe = 1; 13518334SpeterSYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW, 13618334Speter &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations"); 13718334SpeterTUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe); 13818334Speter 13918334Speterstatic int mac_enforce_process = 1; 14018334SpeterSYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW, 14118334Speter &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations"); 14218334SpeterTUNABLE_INT("security.mac.enforce_process", &mac_enforce_process); 14318334Speter 14418334Speterstatic int mac_enforce_reboot = 1; 14518334SpeterSYSCTL_INT(_security_mac, OID_AUTO, enforce_reboot, CTLFLAG_RW, 14618334Speter &mac_enforce_reboot, 0, "Enforce MAC policy for reboot operations"); 14718334SpeterTUNABLE_INT("security.mac.enforce_reboot", &mac_enforce_reboot); 14818334Speter 14918334Speterstatic int mac_enforce_socket = 1; 15018334SpeterSYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 15118334Speter &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 15218334SpeterTUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 15318334Speter 15418334Speterstatic int mac_enforce_vm = 1; 15518334SpeterSYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW, 15618334Speter &mac_enforce_vm, 0, "Enforce MAC policy on vm operations"); 15718334SpeterTUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm); 15818334Speter 15918334Speterstatic int mac_cache_fslabel_in_vnode = 1; 16018334SpeterSYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW, 16118334Speter &mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode"); 16218334SpeterTUNABLE_INT("security.mac.cache_fslabel_in_vnode", 16318334Speter &mac_cache_fslabel_in_vnode); 16418334Speter 16518334Speterstatic int mac_mmap_revocation = 1; 16618334SpeterSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW, 16718334Speter &mac_mmap_revocation, 0, "Revoke mmap access to files on subject " 16818334Speter "relabel"); 16918334Speterstatic int mac_mmap_revocation_via_cow = 0; 17018334SpeterSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW, 17118334Speter &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via " 17218334Speter "copy-on-write semantics, or by removing all write access"); 17318334Speter 17418334Speter#ifdef MAC_DEBUG 17518334SpeterSYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0, 17618334Speter "TrustedBSD MAC debug info"); 17718334Speter 17818334Speterstatic int mac_debug_label_fallback = 0; 17918334SpeterSYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW, 18018334Speter &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label" 18118334Speter "when label is corrupted."); 18218334SpeterTUNABLE_INT("security.mac.debug_label_fallback", 18318334Speter &mac_debug_label_fallback); 18418334Speter 18518334SpeterSYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0, 18618334Speter "TrustedBSD MAC object counters"); 18718334Speter 18818334Speterstatic unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs, 18918334Speter nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents, 19018334Speter nmacipqs, nmacpipes; 19118334Speter 19218334SpeterSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD, 19318334Speter &nmacmbufs, 0, "number of mbufs in use"); 19418334SpeterSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD, 19518334Speter &nmaccreds, 0, "number of ucreds in use"); 19618334SpeterSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD, 19718334Speter &nmacifnets, 0, "number of ifnets in use"); 19818334SpeterSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD, 19918334Speter &nmacipqs, 0, "number of ipqs in use"); 20018334SpeterSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD, 20118334Speter &nmacbpfdescs, 0, "number of bpfdescs in use"); 20218334SpeterSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD, 20318334Speter &nmacsockets, 0, "number of sockets in use"); 20418334SpeterSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, pipes, CTLFLAG_RD, 20518334Speter &nmacpipes, 0, "number of pipes in use"); 20618334SpeterSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD, 20718334Speter &nmacmounts, 0, "number of mounts in use"); 20818334SpeterSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD, 20918334Speter &nmactemp, 0, "number of temporary labels in use"); 21018334SpeterSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD, 21118334Speter &nmacvnodes, 0, "number of vnodes in use"); 21218334SpeterSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD, 21318334Speter &nmacdevfsdirents, 0, "number of devfs dirents inuse"); 21418334Speter#endif 21518334Speter 21618334Speterstatic int error_select(int error1, int error2); 21718334Speterstatic int mac_policy_register(struct mac_policy_conf *mpc); 21818334Speterstatic int mac_policy_unregister(struct mac_policy_conf *mpc); 21918334Speter 22018334Speterstatic void mac_check_vnode_mmap_downgrade(struct ucred *cred, 22118334Speter struct vnode *vp, int *prot); 22218334Speterstatic void mac_cred_mmapped_drop_perms_recurse(struct thread *td, 22318334Speter struct ucred *cred, struct vm_map *map); 22418334Speter 22518334Speterstatic void mac_destroy_socket_label(struct label *label); 22618334Speter 22718334Speterstatic int mac_setlabel_vnode_extattr(struct ucred *cred, 22818334Speter struct vnode *vp, struct label *intlabel); 22918334Speter 23018334Speter 23118334SpeterMALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector"); 23218334SpeterMALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes"); 23318334SpeterMALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage"); 23418334Speter 23518334Speter/* 23618334Speter * mac_policy_list_lock protects the consistency of 'mac_policy_list', 23718334Speter * the linked list of attached policy modules. Read-only consumers of 23818334Speter * the list must acquire a shared lock for the duration of their use; 23918334Speter * writers must acquire an exclusive lock. Note that for compound 24018334Speter * operations, locks should be held for the entire compound operation, 24118334Speter * and that this is not yet done for relabel requests. 24218334Speter */ 24318334Speterstatic struct mtx mac_policy_list_lock; 24418334Speterstatic LIST_HEAD(, mac_policy_conf) mac_policy_list; 24518334Speterstatic int mac_policy_list_busy; 24618334Speter#define MAC_POLICY_LIST_LOCKINIT() mtx_init(&mac_policy_list_lock, \ 24718334Speter "mac_policy_list_lock", NULL, MTX_DEF); 24818334Speter#define MAC_POLICY_LIST_LOCK() mtx_lock(&mac_policy_list_lock); 24918334Speter#define MAC_POLICY_LIST_UNLOCK() mtx_unlock(&mac_policy_list_lock); 25018334Speter 25118334Speter#define MAC_POLICY_LIST_BUSY() do { \ 25218334Speter MAC_POLICY_LIST_LOCK(); \ 25318334Speter mac_policy_list_busy++; \ 25418334Speter MAC_POLICY_LIST_UNLOCK(); \ 25518334Speter} while (0) 25618334Speter 25718334Speter#define MAC_POLICY_LIST_UNBUSY() do { \ 25818334Speter MAC_POLICY_LIST_LOCK(); \ 25918334Speter mac_policy_list_busy--; \ 26018334Speter if (mac_policy_list_busy < 0) \ 26118334Speter panic("Extra mac_policy_list_busy--"); \ 26218334Speter MAC_POLICY_LIST_UNLOCK(); \ 26318334Speter} while (0) 26418334Speter 26518334Speter/* 26618334Speter * MAC_CHECK performs the designated check by walking the policy 26718334Speter * module list and checking with each as to how it feels about the 26818334Speter * request. Note that it returns its value via 'error' in the scope 26918334Speter * of the caller. 27018334Speter */ 27118334Speter#define MAC_CHECK(check, args...) do { \ 27218334Speter struct mac_policy_conf *mpc; \ 27318334Speter \ 27418334Speter error = 0; \ 27518334Speter MAC_POLICY_LIST_BUSY(); \ 27618334Speter LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 27718334Speter if (mpc->mpc_ops->mpo_ ## check != NULL) \ 27818334Speter error = error_select( \ 27918334Speter mpc->mpc_ops->mpo_ ## check (args), \ 28018334Speter error); \ 28118334Speter } \ 28218334Speter MAC_POLICY_LIST_UNBUSY(); \ 28318334Speter} while (0) 28418334Speter 28518334Speter/* 28618334Speter * MAC_BOOLEAN performs the designated boolean composition by walking 28718334Speter * the module list, invoking each instance of the operation, and 28818334Speter * combining the results using the passed C operator. Note that it 28918334Speter * returns its value via 'result' in the scope of the caller, which 29018334Speter * should be initialized by the caller in a meaningful way to get 29118334Speter * a meaningful result. 29218334Speter */ 29318334Speter#define MAC_BOOLEAN(operation, composition, args...) do { \ 29418334Speter struct mac_policy_conf *mpc; \ 29518334Speter \ 29618334Speter MAC_POLICY_LIST_BUSY(); \ 29718334Speter LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 29818334Speter if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 29918334Speter result = result composition \ 30018334Speter mpc->mpc_ops->mpo_ ## operation (args); \ 30118334Speter } \ 30218334Speter MAC_POLICY_LIST_UNBUSY(); \ 30318334Speter} while (0) 30418334Speter 30518334Speter#define MAC_EXTERNALIZE(type, label, elementlist, outbuf, \ 30618334Speter outbuflen) do { \ 30718334Speter char *curptr, *curptr_start, *element_name, *element_temp; \ 30818334Speter size_t left, left_start, len; \ 30918334Speter int claimed, first, first_start, ignorenotfound; \ 31018334Speter \ 31118334Speter error = 0; \ 31218334Speter element_temp = elementlist; \ 31318334Speter curptr = outbuf; \ 31418334Speter curptr[0] = '\0'; \ 31518334Speter left = outbuflen; \ 31618334Speter first = 1; \ 31718334Speter while ((element_name = strsep(&element_temp, ",")) != NULL) { \ 31818334Speter curptr_start = curptr; \ 31918334Speter left_start = left; \ 32018334Speter first_start = first; \ 32118334Speter if (element_name[0] == '?') { \ 32218334Speter element_name++; \ 32318334Speter ignorenotfound = 1; \ 32418334Speter } else \ 32518334Speter ignorenotfound = 0; \ 32618334Speter claimed = 0; \ 32718334Speter if (first) { \ 32818334Speter len = snprintf(curptr, left, "%s/", \ 32918334Speter element_name); \ 33018334Speter first = 0; \ 33118334Speter } else \ 33218334Speter len = snprintf(curptr, left, ",%s/", \ 33318334Speter element_name); \ 33418334Speter if (len >= left) { \ 33518334Speter error = EINVAL; /* XXXMAC: E2BIG */ \ 33618334Speter break; \ 33718334Speter } \ 33818334Speter curptr += len; \ 33918334Speter left -= len; \ 34018334Speter \ 34118334Speter MAC_CHECK(externalize_ ## type, label, element_name, \ 34218334Speter curptr, left, &len, &claimed); \ 34318334Speter if (error) \ 34418334Speter break; \ 34518334Speter if (claimed == 1) { \ 34618334Speter if (len >= outbuflen) { \ 34718334Speter error = EINVAL; /* XXXMAC: E2BIG */ \ 34818334Speter break; \ 34918334Speter } \ 35018334Speter curptr += len; \ 35118334Speter left -= len; \ 35218334Speter } else if (claimed == 0 && ignorenotfound) { \ 35318334Speter /* \ 35418334Speter * Revert addition of the label element \ 35518334Speter * name. \ 35618334Speter */ \ 35718334Speter curptr = curptr_start; \ 35818334Speter *curptr = '\0'; \ 35918334Speter left = left_start; \ 36018334Speter first = first_start; \ 36118334Speter } else { \ 36218334Speter error = EINVAL; /* XXXMAC: ENOLABEL */ \ 36318334Speter break; \ 36418334Speter } \ 36518334Speter } \ 36618334Speter} while (0) 36718334Speter 36818334Speter#define MAC_INTERNALIZE(type, label, instring) do { \ 36918334Speter char *element, *element_name, *element_data; \ 37018334Speter int claimed; \ 37118334Speter \ 37218334Speter error = 0; \ 37318334Speter element = instring; \ 37418334Speter while ((element_name = strsep(&element, ",")) != NULL) { \ 37518334Speter element_data = element_name; \ 37618334Speter element_name = strsep(&element_data, "/"); \ 37718334Speter if (element_data == NULL) { \ 37818334Speter error = EINVAL; \ 37918334Speter break; \ 38018334Speter } \ 38118334Speter claimed = 0; \ 38218334Speter MAC_CHECK(internalize_ ## type, label, element_name, \ 38318334Speter element_data, &claimed); \ 38418334Speter if (error) \ 38518334Speter break; \ 38618334Speter if (claimed != 1) { \ 38718334Speter /* XXXMAC: Another error here? */ \ 38818334Speter error = EINVAL; \ 38918334Speter break; \ 39018334Speter } \ 39118334Speter } \ 39218334Speter} while (0) 39318334Speter 39418334Speter/* 39518334Speter * MAC_PERFORM performs the designated operation by walking the policy 39618334Speter * module list and invoking that operation for each policy. 39718334Speter */ 39818334Speter#define MAC_PERFORM(operation, args...) do { \ 39918334Speter struct mac_policy_conf *mpc; \ 40018334Speter \ 40118334Speter MAC_POLICY_LIST_BUSY(); \ 40218334Speter LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 40318334Speter if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 40418334Speter mpc->mpc_ops->mpo_ ## operation (args); \ 40518334Speter } \ 40618334Speter MAC_POLICY_LIST_UNBUSY(); \ 40718334Speter} while (0) 40818334Speter 40918334Speter/* 41018334Speter * Initialize the MAC subsystem, including appropriate SMP locks. 41118334Speter */ 41218334Speterstatic void 41318334Spetermac_init(void) 41418334Speter{ 41518334Speter 41618334Speter LIST_INIT(&mac_policy_list); 41718334Speter MAC_POLICY_LIST_LOCKINIT(); 41818334Speter} 41918334Speter 42018334Speter/* 42118334Speter * For the purposes of modules that want to know if they were loaded 42218334Speter * "early", set the mac_late flag once we've processed modules either 42318334Speter * linked into the kernel, or loaded before the kernel startup. 42418334Speter */ 42518334Speterstatic void 42618334Spetermac_late_init(void) 42718334Speter{ 42818334Speter 42918334Speter mac_late = 1; 43018334Speter} 43118334Speter 43218334Speter/* 43318334Speter * Allow MAC policy modules to register during boot, etc. 43418334Speter */ 43518334Speterint 43618334Spetermac_policy_modevent(module_t mod, int type, void *data) 43718334Speter{ 43818334Speter struct mac_policy_conf *mpc; 43918334Speter int error; 44018334Speter 44118334Speter error = 0; 44218334Speter mpc = (struct mac_policy_conf *) data; 44318334Speter 44418334Speter switch (type) { 44518334Speter case MOD_LOAD: 44618334Speter if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && 44718334Speter mac_late) { 44818334Speter printf("mac_policy_modevent: can't load %s policy " 44918334Speter "after booting\n", mpc->mpc_name); 45018334Speter error = EBUSY; 45118334Speter break; 45218334Speter } 45318334Speter error = mac_policy_register(mpc); 45418334Speter break; 45518334Speter case MOD_UNLOAD: 45618334Speter /* Don't unregister the module if it was never registered. */ 45718334Speter if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) 45818334Speter != 0) 45918334Speter error = mac_policy_unregister(mpc); 46018334Speter else 46118334Speter error = 0; 46218334Speter break; 46318334Speter default: 46418334Speter break; 46518334Speter } 46618334Speter 46718334Speter return (error); 46818334Speter} 46918334Speter 47018334Speterstatic int 47118334Spetermac_policy_register(struct mac_policy_conf *mpc) 47218334Speter{ 47318334Speter struct mac_policy_conf *tmpc; 47418334Speter struct mac_policy_op_entry *mpe; 47518334Speter int slot; 47618334Speter 47718334Speter MALLOC(mpc->mpc_ops, struct mac_policy_ops *, sizeof(*mpc->mpc_ops), 47818334Speter M_MACOPVEC, M_WAITOK | M_ZERO); 47918334Speter for (mpe = mpc->mpc_entries; mpe->mpe_constant != MAC_OP_LAST; mpe++) { 48018334Speter switch (mpe->mpe_constant) { 48118334Speter case MAC_OP_LAST: 48218334Speter /* 48318334Speter * Doesn't actually happen, but this allows checking 48418334Speter * that all enumerated values are handled. 48518334Speter */ 48618334Speter break; 48718334Speter case MAC_DESTROY: 48818334Speter mpc->mpc_ops->mpo_destroy = 48918334Speter mpe->mpe_function; 49018334Speter break; 49118334Speter case MAC_INIT: 49218334Speter mpc->mpc_ops->mpo_init = 49318334Speter mpe->mpe_function; 49418334Speter break; 49518334Speter case MAC_SYSCALL: 49618334Speter mpc->mpc_ops->mpo_syscall = 49718334Speter mpe->mpe_function; 49818334Speter break; 49918334Speter case MAC_INIT_BPFDESC_LABEL: 50018334Speter mpc->mpc_ops->mpo_init_bpfdesc_label = 50118334Speter mpe->mpe_function; 50218334Speter break; 50318334Speter case MAC_INIT_CRED_LABEL: 50418334Speter mpc->mpc_ops->mpo_init_cred_label = 50518334Speter mpe->mpe_function; 50618334Speter break; 50718334Speter case MAC_INIT_DEVFSDIRENT_LABEL: 50818334Speter mpc->mpc_ops->mpo_init_devfsdirent_label = 50918334Speter mpe->mpe_function; 51018334Speter break; 51118334Speter case MAC_INIT_IFNET_LABEL: 51218334Speter mpc->mpc_ops->mpo_init_ifnet_label = 51318334Speter mpe->mpe_function; 51418334Speter break; 51518334Speter case MAC_INIT_IPQ_LABEL: 51618334Speter mpc->mpc_ops->mpo_init_ipq_label = 51718334Speter mpe->mpe_function; 51818334Speter break; 51918334Speter case MAC_INIT_MBUF_LABEL: 52018334Speter mpc->mpc_ops->mpo_init_mbuf_label = 52118334Speter mpe->mpe_function; 52218334Speter break; 52318334Speter case MAC_INIT_MOUNT_LABEL: 52418334Speter mpc->mpc_ops->mpo_init_mount_label = 52518334Speter mpe->mpe_function; 52618334Speter break; 52718334Speter case MAC_INIT_MOUNT_FS_LABEL: 52818334Speter mpc->mpc_ops->mpo_init_mount_fs_label = 52918334Speter mpe->mpe_function; 53018334Speter break; 53118334Speter case MAC_INIT_PIPE_LABEL: 53218334Speter mpc->mpc_ops->mpo_init_pipe_label = 53318334Speter mpe->mpe_function; 53418334Speter break; 53518334Speter case MAC_INIT_SOCKET_LABEL: 53618334Speter mpc->mpc_ops->mpo_init_socket_label = 53718334Speter mpe->mpe_function; 53818334Speter break; 53918334Speter case MAC_INIT_SOCKET_PEER_LABEL: 54018334Speter mpc->mpc_ops->mpo_init_socket_peer_label = 54118334Speter mpe->mpe_function; 54218334Speter break; 54318334Speter case MAC_INIT_VNODE_LABEL: 54418334Speter mpc->mpc_ops->mpo_init_vnode_label = 54518334Speter mpe->mpe_function; 54618334Speter break; 54718334Speter case MAC_DESTROY_BPFDESC_LABEL: 54818334Speter mpc->mpc_ops->mpo_destroy_bpfdesc_label = 54918334Speter mpe->mpe_function; 55018334Speter break; 55118334Speter case MAC_DESTROY_CRED_LABEL: 55218334Speter mpc->mpc_ops->mpo_destroy_cred_label = 55318334Speter mpe->mpe_function; 55418334Speter break; 55518334Speter case MAC_DESTROY_DEVFSDIRENT_LABEL: 55618334Speter mpc->mpc_ops->mpo_destroy_devfsdirent_label = 55718334Speter mpe->mpe_function; 55818334Speter break; 55918334Speter case MAC_DESTROY_IFNET_LABEL: 56018334Speter mpc->mpc_ops->mpo_destroy_ifnet_label = 56118334Speter mpe->mpe_function; 56218334Speter break; 56318334Speter case MAC_DESTROY_IPQ_LABEL: 56418334Speter mpc->mpc_ops->mpo_destroy_ipq_label = 56518334Speter mpe->mpe_function; 56618334Speter break; 56718334Speter case MAC_DESTROY_MBUF_LABEL: 56818334Speter mpc->mpc_ops->mpo_destroy_mbuf_label = 56918334Speter mpe->mpe_function; 57018334Speter break; 57118334Speter case MAC_DESTROY_MOUNT_LABEL: 57218334Speter mpc->mpc_ops->mpo_destroy_mount_label = 57318334Speter mpe->mpe_function; 57418334Speter break; 57518334Speter case MAC_DESTROY_MOUNT_FS_LABEL: 57618334Speter mpc->mpc_ops->mpo_destroy_mount_fs_label = 57718334Speter mpe->mpe_function; 57818334Speter break; 57918334Speter case MAC_DESTROY_PIPE_LABEL: 58018334Speter mpc->mpc_ops->mpo_destroy_pipe_label = 58118334Speter mpe->mpe_function; 58218334Speter break; 58318334Speter case MAC_DESTROY_SOCKET_LABEL: 58418334Speter mpc->mpc_ops->mpo_destroy_socket_label = 58518334Speter mpe->mpe_function; 58618334Speter break; 58718334Speter case MAC_DESTROY_SOCKET_PEER_LABEL: 58818334Speter mpc->mpc_ops->mpo_destroy_socket_peer_label = 58918334Speter mpe->mpe_function; 59018334Speter break; 59118334Speter case MAC_DESTROY_VNODE_LABEL: 59218334Speter mpc->mpc_ops->mpo_destroy_vnode_label = 59318334Speter mpe->mpe_function; 59418334Speter break; 59518334Speter case MAC_COPY_PIPE_LABEL: 59618334Speter mpc->mpc_ops->mpo_copy_pipe_label = 59718334Speter mpe->mpe_function; 59818334Speter break; 59918334Speter case MAC_COPY_VNODE_LABEL: 60018334Speter mpc->mpc_ops->mpo_copy_vnode_label = 60118334Speter mpe->mpe_function; 60218334Speter break; 60318334Speter case MAC_EXTERNALIZE_CRED_LABEL: 60418334Speter mpc->mpc_ops->mpo_externalize_cred_label = 60518334Speter mpe->mpe_function; 60618334Speter break; 60718334Speter case MAC_EXTERNALIZE_IFNET_LABEL: 60818334Speter mpc->mpc_ops->mpo_externalize_ifnet_label = 60918334Speter mpe->mpe_function; 61018334Speter break; 61118334Speter case MAC_EXTERNALIZE_PIPE_LABEL: 61218334Speter mpc->mpc_ops->mpo_externalize_pipe_label = 61318334Speter mpe->mpe_function; 61418334Speter break; 61518334Speter case MAC_EXTERNALIZE_SOCKET_LABEL: 61618334Speter mpc->mpc_ops->mpo_externalize_socket_label = 61718334Speter mpe->mpe_function; 61818334Speter break; 61918334Speter case MAC_EXTERNALIZE_SOCKET_PEER_LABEL: 62018334Speter mpc->mpc_ops->mpo_externalize_socket_peer_label = 62118334Speter mpe->mpe_function; 62218334Speter break; 62318334Speter case MAC_EXTERNALIZE_VNODE_LABEL: 62418334Speter mpc->mpc_ops->mpo_externalize_vnode_label = 62518334Speter mpe->mpe_function; 62618334Speter break; 62718334Speter case MAC_INTERNALIZE_CRED_LABEL: 62818334Speter mpc->mpc_ops->mpo_internalize_cred_label = 62918334Speter mpe->mpe_function; 63018334Speter break; 63118334Speter case MAC_INTERNALIZE_IFNET_LABEL: 63218334Speter mpc->mpc_ops->mpo_internalize_ifnet_label = 63318334Speter mpe->mpe_function; 63418334Speter break; 63518334Speter case MAC_INTERNALIZE_PIPE_LABEL: 63618334Speter mpc->mpc_ops->mpo_internalize_pipe_label = 63718334Speter mpe->mpe_function; 63818334Speter break; 63918334Speter case MAC_INTERNALIZE_SOCKET_LABEL: 64018334Speter mpc->mpc_ops->mpo_internalize_socket_label = 64118334Speter mpe->mpe_function; 64218334Speter break; 64318334Speter case MAC_INTERNALIZE_VNODE_LABEL: 64418334Speter mpc->mpc_ops->mpo_internalize_vnode_label = 64518334Speter mpe->mpe_function; 64618334Speter break; 64718334Speter case MAC_CREATE_DEVFS_DEVICE: 64818334Speter mpc->mpc_ops->mpo_create_devfs_device = 64918334Speter mpe->mpe_function; 65018334Speter break; 65118334Speter case MAC_CREATE_DEVFS_DIRECTORY: 65218334Speter mpc->mpc_ops->mpo_create_devfs_directory = 65318334Speter mpe->mpe_function; 65418334Speter break; 65518334Speter case MAC_CREATE_DEVFS_SYMLINK: 65618334Speter mpc->mpc_ops->mpo_create_devfs_symlink = 65718334Speter mpe->mpe_function; 65818334Speter break; 65918334Speter case MAC_CREATE_DEVFS_VNODE: 66018334Speter mpc->mpc_ops->mpo_create_devfs_vnode = 66118334Speter mpe->mpe_function; 66218334Speter break; 66318334Speter case MAC_CREATE_MOUNT: 66418334Speter mpc->mpc_ops->mpo_create_mount = 66518334Speter mpe->mpe_function; 66618334Speter break; 66718334Speter case MAC_CREATE_ROOT_MOUNT: 66818334Speter mpc->mpc_ops->mpo_create_root_mount = 66918334Speter mpe->mpe_function; 67018334Speter break; 67118334Speter case MAC_RELABEL_VNODE: 67218334Speter mpc->mpc_ops->mpo_relabel_vnode = 67318334Speter mpe->mpe_function; 67418334Speter break; 67518334Speter case MAC_UPDATE_DEVFSDIRENT: 67618334Speter mpc->mpc_ops->mpo_update_devfsdirent = 67718334Speter mpe->mpe_function; 67818334Speter break; 67918334Speter case MAC_ASSOCIATE_VNODE_DEVFS: 68018334Speter mpc->mpc_ops->mpo_associate_vnode_devfs = 68118334Speter mpe->mpe_function; 68218334Speter break; 68318334Speter case MAC_ASSOCIATE_VNODE_EXTATTR: 68418334Speter mpc->mpc_ops->mpo_associate_vnode_extattr = 68518334Speter mpe->mpe_function; 68618334Speter break; 68718334Speter case MAC_ASSOCIATE_VNODE_SINGLELABEL: 68818334Speter mpc->mpc_ops->mpo_associate_vnode_singlelabel = 68918334Speter mpe->mpe_function; 69018334Speter break; 69118334Speter case MAC_CREATE_VNODE_EXTATTR: 69218334Speter mpc->mpc_ops->mpo_create_vnode_extattr = 69318334Speter mpe->mpe_function; 69418334Speter break; 69518334Speter case MAC_SETLABEL_VNODE_EXTATTR: 69618334Speter mpc->mpc_ops->mpo_setlabel_vnode_extattr = 69718334Speter mpe->mpe_function; 69818334Speter break; 69918334Speter case MAC_CREATE_MBUF_FROM_SOCKET: 70018334Speter mpc->mpc_ops->mpo_create_mbuf_from_socket = 70118334Speter mpe->mpe_function; 70218334Speter break; 70318334Speter case MAC_CREATE_PIPE: 70418334Speter mpc->mpc_ops->mpo_create_pipe = 70518334Speter mpe->mpe_function; 70618334Speter break; 70718334Speter case MAC_CREATE_SOCKET: 70818334Speter mpc->mpc_ops->mpo_create_socket = 70918334Speter mpe->mpe_function; 71018334Speter break; 71118334Speter case MAC_CREATE_SOCKET_FROM_SOCKET: 71218334Speter mpc->mpc_ops->mpo_create_socket_from_socket = 71318334Speter mpe->mpe_function; 71418334Speter break; 71518334Speter case MAC_RELABEL_PIPE: 71618334Speter mpc->mpc_ops->mpo_relabel_pipe = 71718334Speter mpe->mpe_function; 71818334Speter break; 71918334Speter case MAC_RELABEL_SOCKET: 72018334Speter mpc->mpc_ops->mpo_relabel_socket = 72118334Speter mpe->mpe_function; 72218334Speter break; 72318334Speter case MAC_SET_SOCKET_PEER_FROM_MBUF: 72418334Speter mpc->mpc_ops->mpo_set_socket_peer_from_mbuf = 72518334Speter mpe->mpe_function; 72618334Speter break; 72718334Speter case MAC_SET_SOCKET_PEER_FROM_SOCKET: 72818334Speter mpc->mpc_ops->mpo_set_socket_peer_from_socket = 72918334Speter mpe->mpe_function; 73018334Speter break; 73118334Speter case MAC_CREATE_BPFDESC: 73218334Speter mpc->mpc_ops->mpo_create_bpfdesc = 73318334Speter mpe->mpe_function; 73418334Speter break; 73518334Speter case MAC_CREATE_DATAGRAM_FROM_IPQ: 73618334Speter mpc->mpc_ops->mpo_create_datagram_from_ipq = 73718334Speter mpe->mpe_function; 73818334Speter break; 73918334Speter case MAC_CREATE_FRAGMENT: 74018334Speter mpc->mpc_ops->mpo_create_fragment = 74118334Speter mpe->mpe_function; 74218334Speter break; 74318334Speter case MAC_CREATE_IFNET: 74418334Speter mpc->mpc_ops->mpo_create_ifnet = 74518334Speter mpe->mpe_function; 74618334Speter break; 74718334Speter case MAC_CREATE_IPQ: 74818334Speter mpc->mpc_ops->mpo_create_ipq = 74918334Speter mpe->mpe_function; 75018334Speter break; 75118334Speter case MAC_CREATE_MBUF_FROM_MBUF: 75218334Speter mpc->mpc_ops->mpo_create_mbuf_from_mbuf = 75318334Speter mpe->mpe_function; 75418334Speter break; 75518334Speter case MAC_CREATE_MBUF_LINKLAYER: 75618334Speter mpc->mpc_ops->mpo_create_mbuf_linklayer = 75718334Speter mpe->mpe_function; 75818334Speter break; 75918334Speter case MAC_CREATE_MBUF_FROM_BPFDESC: 76018334Speter mpc->mpc_ops->mpo_create_mbuf_from_bpfdesc = 76118334Speter mpe->mpe_function; 76218334Speter break; 76318334Speter case MAC_CREATE_MBUF_FROM_IFNET: 76418334Speter mpc->mpc_ops->mpo_create_mbuf_from_ifnet = 76518334Speter mpe->mpe_function; 76618334Speter break; 76718334Speter case MAC_CREATE_MBUF_MULTICAST_ENCAP: 76818334Speter mpc->mpc_ops->mpo_create_mbuf_multicast_encap = 76918334Speter mpe->mpe_function; 77018334Speter break; 77118334Speter case MAC_CREATE_MBUF_NETLAYER: 77218334Speter mpc->mpc_ops->mpo_create_mbuf_netlayer = 77318334Speter mpe->mpe_function; 77418334Speter break; 77518334Speter case MAC_FRAGMENT_MATCH: 77618334Speter mpc->mpc_ops->mpo_fragment_match = 77718334Speter mpe->mpe_function; 77818334Speter break; 77918334Speter case MAC_RELABEL_IFNET: 78018334Speter mpc->mpc_ops->mpo_relabel_ifnet = 78118334Speter mpe->mpe_function; 78218334Speter break; 78318334Speter case MAC_UPDATE_IPQ: 78418334Speter mpc->mpc_ops->mpo_update_ipq = 78518334Speter mpe->mpe_function; 78618334Speter break; 78718334Speter case MAC_CREATE_CRED: 78818334Speter mpc->mpc_ops->mpo_create_cred = 78918334Speter mpe->mpe_function; 79018334Speter break; 79118334Speter case MAC_EXECVE_TRANSITION: 79218334Speter mpc->mpc_ops->mpo_execve_transition = 79318334Speter mpe->mpe_function; 79418334Speter break; 79518334Speter case MAC_EXECVE_WILL_TRANSITION: 79618334Speter mpc->mpc_ops->mpo_execve_will_transition = 79718334Speter mpe->mpe_function; 79818334Speter break; 79918334Speter case MAC_CREATE_PROC0: 80018334Speter mpc->mpc_ops->mpo_create_proc0 = 80118334Speter mpe->mpe_function; 80218334Speter break; 80318334Speter case MAC_CREATE_PROC1: 80418334Speter mpc->mpc_ops->mpo_create_proc1 = 80518334Speter mpe->mpe_function; 80618334Speter break; 80718334Speter case MAC_RELABEL_CRED: 80818334Speter mpc->mpc_ops->mpo_relabel_cred = 80918334Speter mpe->mpe_function; 81018334Speter break; 81118334Speter case MAC_THREAD_USERRET: 81218334Speter mpc->mpc_ops->mpo_thread_userret = 81318334Speter mpe->mpe_function; 81418334Speter break; 81518334Speter case MAC_CHECK_BPFDESC_RECEIVE: 81618334Speter mpc->mpc_ops->mpo_check_bpfdesc_receive = 81718334Speter mpe->mpe_function; 81818334Speter break; 81918334Speter case MAC_CHECK_CRED_RELABEL: 82018334Speter mpc->mpc_ops->mpo_check_cred_relabel = 82118334Speter mpe->mpe_function; 82218334Speter break; 82318334Speter case MAC_CHECK_CRED_VISIBLE: 82418334Speter mpc->mpc_ops->mpo_check_cred_visible = 82518334Speter mpe->mpe_function; 82618334Speter break; 82718334Speter case MAC_CHECK_IFNET_RELABEL: 82818334Speter mpc->mpc_ops->mpo_check_ifnet_relabel = 82918334Speter mpe->mpe_function; 83018334Speter break; 83118334Speter case MAC_CHECK_IFNET_TRANSMIT: 83218334Speter mpc->mpc_ops->mpo_check_ifnet_transmit = 83318334Speter mpe->mpe_function; 83418334Speter break; 83518334Speter case MAC_CHECK_MOUNT_STAT: 83618334Speter mpc->mpc_ops->mpo_check_mount_stat = 83718334Speter mpe->mpe_function; 83818334Speter break; 83918334Speter case MAC_CHECK_PIPE_IOCTL: 84018334Speter mpc->mpc_ops->mpo_check_pipe_ioctl = 84118334Speter mpe->mpe_function; 84218334Speter break; 84318334Speter case MAC_CHECK_PIPE_POLL: 84418334Speter mpc->mpc_ops->mpo_check_pipe_poll = 84518334Speter mpe->mpe_function; 84618334Speter break; 84718334Speter case MAC_CHECK_PIPE_READ: 84818334Speter mpc->mpc_ops->mpo_check_pipe_read = 84918334Speter mpe->mpe_function; 85018334Speter break; 85118334Speter case MAC_CHECK_PIPE_RELABEL: 85218334Speter mpc->mpc_ops->mpo_check_pipe_relabel = 85318334Speter mpe->mpe_function; 85418334Speter break; 85518334Speter case MAC_CHECK_PIPE_STAT: 85618334Speter mpc->mpc_ops->mpo_check_pipe_stat = 85718334Speter mpe->mpe_function; 85818334Speter break; 85918334Speter case MAC_CHECK_PIPE_WRITE: 86018334Speter mpc->mpc_ops->mpo_check_pipe_write = 86118334Speter mpe->mpe_function; 86218334Speter break; 86318334Speter case MAC_CHECK_PROC_DEBUG: 86418334Speter mpc->mpc_ops->mpo_check_proc_debug = 86518334Speter mpe->mpe_function; 86618334Speter break; 86718334Speter case MAC_CHECK_PROC_SCHED: 86818334Speter mpc->mpc_ops->mpo_check_proc_sched = 86918334Speter mpe->mpe_function; 87018334Speter break; 87118334Speter case MAC_CHECK_PROC_SIGNAL: 87218334Speter mpc->mpc_ops->mpo_check_proc_signal = 87318334Speter mpe->mpe_function; 87418334Speter break; 87518334Speter case MAC_CHECK_SOCKET_BIND: 87618334Speter mpc->mpc_ops->mpo_check_socket_bind = 87718334Speter mpe->mpe_function; 87818334Speter break; 87918334Speter case MAC_CHECK_SOCKET_CONNECT: 88018334Speter mpc->mpc_ops->mpo_check_socket_connect = 88118334Speter mpe->mpe_function; 88218334Speter break; 88318334Speter case MAC_CHECK_SOCKET_DELIVER: 88418334Speter mpc->mpc_ops->mpo_check_socket_deliver = 88518334Speter mpe->mpe_function; 88618334Speter break; 88718334Speter case MAC_CHECK_SOCKET_LISTEN: 88818334Speter mpc->mpc_ops->mpo_check_socket_listen = 88918334Speter mpe->mpe_function; 89018334Speter break; 89118334Speter case MAC_CHECK_SOCKET_RECEIVE: 89218334Speter mpc->mpc_ops->mpo_check_socket_receive = 89318334Speter mpe->mpe_function; 89418334Speter break; 89518334Speter case MAC_CHECK_SOCKET_RELABEL: 89618334Speter mpc->mpc_ops->mpo_check_socket_relabel = 89718334Speter mpe->mpe_function; 89818334Speter break; 89918334Speter case MAC_CHECK_SOCKET_SEND: 90018334Speter mpc->mpc_ops->mpo_check_socket_send = 90118334Speter mpe->mpe_function; 90218334Speter break; 90318334Speter case MAC_CHECK_SOCKET_VISIBLE: 90418334Speter mpc->mpc_ops->mpo_check_socket_visible = 90518334Speter mpe->mpe_function; 90618334Speter break; 90718334Speter case MAC_CHECK_SYSTEM_REBOOT: 90818334Speter mpc->mpc_ops->mpo_check_system_reboot = 90918334Speter mpe->mpe_function; 91018334Speter break; 91118334Speter case MAC_CHECK_SYSTEM_SWAPON: 91218334Speter mpc->mpc_ops->mpo_check_system_swapon = 91318334Speter mpe->mpe_function; 91418334Speter break; 91518334Speter case MAC_CHECK_VNODE_ACCESS: 91618334Speter mpc->mpc_ops->mpo_check_vnode_access = 91718334Speter mpe->mpe_function; 91818334Speter break; 91918334Speter case MAC_CHECK_VNODE_CHDIR: 92018334Speter mpc->mpc_ops->mpo_check_vnode_chdir = 92118334Speter mpe->mpe_function; 92218334Speter break; 92318334Speter case MAC_CHECK_VNODE_CHROOT: 92418334Speter mpc->mpc_ops->mpo_check_vnode_chroot = 92518334Speter mpe->mpe_function; 92618334Speter break; 92718334Speter case MAC_CHECK_VNODE_CREATE: 92818334Speter mpc->mpc_ops->mpo_check_vnode_create = 92918334Speter mpe->mpe_function; 93018334Speter break; 93118334Speter case MAC_CHECK_VNODE_DELETE: 93218334Speter mpc->mpc_ops->mpo_check_vnode_delete = 93318334Speter mpe->mpe_function; 93418334Speter break; 93518334Speter case MAC_CHECK_VNODE_DELETEACL: 93618334Speter mpc->mpc_ops->mpo_check_vnode_deleteacl = 93718334Speter mpe->mpe_function; 93818334Speter break; 93918334Speter case MAC_CHECK_VNODE_EXEC: 94018334Speter mpc->mpc_ops->mpo_check_vnode_exec = 94118334Speter mpe->mpe_function; 94218334Speter break; 94318334Speter case MAC_CHECK_VNODE_GETACL: 94418334Speter mpc->mpc_ops->mpo_check_vnode_getacl = 94518334Speter mpe->mpe_function; 94618334Speter break; 94718334Speter case MAC_CHECK_VNODE_GETEXTATTR: 94818334Speter mpc->mpc_ops->mpo_check_vnode_getextattr = 94918334Speter mpe->mpe_function; 95018334Speter break; 95118334Speter case MAC_CHECK_VNODE_LINK: 95218334Speter mpc->mpc_ops->mpo_check_vnode_link = 95318334Speter mpe->mpe_function; 95418334Speter break; 95518334Speter case MAC_CHECK_VNODE_LOOKUP: 95618334Speter mpc->mpc_ops->mpo_check_vnode_lookup = 95718334Speter mpe->mpe_function; 95818334Speter break; 95918334Speter case MAC_CHECK_VNODE_MMAP: 96018334Speter mpc->mpc_ops->mpo_check_vnode_mmap = 96118334Speter mpe->mpe_function; 96218334Speter break; 96318334Speter case MAC_CHECK_VNODE_MMAP_DOWNGRADE: 96418334Speter mpc->mpc_ops->mpo_check_vnode_mmap_downgrade = 96518334Speter mpe->mpe_function; 96618334Speter break; 96718334Speter case MAC_CHECK_VNODE_MPROTECT: 96818334Speter mpc->mpc_ops->mpo_check_vnode_mprotect = 96918334Speter mpe->mpe_function; 97018334Speter break; 97118334Speter case MAC_CHECK_VNODE_OPEN: 97218334Speter mpc->mpc_ops->mpo_check_vnode_open = 97318334Speter mpe->mpe_function; 97418334Speter break; 97518334Speter case MAC_CHECK_VNODE_POLL: 97618334Speter mpc->mpc_ops->mpo_check_vnode_poll = 97718334Speter mpe->mpe_function; 97818334Speter break; 97918334Speter case MAC_CHECK_VNODE_READ: 98018334Speter mpc->mpc_ops->mpo_check_vnode_read = 98118334Speter mpe->mpe_function; 98218334Speter break; 98318334Speter case MAC_CHECK_VNODE_READDIR: 98418334Speter mpc->mpc_ops->mpo_check_vnode_readdir = 98518334Speter mpe->mpe_function; 98618334Speter break; 98718334Speter case MAC_CHECK_VNODE_READLINK: 98818334Speter mpc->mpc_ops->mpo_check_vnode_readlink = 98918334Speter mpe->mpe_function; 99018334Speter break; 99118334Speter case MAC_CHECK_VNODE_RELABEL: 99218334Speter mpc->mpc_ops->mpo_check_vnode_relabel = 99318334Speter mpe->mpe_function; 99418334Speter break; 99518334Speter case MAC_CHECK_VNODE_RENAME_FROM: 99618334Speter mpc->mpc_ops->mpo_check_vnode_rename_from = 99718334Speter mpe->mpe_function; 99818334Speter break; 99918334Speter case MAC_CHECK_VNODE_RENAME_TO: 100018334Speter mpc->mpc_ops->mpo_check_vnode_rename_to = 100118334Speter mpe->mpe_function; 100218334Speter break; 100318334Speter case MAC_CHECK_VNODE_REVOKE: 100418334Speter mpc->mpc_ops->mpo_check_vnode_revoke = 100518334Speter mpe->mpe_function; 100618334Speter break; 100718334Speter case MAC_CHECK_VNODE_SETACL: 100818334Speter mpc->mpc_ops->mpo_check_vnode_setacl = 100918334Speter mpe->mpe_function; 101018334Speter break; 101118334Speter case MAC_CHECK_VNODE_SETEXTATTR: 101218334Speter mpc->mpc_ops->mpo_check_vnode_setextattr = 101318334Speter mpe->mpe_function; 101418334Speter break; 101518334Speter case MAC_CHECK_VNODE_SETFLAGS: 101618334Speter mpc->mpc_ops->mpo_check_vnode_setflags = 101718334Speter mpe->mpe_function; 101818334Speter break; 101918334Speter case MAC_CHECK_VNODE_SETMODE: 102018334Speter mpc->mpc_ops->mpo_check_vnode_setmode = 102118334Speter mpe->mpe_function; 102218334Speter break; 102318334Speter case MAC_CHECK_VNODE_SETOWNER: 102418334Speter mpc->mpc_ops->mpo_check_vnode_setowner = 102518334Speter mpe->mpe_function; 102618334Speter break; 102718334Speter case MAC_CHECK_VNODE_SETUTIMES: 102818334Speter mpc->mpc_ops->mpo_check_vnode_setutimes = 102918334Speter mpe->mpe_function; 103018334Speter break; 103118334Speter case MAC_CHECK_VNODE_STAT: 103218334Speter mpc->mpc_ops->mpo_check_vnode_stat = 103318334Speter mpe->mpe_function; 103418334Speter break; 103518334Speter case MAC_CHECK_VNODE_WRITE: 103618334Speter mpc->mpc_ops->mpo_check_vnode_write = 103718334Speter mpe->mpe_function; 103818334Speter break; 103918334Speter/* 104018334Speter default: 104118334Speter printf("MAC policy `%s': unknown operation %d\n", 104218334Speter mpc->mpc_name, mpe->mpe_constant); 104318334Speter return (EINVAL); 104418334Speter*/ 104518334Speter } 104618334Speter } 104718334Speter MAC_POLICY_LIST_LOCK(); 104818334Speter if (mac_policy_list_busy > 0) { 104918334Speter MAC_POLICY_LIST_UNLOCK(); 105018334Speter FREE(mpc->mpc_ops, M_MACOPVEC); 105118334Speter mpc->mpc_ops = NULL; 105218334Speter return (EBUSY); 105318334Speter } 105418334Speter LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 105518334Speter if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 105618334Speter MAC_POLICY_LIST_UNLOCK(); 105718334Speter FREE(mpc->mpc_ops, M_MACOPVEC); 105818334Speter mpc->mpc_ops = NULL; 105918334Speter return (EEXIST); 106018334Speter } 106118334Speter } 106218334Speter if (mpc->mpc_field_off != NULL) { 106318334Speter slot = ffs(mac_policy_offsets_free); 106418334Speter if (slot == 0) { 106518334Speter MAC_POLICY_LIST_UNLOCK(); 106618334Speter FREE(mpc->mpc_ops, M_MACOPVEC); 106718334Speter mpc->mpc_ops = NULL; 106818334Speter return (ENOMEM); 106918334Speter } 107018334Speter slot--; 107118334Speter mac_policy_offsets_free &= ~(1 << slot); 107218334Speter *mpc->mpc_field_off = slot; 107318334Speter } 107418334Speter mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; 107518334Speter LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); 107618334Speter 107718334Speter /* Per-policy initialization. */ 107818334Speter if (mpc->mpc_ops->mpo_init != NULL) 107918334Speter (*(mpc->mpc_ops->mpo_init))(mpc); 108018334Speter MAC_POLICY_LIST_UNLOCK(); 108118334Speter 108218334Speter printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, 108318334Speter mpc->mpc_name); 108418334Speter 108518334Speter return (0); 108618334Speter} 108718334Speter 108818334Speterstatic int 108918334Spetermac_policy_unregister(struct mac_policy_conf *mpc) 109018334Speter{ 109118334Speter 109218334Speter /* 109318334Speter * If we fail the load, we may get a request to unload. Check 109418334Speter * to see if we did the run-time registration, and if not, 109518334Speter * silently succeed. 109618334Speter */ 109718334Speter MAC_POLICY_LIST_LOCK(); 109818334Speter if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) { 109918334Speter MAC_POLICY_LIST_UNLOCK(); 110018334Speter return (0); 110118334Speter } 110218334Speter#if 0 110318334Speter /* 110418334Speter * Don't allow unloading modules with private data. 110518334Speter */ 110618334Speter if (mpc->mpc_field_off != NULL) { 110718334Speter MAC_POLICY_LIST_UNLOCK(); 110818334Speter return (EBUSY); 110918334Speter } 111018334Speter#endif 111118334Speter /* 111218334Speter * Only allow the unload to proceed if the module is unloadable 111318334Speter * by its own definition. 111418334Speter */ 111518334Speter if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) { 111618334Speter MAC_POLICY_LIST_UNLOCK(); 111718334Speter return (EBUSY); 111818334Speter } 111918334Speter /* 112018334Speter * Right now, we EBUSY if the list is in use. In the future, 112118334Speter * for reliability reasons, we might want to sleep and wakeup 112218334Speter * later to try again. 112318334Speter */ 112418334Speter if (mac_policy_list_busy > 0) { 112518334Speter MAC_POLICY_LIST_UNLOCK(); 112618334Speter return (EBUSY); 112718334Speter } 112818334Speter if (mpc->mpc_ops->mpo_destroy != NULL) 112918334Speter (*(mpc->mpc_ops->mpo_destroy))(mpc); 113018334Speter 113118334Speter LIST_REMOVE(mpc, mpc_list); 113218334Speter MAC_POLICY_LIST_UNLOCK(); 113318334Speter 113418334Speter FREE(mpc->mpc_ops, M_MACOPVEC); 113518334Speter mpc->mpc_ops = NULL; 113618334Speter mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED; 113718334Speter 113818334Speter printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, 113918334Speter mpc->mpc_name); 114018334Speter 114118334Speter return (0); 114218334Speter} 114318334Speter 114418334Speter/* 114518334Speter * Define an error value precedence, and given two arguments, selects the 114618334Speter * value with the higher precedence. 114718334Speter */ 114818334Speterstatic int 114918334Spetererror_select(int error1, int error2) 115018334Speter{ 115118334Speter 115218334Speter /* Certain decision-making errors take top priority. */ 115318334Speter if (error1 == EDEADLK || error2 == EDEADLK) 115418334Speter return (EDEADLK); 115518334Speter 115618334Speter /* Invalid arguments should be reported where possible. */ 115718334Speter if (error1 == EINVAL || error2 == EINVAL) 115818334Speter return (EINVAL); 115918334Speter 116018334Speter /* Precedence goes to "visibility", with both process and file. */ 116118334Speter if (error1 == ESRCH || error2 == ESRCH) 116218334Speter return (ESRCH); 116318334Speter 116418334Speter if (error1 == ENOENT || error2 == ENOENT) 116518334Speter return (ENOENT); 116618334Speter 116718334Speter /* Precedence goes to DAC/MAC protections. */ 116818334Speter if (error1 == EACCES || error2 == EACCES) 116918334Speter return (EACCES); 117018334Speter 117118334Speter /* Precedence goes to privilege. */ 117218334Speter if (error1 == EPERM || error2 == EPERM) 117318334Speter return (EPERM); 117418334Speter 117518334Speter /* Precedence goes to error over success; otherwise, arbitrary. */ 117618334Speter if (error1 != 0) 117718334Speter return (error1); 117818334Speter return (error2); 117918334Speter} 118018334Speter 118118334Speterstatic void 118218334Spetermac_init_label(struct label *label) 118318334Speter{ 118418334Speter 118518334Speter bzero(label, sizeof(*label)); 118618334Speter label->l_flags = MAC_FLAG_INITIALIZED; 118718334Speter} 118818334Speter 118918334Speterstatic void 119018334Spetermac_destroy_label(struct label *label) 119118334Speter{ 119218334Speter 119318334Speter KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 119418334Speter ("destroying uninitialized label")); 119518334Speter 119618334Speter bzero(label, sizeof(*label)); 119718334Speter /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 119818334Speter} 119918334Speter 120018334Spetervoid 120118334Spetermac_init_bpfdesc(struct bpf_d *bpf_d) 120218334Speter{ 120318334Speter 120418334Speter mac_init_label(&bpf_d->bd_label); 120518334Speter MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label); 120618334Speter#ifdef MAC_DEBUG 120718334Speter atomic_add_int(&nmacbpfdescs, 1); 120818334Speter#endif 120918334Speter} 121018334Speter 121118334Speterstatic void 121218334Spetermac_init_cred_label(struct label *label) 121318334Speter{ 121418334Speter 121518334Speter mac_init_label(label); 121618334Speter MAC_PERFORM(init_cred_label, label); 121718334Speter#ifdef MAC_DEBUG 121818334Speter atomic_add_int(&nmaccreds, 1); 121918334Speter#endif 122018334Speter} 122118334Speter 122218334Spetervoid 122318334Spetermac_init_cred(struct ucred *cred) 122418334Speter{ 122518334Speter 122618334Speter mac_init_cred_label(&cred->cr_label); 122718334Speter} 122818334Speter 122918334Spetervoid 123018334Spetermac_init_devfsdirent(struct devfs_dirent *de) 123118334Speter{ 123218334Speter 123318334Speter mac_init_label(&de->de_label); 123418334Speter MAC_PERFORM(init_devfsdirent_label, &de->de_label); 123518334Speter#ifdef MAC_DEBUG 123618334Speter atomic_add_int(&nmacdevfsdirents, 1); 123718334Speter#endif 123818334Speter} 123918334Speter 124018334Speterstatic void 124118334Spetermac_init_ifnet_label(struct label *label) 124218334Speter{ 124318334Speter 124418334Speter mac_init_label(label); 124518334Speter MAC_PERFORM(init_ifnet_label, label); 124618334Speter#ifdef MAC_DEBUG 124718334Speter atomic_add_int(&nmacifnets, 1); 124818334Speter#endif 124918334Speter} 125018334Speter 125118334Spetervoid 125218334Spetermac_init_ifnet(struct ifnet *ifp) 125318334Speter{ 125418334Speter 125518334Speter mac_init_ifnet_label(&ifp->if_label); 125618334Speter} 125718334Speter 125818334Spetervoid 125918334Spetermac_init_ipq(struct ipq *ipq) 126018334Speter{ 126118334Speter 126218334Speter mac_init_label(&ipq->ipq_label); 126318334Speter MAC_PERFORM(init_ipq_label, &ipq->ipq_label); 126418334Speter#ifdef MAC_DEBUG 126518334Speter atomic_add_int(&nmacipqs, 1); 126618334Speter#endif 126718334Speter} 126818334Speter 126918334Speterint 127018334Spetermac_init_mbuf(struct mbuf *m, int flag) 127118334Speter{ 127218334Speter int error; 127318334Speter 127418334Speter KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf")); 127518334Speter 127618334Speter mac_init_label(&m->m_pkthdr.label); 127718334Speter 127818334Speter MAC_CHECK(init_mbuf_label, &m->m_pkthdr.label, flag); 127918334Speter if (error) { 128018334Speter MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 128118334Speter mac_destroy_label(&m->m_pkthdr.label); 128218334Speter } 128318334Speter 128418334Speter#ifdef MAC_DEBUG 128518334Speter if (error == 0) 128618334Speter atomic_add_int(&nmacmbufs, 1); 128718334Speter#endif 128818334Speter return (error); 128918334Speter} 129018334Speter 129118334Spetervoid 129218334Spetermac_init_mount(struct mount *mp) 129318334Speter{ 129418334Speter 129518334Speter mac_init_label(&mp->mnt_mntlabel); 129618334Speter mac_init_label(&mp->mnt_fslabel); 129718334Speter MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel); 129818334Speter MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel); 129918334Speter#ifdef MAC_DEBUG 130018334Speter atomic_add_int(&nmacmounts, 1); 130118334Speter#endif 130218334Speter} 130318334Speter 130418334Speterstatic void 130518334Spetermac_init_pipe_label(struct label *label) 130618334Speter{ 130718334Speter 130818334Speter mac_init_label(label); 130918334Speter MAC_PERFORM(init_pipe_label, label); 131018334Speter#ifdef MAC_DEBUG 131118334Speter atomic_add_int(&nmacpipes, 1); 131218334Speter#endif 131318334Speter} 131418334Speter 131518334Spetervoid 131618334Spetermac_init_pipe(struct pipe *pipe) 131718334Speter{ 131818334Speter struct label *label; 131918334Speter 132018334Speter label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 132118334Speter pipe->pipe_label = label; 132218334Speter pipe->pipe_peer->pipe_label = label; 132318334Speter mac_init_pipe_label(label); 132418334Speter} 132518334Speter 132618334Speterstatic int 132718334Spetermac_init_socket_label(struct label *label, int flag) 132818334Speter{ 132918334Speter int error; 133018334Speter 133118334Speter mac_init_label(label); 133218334Speter 133318334Speter MAC_CHECK(init_socket_label, label, flag); 133418334Speter if (error) { 133518334Speter MAC_PERFORM(destroy_socket_label, label); 133618334Speter mac_destroy_label(label); 133718334Speter } 133818334Speter 133918334Speter#ifdef MAC_DEBUG 134018334Speter if (error == 0) 134118334Speter atomic_add_int(&nmacsockets, 1); 134218334Speter#endif 134318334Speter 134418334Speter return (error); 134518334Speter} 134618334Speter 134718334Speterstatic int 134818334Spetermac_init_socket_peer_label(struct label *label, int flag) 134918334Speter{ 135018334Speter int error; 135118334Speter 135218334Speter mac_init_label(label); 135318334Speter 135418334Speter MAC_CHECK(init_socket_peer_label, label, flag); 135518334Speter if (error) { 135618334Speter MAC_PERFORM(destroy_socket_label, label); 135718334Speter mac_destroy_label(label); 135818334Speter } 135918334Speter 136018334Speter return (error); 136118334Speter} 136218334Speter 136318334Speterint 136418334Spetermac_init_socket(struct socket *socket, int flag) 136518334Speter{ 136618334Speter int error; 136718334Speter 136818334Speter error = mac_init_socket_label(&socket->so_label, flag); 136918334Speter if (error) 137018334Speter return (error); 137118334Speter 137218334Speter error = mac_init_socket_peer_label(&socket->so_peerlabel, flag); 137318334Speter if (error) 137418334Speter mac_destroy_socket_label(&socket->so_label); 137518334Speter 137618334Speter return (error); 137718334Speter} 137818334Speter 137918334Spetervoid 138018334Spetermac_init_vnode_label(struct label *label) 138118334Speter{ 138218334Speter 138318334Speter mac_init_label(label); 138418334Speter MAC_PERFORM(init_vnode_label, label); 138518334Speter#ifdef MAC_DEBUG 138618334Speter atomic_add_int(&nmacvnodes, 1); 138718334Speter#endif 138818334Speter} 138918334Speter 139018334Spetervoid 139118334Spetermac_init_vnode(struct vnode *vp) 139218334Speter{ 139318334Speter 139418334Speter mac_init_vnode_label(&vp->v_label); 139518334Speter} 139618334Speter 139718334Spetervoid 139818334Spetermac_destroy_bpfdesc(struct bpf_d *bpf_d) 139918334Speter{ 140018334Speter 140118334Speter MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label); 140218334Speter mac_destroy_label(&bpf_d->bd_label); 140318334Speter#ifdef MAC_DEBUG 140418334Speter atomic_subtract_int(&nmacbpfdescs, 1); 140518334Speter#endif 140618334Speter} 140718334Speter 140818334Speterstatic void 140918334Spetermac_destroy_cred_label(struct label *label) 141018334Speter{ 141118334Speter 141218334Speter MAC_PERFORM(destroy_cred_label, label); 141318334Speter mac_destroy_label(label); 141418334Speter#ifdef MAC_DEBUG 141518334Speter atomic_subtract_int(&nmaccreds, 1); 141618334Speter#endif 141718334Speter} 141818334Speter 141918334Spetervoid 142018334Spetermac_destroy_cred(struct ucred *cred) 142118334Speter{ 142218334Speter 142318334Speter mac_destroy_cred_label(&cred->cr_label); 142418334Speter} 142518334Speter 142618334Spetervoid 142718334Spetermac_destroy_devfsdirent(struct devfs_dirent *de) 142818334Speter{ 142918334Speter 143018334Speter MAC_PERFORM(destroy_devfsdirent_label, &de->de_label); 143118334Speter mac_destroy_label(&de->de_label); 143218334Speter#ifdef MAC_DEBUG 143318334Speter atomic_subtract_int(&nmacdevfsdirents, 1); 143418334Speter#endif 143518334Speter} 143618334Speter 143718334Speterstatic void 143818334Spetermac_destroy_ifnet_label(struct label *label) 143918334Speter{ 144018334Speter 144118334Speter MAC_PERFORM(destroy_ifnet_label, label); 144218334Speter mac_destroy_label(label); 144318334Speter#ifdef MAC_DEBUG 144418334Speter atomic_subtract_int(&nmacifnets, 1); 144518334Speter#endif 144618334Speter} 144718334Speter 144818334Spetervoid 144918334Spetermac_destroy_ifnet(struct ifnet *ifp) 145018334Speter{ 145118334Speter 145218334Speter mac_destroy_ifnet_label(&ifp->if_label); 145318334Speter} 145418334Speter 145518334Spetervoid 145618334Spetermac_destroy_ipq(struct ipq *ipq) 145718334Speter{ 145818334Speter 145918334Speter MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 146018334Speter mac_destroy_label(&ipq->ipq_label); 146118334Speter#ifdef MAC_DEBUG 146218334Speter atomic_subtract_int(&nmacipqs, 1); 146318334Speter#endif 146418334Speter} 146518334Speter 146618334Spetervoid 146718334Spetermac_destroy_mbuf(struct mbuf *m) 146818334Speter{ 146918334Speter 147018334Speter MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 147118334Speter mac_destroy_label(&m->m_pkthdr.label); 147218334Speter#ifdef MAC_DEBUG 147318334Speter atomic_subtract_int(&nmacmbufs, 1); 147418334Speter#endif 147518334Speter} 147618334Speter 147718334Spetervoid 147818334Spetermac_destroy_mount(struct mount *mp) 147918334Speter{ 148018334Speter 148118334Speter MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel); 148218334Speter MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel); 148318334Speter mac_destroy_label(&mp->mnt_fslabel); 148418334Speter mac_destroy_label(&mp->mnt_mntlabel); 148518334Speter#ifdef MAC_DEBUG 148618334Speter atomic_subtract_int(&nmacmounts, 1); 148718334Speter#endif 148818334Speter} 148918334Speter 149018334Speterstatic void 149118334Spetermac_destroy_pipe_label(struct label *label) 149218334Speter{ 149318334Speter 149418334Speter MAC_PERFORM(destroy_pipe_label, label); 149518334Speter mac_destroy_label(label); 149618334Speter#ifdef MAC_DEBUG 149718334Speter atomic_subtract_int(&nmacpipes, 1); 149818334Speter#endif 149918334Speter} 150018334Speter 150118334Spetervoid 150218334Spetermac_destroy_pipe(struct pipe *pipe) 150318334Speter{ 150418334Speter 150518334Speter mac_destroy_pipe_label(pipe->pipe_label); 150618334Speter free(pipe->pipe_label, M_MACPIPELABEL); 150718334Speter} 150818334Speter 150918334Speterstatic void 151018334Spetermac_destroy_socket_label(struct label *label) 151118334Speter{ 151218334Speter 151318334Speter MAC_PERFORM(destroy_socket_label, label); 151418334Speter mac_destroy_label(label); 151518334Speter#ifdef MAC_DEBUG 151618334Speter atomic_subtract_int(&nmacsockets, 1); 151718334Speter#endif 151818334Speter} 151918334Speter 152018334Speterstatic void 152118334Spetermac_destroy_socket_peer_label(struct label *label) 152218334Speter{ 152318334Speter 152418334Speter MAC_PERFORM(destroy_socket_peer_label, label); 152518334Speter mac_destroy_label(label); 152618334Speter} 152718334Speter 152818334Spetervoid 152918334Spetermac_destroy_socket(struct socket *socket) 153018334Speter{ 153118334Speter 153218334Speter mac_destroy_socket_label(&socket->so_label); 153318334Speter mac_destroy_socket_peer_label(&socket->so_peerlabel); 153418334Speter} 153518334Speter 153618334Spetervoid 153718334Spetermac_destroy_vnode_label(struct label *label) 153818334Speter{ 153918334Speter 154018334Speter MAC_PERFORM(destroy_vnode_label, label); 154118334Speter mac_destroy_label(label); 154218334Speter#ifdef MAC_DEBUG 154318334Speter atomic_subtract_int(&nmacvnodes, 1); 154418334Speter#endif 154518334Speter} 154618334Speter 154718334Spetervoid 154818334Spetermac_destroy_vnode(struct vnode *vp) 154918334Speter{ 155018334Speter 155118334Speter mac_destroy_vnode_label(&vp->v_label); 155218334Speter} 155318334Speter 155418334Speterstatic void 155518334Spetermac_copy_pipe_label(struct label *src, struct label *dest) 155618334Speter{ 155718334Speter 155818334Speter MAC_PERFORM(copy_pipe_label, src, dest); 155918334Speter} 156018334Speter 156118334Spetervoid 156218334Spetermac_copy_vnode_label(struct label *src, struct label *dest) 156318334Speter{ 156418334Speter 156518334Speter MAC_PERFORM(copy_vnode_label, src, dest); 156618334Speter} 156718334Speter 156818334Speterstatic int 156918334Spetermac_check_structmac_consistent(struct mac *mac) 157018334Speter{ 157118334Speter 157218334Speter if (mac->m_buflen > MAC_MAX_LABEL_BUF_LEN) 157318334Speter return (EINVAL); 157418334Speter 157518334Speter return (0); 157618334Speter} 157718334Speter 157818334Speterstatic int 157918334Spetermac_externalize_cred_label(struct label *label, char *elements, 158018334Speter char *outbuf, size_t outbuflen, int flags) 158118334Speter{ 158218334Speter int error; 158318334Speter 158418334Speter MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen); 158518334Speter 158618334Speter return (error); 158718334Speter} 158818334Speter 158918334Speterstatic int 159018334Spetermac_externalize_ifnet_label(struct label *label, char *elements, 159118334Speter char *outbuf, size_t outbuflen, int flags) 159218334Speter{ 159318334Speter int error; 159418334Speter 159518334Speter MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen); 159618334Speter 159718334Speter return (error); 159818334Speter} 159918334Speter 160018334Speterstatic int 160118334Spetermac_externalize_pipe_label(struct label *label, char *elements, 160218334Speter char *outbuf, size_t outbuflen, int flags) 160318334Speter{ 160418334Speter int error; 160518334Speter 160618334Speter MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen); 160718334Speter 160818334Speter return (error); 160918334Speter} 161018334Speter 161118334Speterstatic int 161218334Spetermac_externalize_socket_label(struct label *label, char *elements, 161318334Speter char *outbuf, size_t outbuflen, int flags) 161418334Speter{ 161518334Speter int error; 161618334Speter 161718334Speter MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen); 161818334Speter 161918334Speter return (error); 162018334Speter} 162118334Speter 162218334Speterstatic int 162318334Spetermac_externalize_socket_peer_label(struct label *label, char *elements, 162418334Speter char *outbuf, size_t outbuflen, int flags) 162518334Speter{ 162618334Speter int error; 162718334Speter 162818334Speter MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen); 162918334Speter 163018334Speter return (error); 163118334Speter} 163218334Speter 163318334Speterstatic int 163418334Spetermac_externalize_vnode_label(struct label *label, char *elements, 163518334Speter char *outbuf, size_t outbuflen, int flags) 163618334Speter{ 163718334Speter int error; 163818334Speter 163918334Speter MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen); 164018334Speter 164118334Speter return (error); 164218334Speter} 164318334Speter 164418334Speterstatic int 164518334Spetermac_internalize_cred_label(struct label *label, char *string) 164618334Speter{ 164718334Speter int error; 164818334Speter 164918334Speter MAC_INTERNALIZE(cred_label, label, string); 165018334Speter 165118334Speter return (error); 165218334Speter} 165318334Speter 165418334Speterstatic int 165518334Spetermac_internalize_ifnet_label(struct label *label, char *string) 165618334Speter{ 165718334Speter int error; 165818334Speter 165918334Speter MAC_INTERNALIZE(ifnet_label, label, string); 166018334Speter 166118334Speter return (error); 166218334Speter} 166318334Speter 166418334Speterstatic int 166518334Spetermac_internalize_pipe_label(struct label *label, char *string) 166618334Speter{ 166718334Speter int error; 166818334Speter 166918334Speter MAC_INTERNALIZE(pipe_label, label, string); 167018334Speter 167118334Speter return (error); 167218334Speter} 167318334Speter 167418334Speterstatic int 167518334Spetermac_internalize_socket_label(struct label *label, char *string) 167618334Speter{ 167718334Speter int error; 167818334Speter 167918334Speter MAC_INTERNALIZE(socket_label, label, string); 168018334Speter 168118334Speter return (error); 168218334Speter} 168318334Speter 168418334Speterstatic int 168518334Spetermac_internalize_vnode_label(struct label *label, char *string) 168618334Speter{ 168718334Speter int error; 168818334Speter 168918334Speter MAC_INTERNALIZE(vnode_label, label, string); 169018334Speter 169118334Speter return (error); 169218334Speter} 169318334Speter 169418334Speter/* 169518334Speter * Initialize MAC label for the first kernel process, from which other 169618334Speter * kernel processes and threads are spawned. 169718334Speter */ 169818334Spetervoid 169918334Spetermac_create_proc0(struct ucred *cred) 170018334Speter{ 170118334Speter 170218334Speter MAC_PERFORM(create_proc0, cred); 170318334Speter} 170418334Speter 170518334Speter/* 170618334Speter * Initialize MAC label for the first userland process, from which other 170718334Speter * userland processes and threads are spawned. 170818334Speter */ 170918334Spetervoid 171018334Spetermac_create_proc1(struct ucred *cred) 171118334Speter{ 171218334Speter 171318334Speter MAC_PERFORM(create_proc1, cred); 171418334Speter} 171518334Speter 171618334Spetervoid 171718334Spetermac_thread_userret(struct thread *td) 171818334Speter{ 171918334Speter 172018334Speter MAC_PERFORM(thread_userret, td); 172118334Speter} 172218334Speter 172318334Speter/* 172418334Speter * When a new process is created, its label must be initialized. Generally, 172518334Speter * this involves inheritence from the parent process, modulo possible 172618334Speter * deltas. This function allows that processing to take place. 172718334Speter */ 172818334Spetervoid 172918334Spetermac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 173018334Speter{ 173118334Speter 173218334Speter MAC_PERFORM(create_cred, parent_cred, child_cred); 173318334Speter} 173418334Speter 173518334Spetervoid 173618334Spetermac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp) 173718334Speter{ 173818334Speter 173918334Speter MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label); 174018334Speter} 174118334Speter 174218334Spetervoid 174318334Spetermac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, 174418334Speter struct vnode *vp) 174518334Speter{ 174618334Speter 174718334Speter MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de, 174818334Speter &de->de_label, vp, &vp->v_label); 174918334Speter} 175018334Speter 175118334Speterint 175218334Spetermac_associate_vnode_extattr(struct mount *mp, struct vnode *vp) 175318334Speter{ 175418334Speter int error; 175518334Speter 175618334Speter ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr"); 175718334Speter 175818334Speter MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp, 175918334Speter &vp->v_label); 176018334Speter 176118334Speter return (error); 176218334Speter} 176318334Speter 176418334Spetervoid 176518334Spetermac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp) 176618334Speter{ 176718334Speter 176818334Speter MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp, 176918334Speter &vp->v_label); 177018334Speter} 177118334Speter 177218334Speterint 177318334Spetermac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 177418334Speter struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 177518334Speter{ 177618334Speter int error; 177718334Speter 177818334Speter ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr"); 177918334Speter ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr"); 178018334Speter 178118334Speter error = VOP_OPENEXTATTR(vp, cred, curthread); 178218334Speter if (error == EOPNOTSUPP) { 178318334Speter /* XXX: Optionally abort if transactions not supported. */ 178418334Speter if (ea_warn_once == 0) { 178518334Speter printf("Warning: transactions not supported " 178618334Speter "in EA write.\n"); 178718334Speter ea_warn_once = 1; 178818334Speter } 178918334Speter } else if (error) 179018334Speter return (error); 179118334Speter 179218334Speter MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel, 179318334Speter dvp, &dvp->v_label, vp, &vp->v_label, cnp); 179418334Speter 179518334Speter if (error) { 179618334Speter VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 179718334Speter return (error); 179818334Speter } 179918334Speter 180018334Speter error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 180118334Speter 180218334Speter if (error == EOPNOTSUPP) 180318334Speter error = 0; /* XXX */ 180418334Speter 180518334Speter return (error); 180618334Speter} 180718334Speter 180818334Speterstatic int 180918334Spetermac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 181018334Speter struct label *intlabel) 181118334Speter{ 181218334Speter int error; 181318334Speter 181418334Speter ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr"); 181518334Speter 181618334Speter error = VOP_OPENEXTATTR(vp, cred, curthread); 181718334Speter if (error == EOPNOTSUPP) { 181818334Speter /* XXX: Optionally abort if transactions not supported. */ 181918334Speter if (ea_warn_once == 0) { 182018334Speter printf("Warning: transactions not supported " 182118334Speter "in EA write.\n"); 182218334Speter ea_warn_once = 1; 182318334Speter } 182418334Speter } else if (error) 182518334Speter return (error); 182618334Speter 182718334Speter MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel); 182818334Speter 182918334Speter if (error) { 183018334Speter VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 183118334Speter return (error); 183218334Speter } 183318334Speter 183418334Speter error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 183518334Speter 183618334Speter if (error == EOPNOTSUPP) 183718334Speter error = 0; /* XXX */ 183818334Speter 183918334Speter return (error); 184018334Speter} 184118334Speter 184218334Spetervoid 184318334Spetermac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp) 184418334Speter{ 184518334Speter 184618334Speter ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 184718334Speter 184818334Speter MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label); 184918334Speter} 185018334Speter 185118334Speterint 185218334Spetermac_execve_will_transition(struct ucred *old, struct vnode *vp) 185318334Speter{ 185418334Speter int result; 185518334Speter 185618334Speter result = 0; 185718334Speter MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label); 185818334Speter 185918334Speter return (result); 186018334Speter} 186118334Speter 186218334Speterint 186318334Spetermac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags) 186418334Speter{ 186518334Speter int error; 186618334Speter 186718334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 186818334Speter 186918334Speter if (!mac_enforce_fs) 187018334Speter return (0); 187118334Speter 187218334Speter MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags); 187318334Speter return (error); 187418334Speter} 187518334Speter 187618334Speterint 187718334Spetermac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 187818334Speter{ 187918334Speter int error; 188018334Speter 188118334Speter ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 188218334Speter 188318334Speter if (!mac_enforce_fs) 188418334Speter return (0); 188518334Speter 188618334Speter MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 188718334Speter return (error); 188818334Speter} 188918334Speter 189018334Speterint 189118334Spetermac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 189218334Speter{ 189318334Speter int error; 189418334Speter 189518334Speter ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 189618334Speter 189718334Speter if (!mac_enforce_fs) 189818334Speter return (0); 189918334Speter 190018334Speter MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 190118334Speter return (error); 190218334Speter} 190318334Speter 190418334Speterint 190518334Spetermac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 190618334Speter struct componentname *cnp, struct vattr *vap) 190718334Speter{ 190818334Speter int error; 190918334Speter 191018334Speter ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 191118334Speter 191218334Speter if (!mac_enforce_fs) 191318334Speter return (0); 191418334Speter 191518334Speter MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 191618334Speter return (error); 191718334Speter} 191818334Speter 191918334Speterint 192018334Spetermac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 192118334Speter struct componentname *cnp) 192218334Speter{ 192318334Speter int error; 192418334Speter 192518334Speter ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 192618334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 192718334Speter 192818334Speter if (!mac_enforce_fs) 192918334Speter return (0); 193018334Speter 193118334Speter MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 193218334Speter &vp->v_label, cnp); 193318334Speter return (error); 193418334Speter} 193518334Speter 193618334Speterint 193718334Spetermac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 193818334Speter acl_type_t type) 193918334Speter{ 194018334Speter int error; 194118334Speter 194218334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 194318334Speter 194418334Speter if (!mac_enforce_fs) 194518334Speter return (0); 194618334Speter 194718334Speter MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 194818334Speter return (error); 194918334Speter} 195018334Speter 195118334Speterint 195218334Spetermac_check_vnode_exec(struct ucred *cred, struct vnode *vp) 195318334Speter{ 195418334Speter int error; 195518334Speter 195618334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 195718334Speter 195818334Speter if (!mac_enforce_process && !mac_enforce_fs) 195918334Speter return (0); 196018334Speter 196118334Speter MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label); 196218334Speter 196318334Speter return (error); 196418334Speter} 196518334Speter 196618334Speterint 196718334Spetermac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 196818334Speter{ 196918334Speter int error; 197018334Speter 197118334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 197218334Speter 197318334Speter if (!mac_enforce_fs) 197418334Speter return (0); 197518334Speter 197618334Speter MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 197718334Speter return (error); 197818334Speter} 197918334Speter 198018334Speterint 198118334Spetermac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 198218334Speter int attrnamespace, const char *name, struct uio *uio) 198318334Speter{ 198418334Speter int error; 198518334Speter 198618334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 198718334Speter 198818334Speter if (!mac_enforce_fs) 198918334Speter return (0); 199018334Speter 199118334Speter MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 199218334Speter attrnamespace, name, uio); 199318334Speter return (error); 199418334Speter} 199518334Speter 199618334Speterint 199718334Spetermac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 199818334Speter struct vnode *vp, struct componentname *cnp) 199918334Speter{ 200018334Speter int error; 200118334Speter 200218334Speter ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link"); 200318334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link"); 200418334Speter 200518334Speter if (!mac_enforce_fs) 200618334Speter return (0); 200718334Speter 200818334Speter MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp, 200918334Speter &vp->v_label, cnp); 201018334Speter return (error); 201118334Speter} 201218334Speter 201318334Speterint 201418334Spetermac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 201518334Speter struct componentname *cnp) 201618334Speter{ 201718334Speter int error; 201818334Speter 201918334Speter ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 202018334Speter 202118334Speter if (!mac_enforce_fs) 202218334Speter return (0); 202318334Speter 202418334Speter MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 202518334Speter return (error); 202618334Speter} 202718334Speter 202818334Speterint 202918334Spetermac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) 203018334Speter{ 203118334Speter int error; 203218334Speter 203318334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); 203418334Speter 203518334Speter if (!mac_enforce_fs || !mac_enforce_vm) 203618334Speter return (0); 203718334Speter 203818334Speter MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); 203918334Speter return (error); 204018334Speter} 204118334Speter 204218334Spetervoid 204318334Spetermac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) 204418334Speter{ 204518334Speter int result = *prot; 204618334Speter 204718334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); 204818334Speter 204918334Speter if (!mac_enforce_fs || !mac_enforce_vm) 205018334Speter return; 205118334Speter 205218334Speter MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, 205318334Speter &result); 205418334Speter 205518334Speter *prot = result; 205618334Speter} 205718334Speter 205818334Speterint 205918334Spetermac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) 206018334Speter{ 206118334Speter int error; 206218334Speter 206318334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); 206418334Speter 206518334Speter if (!mac_enforce_fs || !mac_enforce_vm) 206618334Speter return (0); 206718334Speter 206818334Speter MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); 206918334Speter return (error); 207018334Speter} 207118334Speter 207218334Speterint 207318334Spetermac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode) 207418334Speter{ 207518334Speter int error; 207618334Speter 207718334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 207818334Speter 207918334Speter if (!mac_enforce_fs) 208018334Speter return (0); 208118334Speter 208218334Speter MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 208318334Speter return (error); 208418334Speter} 208518334Speter 208618334Speterint 208718334Spetermac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 208818334Speter struct vnode *vp) 208918334Speter{ 209018334Speter int error; 209118334Speter 209218334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 209318334Speter 209418334Speter if (!mac_enforce_fs) 209518334Speter return (0); 209618334Speter 209718334Speter MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 209818334Speter &vp->v_label); 209918334Speter 210018334Speter return (error); 210118334Speter} 210218334Speter 210318334Speterint 210418334Spetermac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 210518334Speter struct vnode *vp) 210618334Speter{ 210718334Speter int error; 210818334Speter 210918334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 211018334Speter 211118334Speter if (!mac_enforce_fs) 211218334Speter return (0); 211318334Speter 211418334Speter MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 211518334Speter &vp->v_label); 211618334Speter 211718334Speter return (error); 211818334Speter} 211918334Speter 212018334Speterint 212118334Spetermac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 212218334Speter{ 212318334Speter int error; 212418334Speter 212518334Speter ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 212618334Speter 212718334Speter if (!mac_enforce_fs) 212818334Speter return (0); 212918334Speter 213018334Speter MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 213118334Speter return (error); 213218334Speter} 213318334Speter 213418334Speterint 213518334Spetermac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 213618334Speter{ 213718334Speter int error; 213818334Speter 213918334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 214018334Speter 214118334Speter if (!mac_enforce_fs) 214218334Speter return (0); 214318334Speter 214418334Speter MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 214518334Speter return (error); 214618334Speter} 214718334Speter 214818334Speterstatic int 214918334Spetermac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 215018334Speter struct label *newlabel) 215118334Speter{ 215218334Speter int error; 215318334Speter 215418334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 215518334Speter 215618334Speter MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 215718334Speter 215818334Speter return (error); 215918334Speter} 216018334Speter 216118334Speterint 216218334Spetermac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 216318334Speter struct vnode *vp, struct componentname *cnp) 216418334Speter{ 216518334Speter int error; 216618334Speter 216718334Speter ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 216818334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 216918334Speter 217018334Speter if (!mac_enforce_fs) 217118334Speter return (0); 217218334Speter 217318334Speter MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 217418334Speter &vp->v_label, cnp); 217518334Speter return (error); 217618334Speter} 217718334Speter 217818334Speterint 217918334Spetermac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 218018334Speter struct vnode *vp, int samedir, struct componentname *cnp) 218118334Speter{ 218218334Speter int error; 218318334Speter 218418334Speter ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 218518334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 218618334Speter 218718334Speter if (!mac_enforce_fs) 218818334Speter return (0); 218918334Speter 219018334Speter MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 219118334Speter vp != NULL ? &vp->v_label : NULL, samedir, cnp); 219218334Speter return (error); 219318334Speter} 219418334Speter 219518334Speterint 219618334Spetermac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 219718334Speter{ 219818334Speter int error; 219918334Speter 220018334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 220118334Speter 220218334Speter if (!mac_enforce_fs) 220318334Speter return (0); 220418334Speter 220518334Speter MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 220618334Speter return (error); 220718334Speter} 220818334Speter 220918334Speterint 221018334Spetermac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 221118334Speter struct acl *acl) 221218334Speter{ 221318334Speter int error; 221418334Speter 221518334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 221618334Speter 221718334Speter if (!mac_enforce_fs) 221818334Speter return (0); 221918334Speter 222018334Speter MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 222118334Speter return (error); 222218334Speter} 222318334Speter 222418334Speterint 222518334Spetermac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 222618334Speter int attrnamespace, const char *name, struct uio *uio) 222718334Speter{ 222818334Speter int error; 222918334Speter 223018334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 223118334Speter 223218334Speter if (!mac_enforce_fs) 223318334Speter return (0); 223418334Speter 223518334Speter MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 223618334Speter attrnamespace, name, uio); 223718334Speter return (error); 223818334Speter} 223918334Speter 224018334Speterint 224118334Spetermac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 224218334Speter{ 224318334Speter int error; 224418334Speter 224518334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 224618334Speter 224718334Speter if (!mac_enforce_fs) 224818334Speter return (0); 224918334Speter 225018334Speter MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 225118334Speter return (error); 225218334Speter} 225318334Speter 225418334Speterint 225518334Spetermac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 225618334Speter{ 225718334Speter int error; 225818334Speter 225918334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 226018334Speter 226118334Speter if (!mac_enforce_fs) 226218334Speter return (0); 226318334Speter 226418334Speter MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 226518334Speter return (error); 226618334Speter} 226718334Speter 226818334Speterint 226918334Spetermac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 227018334Speter gid_t gid) 227118334Speter{ 227218334Speter int error; 227318334Speter 227418334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 227518334Speter 227618334Speter if (!mac_enforce_fs) 227718334Speter return (0); 227818334Speter 227918334Speter MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 228018334Speter return (error); 228118334Speter} 228218334Speter 228318334Speterint 228418334Spetermac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 228518334Speter struct timespec atime, struct timespec mtime) 228618334Speter{ 228718334Speter int error; 228818334Speter 228918334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 229018334Speter 229118334Speter if (!mac_enforce_fs) 229218334Speter return (0); 229318334Speter 229418334Speter MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 229518334Speter mtime); 229618334Speter return (error); 229718334Speter} 229818334Speter 229918334Speterint 230018334Spetermac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 230118334Speter struct vnode *vp) 230218334Speter{ 230318334Speter int error; 230418334Speter 230518334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 230618334Speter 230718334Speter if (!mac_enforce_fs) 230818334Speter return (0); 230918334Speter 231018334Speter MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 231118334Speter &vp->v_label); 231218334Speter return (error); 231318334Speter} 231418334Speter 231518334Speterint 231618334Spetermac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 231718334Speter struct vnode *vp) 231818334Speter{ 231918334Speter int error; 232018334Speter 232118334Speter ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 232218334Speter 232318334Speter if (!mac_enforce_fs) 232418334Speter return (0); 232518334Speter 232618334Speter MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 232718334Speter &vp->v_label); 232818334Speter 232918334Speter return (error); 233018334Speter} 233118334Speter 233218334Speter/* 233318334Speter * When relabeling a process, call out to the policies for the maximum 233418334Speter * permission allowed for each object type we know about in its 233518334Speter * memory space, and revoke access (in the least surprising ways we 233618334Speter * know) when necessary. The process lock is not held here. 233718334Speter */ 233818334Speterstatic void 233918334Spetermac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 234018334Speter{ 234118334Speter 234218334Speter /* XXX freeze all other threads */ 234318334Speter mac_cred_mmapped_drop_perms_recurse(td, cred, 234418334Speter &td->td_proc->p_vmspace->vm_map); 234518334Speter /* XXX allow other threads to continue */ 234618334Speter} 234718334Speter 234818334Speterstatic __inline const char * 234918334Speterprot2str(vm_prot_t prot) 235018334Speter{ 235118334Speter 235218334Speter switch (prot & VM_PROT_ALL) { 235318334Speter case VM_PROT_READ: 235418334Speter return ("r--"); 235518334Speter case VM_PROT_READ | VM_PROT_WRITE: 235618334Speter return ("rw-"); 235718334Speter case VM_PROT_READ | VM_PROT_EXECUTE: 235818334Speter return ("r-x"); 235918334Speter case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 236018334Speter return ("rwx"); 236118334Speter case VM_PROT_WRITE: 236218334Speter return ("-w-"); 236318334Speter case VM_PROT_EXECUTE: 236418334Speter return ("--x"); 236518334Speter case VM_PROT_WRITE | VM_PROT_EXECUTE: 236618334Speter return ("-wx"); 236718334Speter default: 236818334Speter return ("---"); 236918334Speter } 237018334Speter} 237118334Speter 237218334Speterstatic void 237318334Spetermac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 237418334Speter struct vm_map *map) 237518334Speter{ 237618334Speter struct vm_map_entry *vme; 237718334Speter int result; 237818334Speter vm_prot_t revokeperms; 237918334Speter vm_object_t object; 238018334Speter vm_ooffset_t offset; 238118334Speter struct vnode *vp; 238218334Speter 238318334Speter if (!mac_mmap_revocation) 238418334Speter return; 238518334Speter 238618334Speter vm_map_lock_read(map); 238718334Speter for (vme = map->header.next; vme != &map->header; vme = vme->next) { 238818334Speter if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 238918334Speter mac_cred_mmapped_drop_perms_recurse(td, cred, 239018334Speter vme->object.sub_map); 239118334Speter continue; 239218334Speter } 239318334Speter /* 239418334Speter * Skip over entries that obviously are not shared. 239518334Speter */ 239618334Speter if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 239718334Speter !vme->max_protection) 239818334Speter continue; 239918334Speter /* 240018334Speter * Drill down to the deepest backing object. 240118334Speter */ 240218334Speter offset = vme->offset; 240318334Speter object = vme->object.vm_object; 240418334Speter if (object == NULL) 240518334Speter continue; 240618334Speter while (object->backing_object != NULL) { 240718334Speter object = object->backing_object; 240818334Speter offset += object->backing_object_offset; 240918334Speter } 241018334Speter /* 241118334Speter * At the moment, vm_maps and objects aren't considered 241218334Speter * by the MAC system, so only things with backing by a 241318334Speter * normal object (read: vnodes) are checked. 241418334Speter */ 241518334Speter if (object->type != OBJT_VNODE) 241618334Speter continue; 241718334Speter vp = (struct vnode *)object->handle; 241818334Speter vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 241918334Speter result = vme->max_protection; 242018334Speter mac_check_vnode_mmap_downgrade(cred, vp, &result); 242118334Speter VOP_UNLOCK(vp, 0, td); 242218334Speter /* 242318334Speter * Find out what maximum protection we may be allowing 242418334Speter * now but a policy needs to get removed. 242518334Speter */ 242618334Speter revokeperms = vme->max_protection & ~result; 242718334Speter if (!revokeperms) 242818334Speter continue; 242918334Speter printf("pid %ld: revoking %s perms from %#lx:%ld " 243018334Speter "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 243118334Speter prot2str(revokeperms), (u_long)vme->start, 243218334Speter (long)(vme->end - vme->start), 243318334Speter prot2str(vme->max_protection), prot2str(vme->protection)); 243418334Speter vm_map_lock_upgrade(map); 243518334Speter /* 243618334Speter * This is the really simple case: if a map has more 243718334Speter * max_protection than is allowed, but it's not being 243818334Speter * actually used (that is, the current protection is 243918334Speter * still allowed), we can just wipe it out and do 244018334Speter * nothing more. 244118334Speter */ 244218334Speter if ((vme->protection & revokeperms) == 0) { 244318334Speter vme->max_protection -= revokeperms; 244418334Speter } else { 244518334Speter if (revokeperms & VM_PROT_WRITE) { 244618334Speter /* 244718334Speter * In the more complicated case, flush out all 244818334Speter * pending changes to the object then turn it 244918334Speter * copy-on-write. 245018334Speter */ 245118334Speter vm_object_reference(object); 245218334Speter vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 245318334Speter vm_object_page_clean(object, 245418334Speter OFF_TO_IDX(offset), 245518334Speter OFF_TO_IDX(offset + vme->end - vme->start + 245618334Speter PAGE_MASK), 245718334Speter OBJPC_SYNC); 245818334Speter VOP_UNLOCK(vp, 0, td); 245918334Speter vm_object_deallocate(object); 246018334Speter /* 246118334Speter * Why bother if there's no read permissions 246218334Speter * anymore? For the rest, we need to leave 246318334Speter * the write permissions on for COW, or 246418334Speter * remove them entirely if configured to. 246518334Speter */ 246618334Speter if (!mac_mmap_revocation_via_cow) { 246718334Speter vme->max_protection &= ~VM_PROT_WRITE; 246818334Speter vme->protection &= ~VM_PROT_WRITE; 246918334Speter } if ((revokeperms & VM_PROT_READ) == 0) 247018334Speter vme->eflags |= MAP_ENTRY_COW | 247118334Speter MAP_ENTRY_NEEDS_COPY; 247218334Speter } 247318334Speter if (revokeperms & VM_PROT_EXECUTE) { 247418334Speter vme->max_protection &= ~VM_PROT_EXECUTE; 247518334Speter vme->protection &= ~VM_PROT_EXECUTE; 247618334Speter } 247718334Speter if (revokeperms & VM_PROT_READ) { 247818334Speter vme->max_protection = 0; 247918334Speter vme->protection = 0; 248018334Speter } 248118334Speter pmap_protect(map->pmap, vme->start, vme->end, 248218334Speter vme->protection & ~revokeperms); 248318334Speter vm_map_simplify_entry(map, vme); 248418334Speter } 248518334Speter vm_map_lock_downgrade(map); 248618334Speter } 248718334Speter vm_map_unlock_read(map); 248818334Speter} 248918334Speter 249018334Speter/* 249118334Speter * When the subject's label changes, it may require revocation of privilege 249218334Speter * to mapped objects. This can't be done on-the-fly later with a unified 249318334Speter * buffer cache. 249418334Speter */ 249518334Speterstatic void 249618334Spetermac_relabel_cred(struct ucred *cred, struct label *newlabel) 2497{ 2498 2499 MAC_PERFORM(relabel_cred, cred, newlabel); 2500} 2501 2502void 2503mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 2504{ 2505 2506 MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 2507} 2508 2509void 2510mac_create_ifnet(struct ifnet *ifnet) 2511{ 2512 2513 MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2514} 2515 2516void 2517mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2518{ 2519 2520 MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2521} 2522 2523void 2524mac_create_socket(struct ucred *cred, struct socket *socket) 2525{ 2526 2527 MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2528} 2529 2530void 2531mac_create_pipe(struct ucred *cred, struct pipe *pipe) 2532{ 2533 2534 MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2535} 2536 2537void 2538mac_create_socket_from_socket(struct socket *oldsocket, 2539 struct socket *newsocket) 2540{ 2541 2542 MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2543 newsocket, &newsocket->so_label); 2544} 2545 2546static void 2547mac_relabel_socket(struct ucred *cred, struct socket *socket, 2548 struct label *newlabel) 2549{ 2550 2551 MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2552} 2553 2554static void 2555mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2556{ 2557 2558 MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2559} 2560 2561void 2562mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2563{ 2564 2565 MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label, 2566 socket, &socket->so_peerlabel); 2567} 2568 2569void 2570mac_set_socket_peer_from_socket(struct socket *oldsocket, 2571 struct socket *newsocket) 2572{ 2573 2574 MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2575 &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2576} 2577 2578void 2579mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2580{ 2581 2582 MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2583 datagram, &datagram->m_pkthdr.label); 2584} 2585 2586void 2587mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2588{ 2589 2590 MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label, 2591 fragment, &fragment->m_pkthdr.label); 2592} 2593 2594void 2595mac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2596{ 2597 2598 MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2599 &ipq->ipq_label); 2600} 2601 2602void 2603mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2604{ 2605 2606 MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label, 2607 newmbuf, &newmbuf->m_pkthdr.label); 2608} 2609 2610void 2611mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2612{ 2613 2614 MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2615 &mbuf->m_pkthdr.label); 2616} 2617 2618void 2619mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2620{ 2621 2622 MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2623 &mbuf->m_pkthdr.label); 2624} 2625 2626void 2627mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2628{ 2629 2630 MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2631 &mbuf->m_pkthdr.label); 2632} 2633 2634void 2635mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2636 struct mbuf *newmbuf) 2637{ 2638 2639 MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, 2640 &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf, 2641 &newmbuf->m_pkthdr.label); 2642} 2643 2644void 2645mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2646{ 2647 2648 MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label, 2649 newmbuf, &newmbuf->m_pkthdr.label); 2650} 2651 2652int 2653mac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2654{ 2655 int result; 2656 2657 result = 1; 2658 MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label, 2659 ipq, &ipq->ipq_label); 2660 2661 return (result); 2662} 2663 2664void 2665mac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2666{ 2667 2668 MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2669 &ipq->ipq_label); 2670} 2671 2672void 2673mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2674{ 2675 2676 MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2677 &mbuf->m_pkthdr.label); 2678} 2679 2680void 2681mac_create_mount(struct ucred *cred, struct mount *mp) 2682{ 2683 2684 MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2685 &mp->mnt_fslabel); 2686} 2687 2688void 2689mac_create_root_mount(struct ucred *cred, struct mount *mp) 2690{ 2691 2692 MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2693 &mp->mnt_fslabel); 2694} 2695 2696int 2697mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2698{ 2699 int error; 2700 2701 if (!mac_enforce_network) 2702 return (0); 2703 2704 MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2705 &ifnet->if_label); 2706 2707 return (error); 2708} 2709 2710static int 2711mac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2712{ 2713 int error; 2714 2715 MAC_CHECK(check_cred_relabel, cred, newlabel); 2716 2717 return (error); 2718} 2719 2720int 2721mac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2722{ 2723 int error; 2724 2725 if (!mac_enforce_process) 2726 return (0); 2727 2728 MAC_CHECK(check_cred_visible, u1, u2); 2729 2730 return (error); 2731} 2732 2733int 2734mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2735{ 2736 int error; 2737 2738 if (!mac_enforce_network) 2739 return (0); 2740 2741 KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr")); 2742 if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED)) 2743 if_printf(ifnet, "not initialized\n"); 2744 2745 MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2746 &mbuf->m_pkthdr.label); 2747 2748 return (error); 2749} 2750 2751int 2752mac_check_mount_stat(struct ucred *cred, struct mount *mount) 2753{ 2754 int error; 2755 2756 if (!mac_enforce_fs) 2757 return (0); 2758 2759 MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2760 2761 return (error); 2762} 2763 2764int 2765mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2766 void *data) 2767{ 2768 int error; 2769 2770 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2771 2772 if (!mac_enforce_pipe) 2773 return (0); 2774 2775 MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2776 2777 return (error); 2778} 2779 2780int 2781mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2782{ 2783 int error; 2784 2785 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2786 2787 if (!mac_enforce_pipe) 2788 return (0); 2789 2790 MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2791 2792 return (error); 2793} 2794 2795int 2796mac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2797{ 2798 int error; 2799 2800 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2801 2802 if (!mac_enforce_pipe) 2803 return (0); 2804 2805 MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2806 2807 return (error); 2808} 2809 2810static int 2811mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2812 struct label *newlabel) 2813{ 2814 int error; 2815 2816 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2817 2818 if (!mac_enforce_pipe) 2819 return (0); 2820 2821 MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2822 2823 return (error); 2824} 2825 2826int 2827mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2828{ 2829 int error; 2830 2831 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2832 2833 if (!mac_enforce_pipe) 2834 return (0); 2835 2836 MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2837 2838 return (error); 2839} 2840 2841int 2842mac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2843{ 2844 int error; 2845 2846 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2847 2848 if (!mac_enforce_pipe) 2849 return (0); 2850 2851 MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2852 2853 return (error); 2854} 2855 2856int 2857mac_check_proc_debug(struct ucred *cred, struct proc *proc) 2858{ 2859 int error; 2860 2861 PROC_LOCK_ASSERT(proc, MA_OWNED); 2862 2863 if (!mac_enforce_process) 2864 return (0); 2865 2866 MAC_CHECK(check_proc_debug, cred, proc); 2867 2868 return (error); 2869} 2870 2871int 2872mac_check_proc_sched(struct ucred *cred, struct proc *proc) 2873{ 2874 int error; 2875 2876 PROC_LOCK_ASSERT(proc, MA_OWNED); 2877 2878 if (!mac_enforce_process) 2879 return (0); 2880 2881 MAC_CHECK(check_proc_sched, cred, proc); 2882 2883 return (error); 2884} 2885 2886int 2887mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2888{ 2889 int error; 2890 2891 PROC_LOCK_ASSERT(proc, MA_OWNED); 2892 2893 if (!mac_enforce_process) 2894 return (0); 2895 2896 MAC_CHECK(check_proc_signal, cred, proc, signum); 2897 2898 return (error); 2899} 2900 2901int 2902mac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2903 struct sockaddr *sockaddr) 2904{ 2905 int error; 2906 2907 if (!mac_enforce_socket) 2908 return (0); 2909 2910 MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2911 sockaddr); 2912 2913 return (error); 2914} 2915 2916int 2917mac_check_socket_connect(struct ucred *cred, struct socket *socket, 2918 struct sockaddr *sockaddr) 2919{ 2920 int error; 2921 2922 if (!mac_enforce_socket) 2923 return (0); 2924 2925 MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2926 sockaddr); 2927 2928 return (error); 2929} 2930 2931int 2932mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2933{ 2934 int error; 2935 2936 if (!mac_enforce_socket) 2937 return (0); 2938 2939 MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2940 &mbuf->m_pkthdr.label); 2941 2942 return (error); 2943} 2944 2945int 2946mac_check_socket_listen(struct ucred *cred, struct socket *socket) 2947{ 2948 int error; 2949 2950 if (!mac_enforce_socket) 2951 return (0); 2952 2953 MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2954 return (error); 2955} 2956 2957int 2958mac_check_socket_receive(struct ucred *cred, struct socket *so) 2959{ 2960 int error; 2961 2962 if (!mac_enforce_socket) 2963 return (0); 2964 2965 MAC_CHECK(check_socket_receive, cred, so, &so->so_label); 2966 2967 return (error); 2968} 2969 2970static int 2971mac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2972 struct label *newlabel) 2973{ 2974 int error; 2975 2976 MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2977 newlabel); 2978 2979 return (error); 2980} 2981 2982int 2983mac_check_socket_send(struct ucred *cred, struct socket *so) 2984{ 2985 int error; 2986 2987 if (!mac_enforce_socket) 2988 return (0); 2989 2990 MAC_CHECK(check_socket_send, cred, so, &so->so_label); 2991 2992 return (error); 2993} 2994 2995int 2996mac_check_socket_visible(struct ucred *cred, struct socket *socket) 2997{ 2998 int error; 2999 3000 if (!mac_enforce_socket) 3001 return (0); 3002 3003 MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 3004 3005 return (error); 3006} 3007 3008int 3009mac_check_system_reboot(struct ucred *cred, int howto) 3010{ 3011 int error; 3012 3013 ASSERT_VOP_LOCKED(vp, "mac_check_system_reboot"); 3014 3015 if (!mac_enforce_reboot) 3016 return (0); 3017 3018 MAC_CHECK(check_system_reboot, cred, howto); 3019 return (error); 3020} 3021 3022int 3023mac_check_system_swapon(struct ucred *cred, struct vnode *vp) 3024{ 3025 int error; 3026 3027 ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon"); 3028 3029 if (!mac_enforce_fs) 3030 return (0); 3031 3032 MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label); 3033 return (error); 3034} 3035 3036int 3037mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 3038 struct ifnet *ifnet) 3039{ 3040 char *elements, *buffer; 3041 struct mac mac; 3042 int error; 3043 3044 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 3045 if (error) 3046 return (error); 3047 3048 error = mac_check_structmac_consistent(&mac); 3049 if (error) 3050 return (error); 3051 3052 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3053 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3054 if (error) { 3055 free(elements, M_MACTEMP); 3056 return (error); 3057 } 3058 3059 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3060 error = mac_externalize_ifnet_label(&ifnet->if_label, elements, 3061 buffer, mac.m_buflen, M_WAITOK); 3062 if (error == 0) 3063 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3064 3065 free(buffer, M_MACTEMP); 3066 free(elements, M_MACTEMP); 3067 3068 return (error); 3069} 3070 3071int 3072mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 3073 struct ifnet *ifnet) 3074{ 3075 struct label intlabel; 3076 struct mac mac; 3077 char *buffer; 3078 int error; 3079 3080 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 3081 if (error) 3082 return (error); 3083 3084 error = mac_check_structmac_consistent(&mac); 3085 if (error) 3086 return (error); 3087 3088 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3089 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3090 if (error) { 3091 free(buffer, M_MACTEMP); 3092 return (error); 3093 } 3094 3095 mac_init_ifnet_label(&intlabel); 3096 error = mac_internalize_ifnet_label(&intlabel, buffer); 3097 free(buffer, M_MACTEMP); 3098 if (error) { 3099 mac_destroy_ifnet_label(&intlabel); 3100 return (error); 3101 } 3102 3103 /* 3104 * XXX: Note that this is a redundant privilege check, since 3105 * policies impose this check themselves if required by the 3106 * policy. Eventually, this should go away. 3107 */ 3108 error = suser_cred(cred, 0); 3109 if (error) { 3110 mac_destroy_ifnet_label(&intlabel); 3111 return (error); 3112 } 3113 3114 MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 3115 &intlabel); 3116 if (error) { 3117 mac_destroy_ifnet_label(&intlabel); 3118 return (error); 3119 } 3120 3121 MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 3122 3123 mac_destroy_ifnet_label(&intlabel); 3124 return (0); 3125} 3126 3127void 3128mac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp) 3129{ 3130 3131 MAC_PERFORM(create_devfs_vnode, de, &de->de_label, vp, &vp->v_label); 3132} 3133 3134void 3135mac_create_devfs_device(dev_t dev, struct devfs_dirent *de) 3136{ 3137 3138 MAC_PERFORM(create_devfs_device, dev, de, &de->de_label); 3139} 3140 3141void 3142mac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd, 3143 struct devfs_dirent *de) 3144{ 3145 3146 MAC_PERFORM(create_devfs_symlink, cred, dd, &dd->de_label, de, 3147 &de->de_label); 3148} 3149 3150void 3151mac_create_devfs_directory(char *dirname, int dirnamelen, 3152 struct devfs_dirent *de) 3153{ 3154 3155 MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de, 3156 &de->de_label); 3157} 3158 3159int 3160mac_setsockopt_label_set(struct ucred *cred, struct socket *so, 3161 struct mac *mac) 3162{ 3163 struct label intlabel; 3164 char *buffer; 3165 int error; 3166 3167 error = mac_check_structmac_consistent(mac); 3168 if (error) 3169 return (error); 3170 3171 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3172 error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); 3173 if (error) { 3174 free(buffer, M_MACTEMP); 3175 return (error); 3176 } 3177 3178 mac_init_socket_label(&intlabel, M_WAITOK); 3179 error = mac_internalize_socket_label(&intlabel, buffer); 3180 free(buffer, M_MACTEMP); 3181 if (error) { 3182 mac_destroy_socket_label(&intlabel); 3183 return (error); 3184 } 3185 3186 mac_check_socket_relabel(cred, so, &intlabel); 3187 if (error) { 3188 mac_destroy_socket_label(&intlabel); 3189 return (error); 3190 } 3191 3192 mac_relabel_socket(cred, so, &intlabel); 3193 3194 mac_destroy_socket_label(&intlabel); 3195 return (0); 3196} 3197 3198int 3199mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 3200{ 3201 int error; 3202 3203 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 3204 3205 error = mac_check_pipe_relabel(cred, pipe, label); 3206 if (error) 3207 return (error); 3208 3209 mac_relabel_pipe(cred, pipe, label); 3210 3211 return (0); 3212} 3213 3214int 3215mac_getsockopt_label_get(struct ucred *cred, struct socket *so, 3216 struct mac *mac) 3217{ 3218 char *buffer, *elements; 3219 int error; 3220 3221 error = mac_check_structmac_consistent(mac); 3222 if (error) 3223 return (error); 3224 3225 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3226 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3227 if (error) { 3228 free(elements, M_MACTEMP); 3229 return (error); 3230 } 3231 3232 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3233 error = mac_externalize_socket_label(&so->so_label, elements, 3234 buffer, mac->m_buflen, M_WAITOK); 3235 if (error == 0) 3236 error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3237 3238 free(buffer, M_MACTEMP); 3239 free(elements, M_MACTEMP); 3240 3241 return (error); 3242} 3243 3244int 3245mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 3246 struct mac *mac) 3247{ 3248 char *elements, *buffer; 3249 int error; 3250 3251 error = mac_check_structmac_consistent(mac); 3252 if (error) 3253 return (error); 3254 3255 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3256 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3257 if (error) { 3258 free(elements, M_MACTEMP); 3259 return (error); 3260 } 3261 3262 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3263 error = mac_externalize_socket_peer_label(&so->so_peerlabel, 3264 elements, buffer, mac->m_buflen, M_WAITOK); 3265 if (error == 0) 3266 error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3267 3268 free(buffer, M_MACTEMP); 3269 free(elements, M_MACTEMP); 3270 3271 return (error); 3272} 3273 3274/* 3275 * Implementation of VOP_SETLABEL() that relies on extended attributes 3276 * to store label data. Can be referenced by filesystems supporting 3277 * extended attributes. 3278 */ 3279int 3280vop_stdsetlabel_ea(struct vop_setlabel_args *ap) 3281{ 3282 struct vnode *vp = ap->a_vp; 3283 struct label *intlabel = ap->a_label; 3284 int error; 3285 3286 ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 3287 3288 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3289 return (EOPNOTSUPP); 3290 3291 error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel); 3292 if (error) 3293 return (error); 3294 3295 mac_relabel_vnode(ap->a_cred, vp, intlabel); 3296 3297 return (0); 3298} 3299 3300static int 3301vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 3302{ 3303 int error; 3304 3305 if (vp->v_mount == NULL) { 3306 /* printf("vn_setlabel: null v_mount\n"); */ 3307 if (vp->v_type != VNON) 3308 printf("vn_setlabel: null v_mount with non-VNON\n"); 3309 return (EBADF); 3310 } 3311 3312 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3313 return (EOPNOTSUPP); 3314 3315 /* 3316 * Multi-phase commit. First check the policies to confirm the 3317 * change is OK. Then commit via the filesystem. Finally, 3318 * update the actual vnode label. Question: maybe the filesystem 3319 * should update the vnode at the end as part of VOP_SETLABEL()? 3320 */ 3321 error = mac_check_vnode_relabel(cred, vp, intlabel); 3322 if (error) 3323 return (error); 3324 3325 /* 3326 * VADMIN provides the opportunity for the filesystem to make 3327 * decisions about who is and is not able to modify labels 3328 * and protections on files. This might not be right. We can't 3329 * assume VOP_SETLABEL() will do it, because we might implement 3330 * that as part of vop_stdsetlabel_ea(). 3331 */ 3332 error = VOP_ACCESS(vp, VADMIN, cred, curthread); 3333 if (error) 3334 return (error); 3335 3336 error = VOP_SETLABEL(vp, intlabel, cred, curthread); 3337 if (error) 3338 return (error); 3339 3340 return (0); 3341} 3342 3343int 3344__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3345{ 3346 char *elements, *buffer; 3347 struct mac mac; 3348 struct proc *tproc; 3349 struct ucred *tcred; 3350 int error; 3351 3352 error = copyin(SCARG(uap, mac_p), &mac, sizeof(mac)); 3353 if (error) 3354 return (error); 3355 3356 error = mac_check_structmac_consistent(&mac); 3357 if (error) 3358 return (error); 3359 3360 tproc = pfind(uap->pid); 3361 if (tproc == NULL) 3362 return (ESRCH); 3363 3364 tcred = NULL; /* Satisfy gcc. */ 3365 error = p_cansee(td, tproc); 3366 if (error == 0) 3367 tcred = crhold(tproc->p_ucred); 3368 PROC_UNLOCK(tproc); 3369 if (error) 3370 return (error); 3371 3372 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3373 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3374 if (error) { 3375 free(elements, M_MACTEMP); 3376 crfree(tcred); 3377 return (error); 3378 } 3379 3380 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3381 error = mac_externalize_cred_label(&tcred->cr_label, elements, 3382 buffer, mac.m_buflen, M_WAITOK); 3383 if (error == 0) 3384 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3385 3386 free(buffer, M_MACTEMP); 3387 free(elements, M_MACTEMP); 3388 crfree(tcred); 3389 return (error); 3390} 3391 3392/* 3393 * MPSAFE 3394 */ 3395int 3396__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3397{ 3398 char *elements, *buffer; 3399 struct mac mac; 3400 int error; 3401 3402 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3403 if (error) 3404 return (error); 3405 3406 error = mac_check_structmac_consistent(&mac); 3407 if (error) 3408 return (error); 3409 3410 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3411 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3412 if (error) { 3413 free(elements, M_MACTEMP); 3414 return (error); 3415 } 3416 3417 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3418 error = mac_externalize_cred_label(&td->td_ucred->cr_label, 3419 elements, buffer, mac.m_buflen, M_WAITOK); 3420 if (error == 0) 3421 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3422 3423 free(buffer, M_MACTEMP); 3424 free(elements, M_MACTEMP); 3425 return (error); 3426} 3427 3428/* 3429 * MPSAFE 3430 */ 3431int 3432__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3433{ 3434 struct ucred *newcred, *oldcred; 3435 struct label intlabel; 3436 struct proc *p; 3437 struct mac mac; 3438 char *buffer; 3439 int error; 3440 3441 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3442 if (error) 3443 return (error); 3444 3445 error = mac_check_structmac_consistent(&mac); 3446 if (error) 3447 return (error); 3448 3449 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3450 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3451 if (error) { 3452 free(buffer, M_MACTEMP); 3453 return (error); 3454 } 3455 3456 mac_init_cred_label(&intlabel); 3457 error = mac_internalize_cred_label(&intlabel, buffer); 3458 free(buffer, M_MACTEMP); 3459 if (error) { 3460 mac_destroy_cred_label(&intlabel); 3461 return (error); 3462 } 3463 3464 newcred = crget(); 3465 3466 p = td->td_proc; 3467 PROC_LOCK(p); 3468 oldcred = p->p_ucred; 3469 3470 error = mac_check_cred_relabel(oldcred, &intlabel); 3471 if (error) { 3472 PROC_UNLOCK(p); 3473 crfree(newcred); 3474 goto out; 3475 } 3476 3477 setsugid(p); 3478 crcopy(newcred, oldcred); 3479 mac_relabel_cred(newcred, &intlabel); 3480 p->p_ucred = newcred; 3481 3482 /* 3483 * Grab additional reference for use while revoking mmaps, prior 3484 * to releasing the proc lock and sharing the cred. 3485 */ 3486 crhold(newcred); 3487 PROC_UNLOCK(p); 3488 3489 if (mac_enforce_vm) { 3490 mtx_lock(&Giant); 3491 mac_cred_mmapped_drop_perms(td, newcred); 3492 mtx_unlock(&Giant); 3493 } 3494 3495 crfree(newcred); /* Free revocation reference. */ 3496 crfree(oldcred); 3497 3498out: 3499 mac_destroy_cred_label(&intlabel); 3500 return (error); 3501} 3502 3503/* 3504 * MPSAFE 3505 */ 3506int 3507__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3508{ 3509 char *elements, *buffer; 3510 struct label intlabel; 3511 struct file *fp; 3512 struct mac mac; 3513 struct vnode *vp; 3514 struct pipe *pipe; 3515 short label_type; 3516 int error; 3517 3518 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3519 if (error) 3520 return (error); 3521 3522 error = mac_check_structmac_consistent(&mac); 3523 if (error) 3524 return (error); 3525 3526 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3527 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3528 if (error) { 3529 free(elements, M_MACTEMP); 3530 return (error); 3531 } 3532 3533 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3534 mtx_lock(&Giant); /* VFS */ 3535 error = fget(td, SCARG(uap, fd), &fp); 3536 if (error) 3537 goto out; 3538 3539 label_type = fp->f_type; 3540 switch (fp->f_type) { 3541 case DTYPE_FIFO: 3542 case DTYPE_VNODE: 3543 vp = (struct vnode *)fp->f_data; 3544 3545 mac_init_vnode_label(&intlabel); 3546 3547 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3548 mac_copy_vnode_label(&vp->v_label, &intlabel); 3549 VOP_UNLOCK(vp, 0, td); 3550 3551 break; 3552 case DTYPE_PIPE: 3553 pipe = (struct pipe *)fp->f_data; 3554 3555 mac_init_pipe_label(&intlabel); 3556 3557 PIPE_LOCK(pipe); 3558 mac_copy_pipe_label(pipe->pipe_label, &intlabel); 3559 PIPE_UNLOCK(pipe); 3560 break; 3561 default: 3562 error = EINVAL; 3563 fdrop(fp, td); 3564 goto out; 3565 } 3566 fdrop(fp, td); 3567 3568 switch (label_type) { 3569 case DTYPE_FIFO: 3570 case DTYPE_VNODE: 3571 if (error == 0) 3572 error = mac_externalize_vnode_label(&intlabel, 3573 elements, buffer, mac.m_buflen, M_WAITOK); 3574 mac_destroy_vnode_label(&intlabel); 3575 break; 3576 case DTYPE_PIPE: 3577 error = mac_externalize_pipe_label(&intlabel, elements, 3578 buffer, mac.m_buflen, M_WAITOK); 3579 mac_destroy_pipe_label(&intlabel); 3580 break; 3581 default: 3582 panic("__mac_get_fd: corrupted label_type"); 3583 } 3584 3585 if (error == 0) 3586 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3587 3588out: 3589 mtx_unlock(&Giant); /* VFS */ 3590 free(buffer, M_MACTEMP); 3591 free(elements, M_MACTEMP); 3592 3593 return (error); 3594} 3595 3596/* 3597 * MPSAFE 3598 */ 3599int 3600__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3601{ 3602 char *elements, *buffer; 3603 struct nameidata nd; 3604 struct label intlabel; 3605 struct mac mac; 3606 int error; 3607 3608 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3609 if (error) 3610 return (error); 3611 3612 error = mac_check_structmac_consistent(&mac); 3613 if (error) 3614 return (error); 3615 3616 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3617 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3618 if (error) { 3619 free(elements, M_MACTEMP); 3620 return (error); 3621 } 3622 3623 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3624 mtx_lock(&Giant); /* VFS */ 3625 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3626 td); 3627 error = namei(&nd); 3628 if (error) 3629 goto out; 3630 3631 mac_init_vnode_label(&intlabel); 3632 mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3633 error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3634 mac.m_buflen, M_WAITOK); 3635 3636 NDFREE(&nd, 0); 3637 mac_destroy_vnode_label(&intlabel); 3638 3639 if (error == 0) 3640 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3641 3642out: 3643 mtx_unlock(&Giant); /* VFS */ 3644 3645 free(buffer, M_MACTEMP); 3646 free(elements, M_MACTEMP); 3647 3648 return (error); 3649} 3650 3651/* 3652 * MPSAFE 3653 */ 3654int 3655__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3656{ 3657 char *elements, *buffer; 3658 struct nameidata nd; 3659 struct label intlabel; 3660 struct mac mac; 3661 int error; 3662 3663 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3664 if (error) 3665 return (error); 3666 3667 error = mac_check_structmac_consistent(&mac); 3668 if (error) 3669 return (error); 3670 3671 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3672 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3673 if (error) { 3674 free(elements, M_MACTEMP); 3675 return (error); 3676 } 3677 3678 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3679 mtx_lock(&Giant); /* VFS */ 3680 NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3681 td); 3682 error = namei(&nd); 3683 if (error) 3684 goto out; 3685 3686 mac_init_vnode_label(&intlabel); 3687 mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3688 error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3689 mac.m_buflen, M_WAITOK); 3690 NDFREE(&nd, 0); 3691 mac_destroy_vnode_label(&intlabel); 3692 3693 if (error == 0) 3694 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3695 3696out: 3697 mtx_unlock(&Giant); /* VFS */ 3698 3699 free(buffer, M_MACTEMP); 3700 free(elements, M_MACTEMP); 3701 3702 return (error); 3703} 3704 3705/* 3706 * MPSAFE 3707 */ 3708int 3709__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3710{ 3711 struct label intlabel; 3712 struct pipe *pipe; 3713 struct file *fp; 3714 struct mount *mp; 3715 struct vnode *vp; 3716 struct mac mac; 3717 char *buffer; 3718 int error; 3719 3720 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3721 if (error) 3722 return (error); 3723 3724 error = mac_check_structmac_consistent(&mac); 3725 if (error) 3726 return (error); 3727 3728 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3729 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3730 if (error) { 3731 free(buffer, M_MACTEMP); 3732 return (error); 3733 } 3734 3735 mtx_lock(&Giant); /* VFS */ 3736 3737 error = fget(td, SCARG(uap, fd), &fp); 3738 if (error) 3739 goto out; 3740 3741 switch (fp->f_type) { 3742 case DTYPE_FIFO: 3743 case DTYPE_VNODE: 3744 mac_init_vnode_label(&intlabel); 3745 error = mac_internalize_vnode_label(&intlabel, buffer); 3746 if (error) { 3747 mac_destroy_vnode_label(&intlabel); 3748 break; 3749 } 3750 3751 vp = (struct vnode *)fp->f_data; 3752 error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3753 if (error != 0) { 3754 mac_destroy_vnode_label(&intlabel); 3755 break; 3756 } 3757 3758 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3759 error = vn_setlabel(vp, &intlabel, td->td_ucred); 3760 VOP_UNLOCK(vp, 0, td); 3761 vn_finished_write(mp); 3762 3763 mac_destroy_vnode_label(&intlabel); 3764 break; 3765 3766 case DTYPE_PIPE: 3767 mac_init_pipe_label(&intlabel); 3768 error = mac_internalize_pipe_label(&intlabel, buffer); 3769 if (error == 0) { 3770 pipe = (struct pipe *)fp->f_data; 3771 PIPE_LOCK(pipe); 3772 error = mac_pipe_label_set(td->td_ucred, pipe, 3773 &intlabel); 3774 PIPE_UNLOCK(pipe); 3775 } 3776 3777 mac_destroy_pipe_label(&intlabel); 3778 break; 3779 3780 default: 3781 error = EINVAL; 3782 } 3783 3784 fdrop(fp, td); 3785out: 3786 mtx_unlock(&Giant); /* VFS */ 3787 3788 free(buffer, M_MACTEMP); 3789 3790 return (error); 3791} 3792 3793/* 3794 * MPSAFE 3795 */ 3796int 3797__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3798{ 3799 struct label intlabel; 3800 struct nameidata nd; 3801 struct mount *mp; 3802 struct mac mac; 3803 char *buffer; 3804 int error; 3805 3806 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3807 if (error) 3808 return (error); 3809 3810 error = mac_check_structmac_consistent(&mac); 3811 if (error) 3812 return (error); 3813 3814 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3815 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3816 if (error) { 3817 free(buffer, M_MACTEMP); 3818 return (error); 3819 } 3820 3821 mac_init_vnode_label(&intlabel); 3822 error = mac_internalize_vnode_label(&intlabel, buffer); 3823 free(buffer, M_MACTEMP); 3824 if (error) { 3825 mac_destroy_vnode_label(&intlabel); 3826 return (error); 3827 } 3828 3829 mtx_lock(&Giant); /* VFS */ 3830 3831 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3832 td); 3833 error = namei(&nd); 3834 if (error == 0) { 3835 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3836 if (error == 0) 3837 error = vn_setlabel(nd.ni_vp, &intlabel, 3838 td->td_ucred); 3839 vn_finished_write(mp); 3840 } 3841 3842 NDFREE(&nd, 0); 3843 mtx_unlock(&Giant); /* VFS */ 3844 mac_destroy_vnode_label(&intlabel); 3845 3846 return (error); 3847} 3848 3849/* 3850 * MPSAFE 3851 */ 3852int 3853__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3854{ 3855 struct label intlabel; 3856 struct nameidata nd; 3857 struct mount *mp; 3858 struct mac mac; 3859 char *buffer; 3860 int error; 3861 3862 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3863 if (error) 3864 return (error); 3865 3866 error = mac_check_structmac_consistent(&mac); 3867 if (error) 3868 return (error); 3869 3870 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3871 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3872 if (error) { 3873 free(buffer, M_MACTEMP); 3874 return (error); 3875 } 3876 3877 mac_init_vnode_label(&intlabel); 3878 error = mac_internalize_vnode_label(&intlabel, buffer); 3879 free(buffer, M_MACTEMP); 3880 if (error) { 3881 mac_destroy_vnode_label(&intlabel); 3882 return (error); 3883 } 3884 3885 mtx_lock(&Giant); /* VFS */ 3886 3887 NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3888 td); 3889 error = namei(&nd); 3890 if (error == 0) { 3891 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3892 if (error == 0) 3893 error = vn_setlabel(nd.ni_vp, &intlabel, 3894 td->td_ucred); 3895 vn_finished_write(mp); 3896 } 3897 3898 NDFREE(&nd, 0); 3899 mtx_unlock(&Giant); /* VFS */ 3900 mac_destroy_vnode_label(&intlabel); 3901 3902 return (error); 3903} 3904 3905/* 3906 * MPSAFE 3907 */ 3908int 3909mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3910{ 3911 struct mac_policy_conf *mpc; 3912 char target[MAC_MAX_POLICY_NAME]; 3913 int error; 3914 3915 error = copyinstr(SCARG(uap, policy), target, sizeof(target), NULL); 3916 if (error) 3917 return (error); 3918 3919 error = ENOSYS; 3920 MAC_POLICY_LIST_BUSY(); 3921 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3922 if (strcmp(mpc->mpc_name, target) == 0 && 3923 mpc->mpc_ops->mpo_syscall != NULL) { 3924 error = mpc->mpc_ops->mpo_syscall(td, 3925 SCARG(uap, call), SCARG(uap, arg)); 3926 goto out; 3927 } 3928 } 3929 3930out: 3931 MAC_POLICY_LIST_UNBUSY(); 3932 return (error); 3933} 3934 3935SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3936SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3937 3938#else /* !MAC */ 3939 3940int 3941__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3942{ 3943 3944 return (ENOSYS); 3945} 3946 3947int 3948__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3949{ 3950 3951 return (ENOSYS); 3952} 3953 3954int 3955__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3956{ 3957 3958 return (ENOSYS); 3959} 3960 3961int 3962__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3963{ 3964 3965 return (ENOSYS); 3966} 3967 3968int 3969__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3970{ 3971 3972 return (ENOSYS); 3973} 3974 3975int 3976__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3977{ 3978 3979 return (ENOSYS); 3980} 3981 3982int 3983__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3984{ 3985 3986 return (ENOSYS); 3987} 3988 3989int 3990__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3991{ 3992 3993 return (ENOSYS); 3994} 3995 3996int 3997__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3998{ 3999 4000 return (ENOSYS); 4001} 4002 4003int 4004mac_syscall(struct thread *td, struct mac_syscall_args *uap) 4005{ 4006 4007 return (ENOSYS); 4008} 4009 4010#endif 4011