mac_cred.c revision 106024
1100894Srwatson/*- 2100894Srwatson * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 3100894Srwatson * Copyright (c) 2001 Ilmar S. Habibulin 4100894Srwatson * Copyright (c) 2001, 2002 Networks Associates Technology, Inc. 5100894Srwatson * All rights reserved. 6100894Srwatson * 7100894Srwatson * This software was developed by Robert Watson and Ilmar Habibulin for the 8100894Srwatson * TrustedBSD Project. 9100894Srwatson * 10100894Srwatson * This software was developed for the FreeBSD Project in part by NAI Labs, 11100894Srwatson * the Security Research Division of Network Associates, Inc. under 12100894Srwatson * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 13100894Srwatson * CHATS research program. 14100894Srwatson * 15100894Srwatson * Redistribution and use in source and binary forms, with or without 16100894Srwatson * modification, are permitted provided that the following conditions 17100894Srwatson * are met: 18100894Srwatson * 1. Redistributions of source code must retain the above copyright 19100894Srwatson * notice, this list of conditions and the following disclaimer. 20100894Srwatson * 2. Redistributions in binary form must reproduce the above copyright 21100894Srwatson * notice, this list of conditions and the following disclaimer in the 22100894Srwatson * documentation and/or other materials provided with the distribution. 23100894Srwatson * 3. The names of the authors may not be used to endorse or promote 24100894Srwatson * products derived from this software without specific prior written 25100894Srwatson * permission. 26100894Srwatson * 27100894Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 28100894Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29100894Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30100894Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 31100894Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32100894Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33100894Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34100894Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35100894Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36100894Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37100894Srwatson * SUCH DAMAGE. 38100894Srwatson * 39100894Srwatson * $FreeBSD: head/sys/security/mac/mac_process.c 106024 2002-10-27 07:03:29Z rwatson $ 40100894Srwatson */ 41100894Srwatson/* 42100894Srwatson * Developed by the TrustedBSD Project. 43100894Srwatson * 44100894Srwatson * Framework for extensible kernel access control. Kernel and userland 45100894Srwatson * interface to the framework, policy registration and composition. 46100894Srwatson */ 47100894Srwatson 48100894Srwatson#include "opt_mac.h" 49104300Sphk#include "opt_devfs.h" 50101173Srwatson 51100894Srwatson#include <sys/param.h> 52100979Srwatson#include <sys/extattr.h> 53100979Srwatson#include <sys/kernel.h> 54100979Srwatson#include <sys/lock.h> 55102949Sbde#include <sys/malloc.h> 56100979Srwatson#include <sys/mutex.h> 57100979Srwatson#include <sys/mac.h> 58101712Srwatson#include <sys/module.h> 59100979Srwatson#include <sys/proc.h> 60100979Srwatson#include <sys/systm.h> 61100894Srwatson#include <sys/sysproto.h> 62100894Srwatson#include <sys/sysent.h> 63100979Srwatson#include <sys/vnode.h> 64100979Srwatson#include <sys/mount.h> 65100979Srwatson#include <sys/file.h> 66100979Srwatson#include <sys/namei.h> 67100979Srwatson#include <sys/socket.h> 68100979Srwatson#include <sys/pipe.h> 69100979Srwatson#include <sys/socketvar.h> 70100979Srwatson#include <sys/sysctl.h> 71100894Srwatson 72100979Srwatson#include <vm/vm.h> 73100979Srwatson#include <vm/pmap.h> 74100979Srwatson#include <vm/vm_map.h> 75100979Srwatson#include <vm/vm_object.h> 76100979Srwatson 77100979Srwatson#include <sys/mac_policy.h> 78100979Srwatson 79100979Srwatson#include <fs/devfs/devfs.h> 80100979Srwatson 81100979Srwatson#include <net/bpfdesc.h> 82100979Srwatson#include <net/if.h> 83100979Srwatson#include <net/if_var.h> 84100979Srwatson 85100979Srwatson#include <netinet/in.h> 86100979Srwatson#include <netinet/ip_var.h> 87100979Srwatson 88100979Srwatson#ifdef MAC 89100979Srwatson 90101712Srwatson/* 91101712Srwatson * Declare that the kernel provides MAC support, version 1. This permits 92101712Srwatson * modules to refuse to be loaded if the necessary support isn't present, 93101712Srwatson * even if it's pre-boot. 94101712Srwatson */ 95101712SrwatsonMODULE_VERSION(kernel_mac_support, 1); 96101712Srwatson 97100979SrwatsonSYSCTL_DECL(_security); 98100979Srwatson 99100979SrwatsonSYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0, 100100979Srwatson "TrustedBSD MAC policy controls"); 101104517Srwatson 102100979Srwatson#if MAC_MAX_POLICIES > 32 103100979Srwatson#error "MAC_MAX_POLICIES too large" 104100979Srwatson#endif 105105497Srwatson 106100979Srwatsonstatic unsigned int mac_max_policies = MAC_MAX_POLICIES; 107100979Srwatsonstatic unsigned int mac_policy_offsets_free = (1 << MAC_MAX_POLICIES) - 1; 108100979SrwatsonSYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD, 109100979Srwatson &mac_max_policies, 0, ""); 110100979Srwatson 111105959Srwatson/* 112105959Srwatson * Has the kernel started generating labeled objects yet? All read/write 113105959Srwatson * access to this variable is serialized during the boot process. Following 114105959Srwatson * the end of serialization, we don't update this flag; no locking. 115105959Srwatson */ 116100979Srwatsonstatic int mac_late = 0; 117100979Srwatson 118105988Srwatson/* 119105988Srwatson * Warn about EA transactions only the first time they happen. 120105988Srwatson * Weak coherency, no locking. 121105988Srwatson */ 122105988Srwatsonstatic int ea_warn_once = 0; 123105988Srwatson 124100979Srwatsonstatic int mac_enforce_fs = 1; 125100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW, 126100979Srwatson &mac_enforce_fs, 0, "Enforce MAC policy on file system objects"); 127100979SrwatsonTUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs); 128100979Srwatson 129100979Srwatsonstatic int mac_enforce_network = 1; 130100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, 131100979Srwatson &mac_enforce_network, 0, "Enforce MAC policy on network packets"); 132100979SrwatsonTUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); 133100979Srwatson 134103513Srwatsonstatic int mac_enforce_pipe = 1; 135103513SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW, 136103513Srwatson &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations"); 137104236SrwatsonTUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe); 138103513Srwatson 139100979Srwatsonstatic int mac_enforce_process = 1; 140100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW, 141100979Srwatson &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations"); 142100979SrwatsonTUNABLE_INT("security.mac.enforce_process", &mac_enforce_process); 143100979Srwatson 144106024Srwatsonstatic int mac_enforce_reboot = 1; 145106024SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_reboot, CTLFLAG_RW, 146106024Srwatson &mac_enforce_reboot, 0, "Enforce MAC policy for reboot operations"); 147106024SrwatsonTUNABLE_INT("security.mac.enforce_reboot", &mac_enforce_reboot); 148106024Srwatson 149100979Srwatsonstatic int mac_enforce_socket = 1; 150100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 151100979Srwatson &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 152100979SrwatsonTUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 153100979Srwatson 154103514Srwatsonstatic int mac_enforce_vm = 1; 155103514SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW, 156103514Srwatson &mac_enforce_vm, 0, "Enforce MAC policy on vm operations"); 157104236SrwatsonTUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm); 158103514Srwatson 159100979Srwatsonstatic int mac_cache_fslabel_in_vnode = 1; 160100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW, 161100979Srwatson &mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode"); 162100979SrwatsonTUNABLE_INT("security.mac.cache_fslabel_in_vnode", 163100979Srwatson &mac_cache_fslabel_in_vnode); 164100979Srwatson 165103136Srwatsonstatic int mac_mmap_revocation = 1; 166103136SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW, 167103136Srwatson &mac_mmap_revocation, 0, "Revoke mmap access to files on subject " 168103136Srwatson "relabel"); 169101892Srwatsonstatic int mac_mmap_revocation_via_cow = 0; 170100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW, 171100979Srwatson &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via " 172100979Srwatson "copy-on-write semantics, or by removing all write access"); 173100979Srwatson 174101988Srwatson#ifdef MAC_DEBUG 175104268SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0, 176104268Srwatson "TrustedBSD MAC debug info"); 177104268Srwatson 178104268Srwatsonstatic int mac_debug_label_fallback = 0; 179104268SrwatsonSYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW, 180104268Srwatson &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label" 181104268Srwatson "when label is corrupted."); 182104268SrwatsonTUNABLE_INT("security.mac.debug_label_fallback", 183104268Srwatson &mac_debug_label_fallback); 184104268Srwatson 185104517SrwatsonSYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0, 186104517Srwatson "TrustedBSD MAC object counters"); 187104517Srwatson 188100979Srwatsonstatic unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs, 189100979Srwatson nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents, 190100979Srwatson nmacipqs, nmacpipes; 191104517Srwatson 192104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD, 193100979Srwatson &nmacmbufs, 0, "number of mbufs in use"); 194104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD, 195100979Srwatson &nmaccreds, 0, "number of ucreds in use"); 196104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD, 197100979Srwatson &nmacifnets, 0, "number of ifnets in use"); 198104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD, 199100979Srwatson &nmacipqs, 0, "number of ipqs in use"); 200104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD, 201100979Srwatson &nmacbpfdescs, 0, "number of bpfdescs in use"); 202104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD, 203100979Srwatson &nmacsockets, 0, "number of sockets in use"); 204104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, pipes, CTLFLAG_RD, 205100979Srwatson &nmacpipes, 0, "number of pipes in use"); 206104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD, 207100979Srwatson &nmacmounts, 0, "number of mounts in use"); 208104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD, 209100979Srwatson &nmactemp, 0, "number of temporary labels in use"); 210104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD, 211100979Srwatson &nmacvnodes, 0, "number of vnodes in use"); 212104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD, 213100979Srwatson &nmacdevfsdirents, 0, "number of devfs dirents inuse"); 214101988Srwatson#endif 215100979Srwatson 216100979Srwatsonstatic int error_select(int error1, int error2); 217100979Srwatsonstatic int mac_policy_register(struct mac_policy_conf *mpc); 218100979Srwatsonstatic int mac_policy_unregister(struct mac_policy_conf *mpc); 219100979Srwatson 220104546Srwatsonstatic void mac_check_vnode_mmap_downgrade(struct ucred *cred, 221104546Srwatson struct vnode *vp, int *prot); 222100979Srwatsonstatic void mac_cred_mmapped_drop_perms_recurse(struct thread *td, 223100979Srwatson struct ucred *cred, struct vm_map *map); 224100979Srwatson 225104541Srwatsonstatic void mac_destroy_socket_label(struct label *label); 226104541Srwatson 227105988Srwatsonstatic int mac_setlabel_vnode_extattr(struct ucred *cred, 228105988Srwatson struct vnode *vp, struct label *intlabel); 229105988Srwatson 230105988Srwatson 231100979SrwatsonMALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector"); 232100979SrwatsonMALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes"); 233105694SrwatsonMALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage"); 234100979Srwatson 235100979Srwatson/* 236100979Srwatson * mac_policy_list_lock protects the consistency of 'mac_policy_list', 237100979Srwatson * the linked list of attached policy modules. Read-only consumers of 238100979Srwatson * the list must acquire a shared lock for the duration of their use; 239100979Srwatson * writers must acquire an exclusive lock. Note that for compound 240100979Srwatson * operations, locks should be held for the entire compound operation, 241100979Srwatson * and that this is not yet done for relabel requests. 242100979Srwatson */ 243100979Srwatsonstatic struct mtx mac_policy_list_lock; 244100979Srwatsonstatic LIST_HEAD(, mac_policy_conf) mac_policy_list; 245100979Srwatsonstatic int mac_policy_list_busy; 246100979Srwatson#define MAC_POLICY_LIST_LOCKINIT() mtx_init(&mac_policy_list_lock, \ 247100979Srwatson "mac_policy_list_lock", NULL, MTX_DEF); 248100979Srwatson#define MAC_POLICY_LIST_LOCK() mtx_lock(&mac_policy_list_lock); 249100979Srwatson#define MAC_POLICY_LIST_UNLOCK() mtx_unlock(&mac_policy_list_lock); 250100979Srwatson 251100979Srwatson#define MAC_POLICY_LIST_BUSY() do { \ 252100979Srwatson MAC_POLICY_LIST_LOCK(); \ 253100979Srwatson mac_policy_list_busy++; \ 254100979Srwatson MAC_POLICY_LIST_UNLOCK(); \ 255100979Srwatson} while (0) 256100979Srwatson 257100979Srwatson#define MAC_POLICY_LIST_UNBUSY() do { \ 258100979Srwatson MAC_POLICY_LIST_LOCK(); \ 259100979Srwatson mac_policy_list_busy--; \ 260100979Srwatson if (mac_policy_list_busy < 0) \ 261100979Srwatson panic("Extra mac_policy_list_busy--"); \ 262100979Srwatson MAC_POLICY_LIST_UNLOCK(); \ 263100979Srwatson} while (0) 264100979Srwatson 265100979Srwatson/* 266100979Srwatson * MAC_CHECK performs the designated check by walking the policy 267100979Srwatson * module list and checking with each as to how it feels about the 268100979Srwatson * request. Note that it returns its value via 'error' in the scope 269100979Srwatson * of the caller. 270100979Srwatson */ 271100979Srwatson#define MAC_CHECK(check, args...) do { \ 272100979Srwatson struct mac_policy_conf *mpc; \ 273100979Srwatson \ 274100979Srwatson error = 0; \ 275100979Srwatson MAC_POLICY_LIST_BUSY(); \ 276100979Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 277100979Srwatson if (mpc->mpc_ops->mpo_ ## check != NULL) \ 278100979Srwatson error = error_select( \ 279100979Srwatson mpc->mpc_ops->mpo_ ## check (args), \ 280100979Srwatson error); \ 281100979Srwatson } \ 282100979Srwatson MAC_POLICY_LIST_UNBUSY(); \ 283100979Srwatson} while (0) 284100979Srwatson 285100979Srwatson/* 286100979Srwatson * MAC_BOOLEAN performs the designated boolean composition by walking 287100979Srwatson * the module list, invoking each instance of the operation, and 288100979Srwatson * combining the results using the passed C operator. Note that it 289100979Srwatson * returns its value via 'result' in the scope of the caller, which 290100979Srwatson * should be initialized by the caller in a meaningful way to get 291100979Srwatson * a meaningful result. 292100979Srwatson */ 293100979Srwatson#define MAC_BOOLEAN(operation, composition, args...) do { \ 294100979Srwatson struct mac_policy_conf *mpc; \ 295100979Srwatson \ 296100979Srwatson MAC_POLICY_LIST_BUSY(); \ 297100979Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 298100979Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 299100979Srwatson result = result composition \ 300100979Srwatson mpc->mpc_ops->mpo_ ## operation (args); \ 301100979Srwatson } \ 302100979Srwatson MAC_POLICY_LIST_UNBUSY(); \ 303100979Srwatson} while (0) 304100979Srwatson 305105694Srwatson#define MAC_EXTERNALIZE(type, label, elementlist, outbuf, \ 306105694Srwatson outbuflen) do { \ 307105694Srwatson char *curptr, *curptr_start, *element_name, *element_temp; \ 308105694Srwatson size_t left, left_start, len; \ 309105694Srwatson int claimed, first, first_start, ignorenotfound; \ 310105694Srwatson \ 311105694Srwatson error = 0; \ 312105694Srwatson element_temp = elementlist; \ 313105694Srwatson curptr = outbuf; \ 314105694Srwatson curptr[0] = '\0'; \ 315105694Srwatson left = outbuflen; \ 316105694Srwatson first = 1; \ 317105694Srwatson while ((element_name = strsep(&element_temp, ",")) != NULL) { \ 318105694Srwatson curptr_start = curptr; \ 319105694Srwatson left_start = left; \ 320105694Srwatson first_start = first; \ 321105694Srwatson if (element_name[0] == '?') { \ 322105694Srwatson element_name++; \ 323105694Srwatson ignorenotfound = 1; \ 324105694Srwatson } else \ 325105694Srwatson ignorenotfound = 0; \ 326105694Srwatson claimed = 0; \ 327105694Srwatson if (first) { \ 328105694Srwatson len = snprintf(curptr, left, "%s/", \ 329105694Srwatson element_name); \ 330105694Srwatson first = 0; \ 331105694Srwatson } else \ 332105694Srwatson len = snprintf(curptr, left, ",%s/", \ 333105694Srwatson element_name); \ 334105694Srwatson if (len >= left) { \ 335105694Srwatson error = EINVAL; /* XXXMAC: E2BIG */ \ 336105694Srwatson break; \ 337105694Srwatson } \ 338105694Srwatson curptr += len; \ 339105694Srwatson left -= len; \ 340105694Srwatson \ 341105694Srwatson MAC_CHECK(externalize_ ## type, label, element_name, \ 342105694Srwatson curptr, left, &len, &claimed); \ 343105694Srwatson if (error) \ 344105694Srwatson break; \ 345105694Srwatson if (claimed == 1) { \ 346105694Srwatson if (len >= outbuflen) { \ 347105694Srwatson error = EINVAL; /* XXXMAC: E2BIG */ \ 348105694Srwatson break; \ 349105694Srwatson } \ 350105694Srwatson curptr += len; \ 351105694Srwatson left -= len; \ 352105694Srwatson } else if (claimed == 0 && ignorenotfound) { \ 353105694Srwatson /* \ 354105694Srwatson * Revert addition of the label element \ 355105694Srwatson * name. \ 356105694Srwatson */ \ 357105694Srwatson curptr = curptr_start; \ 358105694Srwatson *curptr = '\0'; \ 359105694Srwatson left = left_start; \ 360105694Srwatson first = first_start; \ 361105694Srwatson } else { \ 362105694Srwatson error = EINVAL; /* XXXMAC: ENOLABEL */ \ 363105694Srwatson break; \ 364105694Srwatson } \ 365105694Srwatson } \ 366105694Srwatson} while (0) 367105694Srwatson 368105694Srwatson#define MAC_INTERNALIZE(type, label, instring) do { \ 369105694Srwatson char *element, *element_name, *element_data; \ 370105694Srwatson int claimed; \ 371105694Srwatson \ 372105694Srwatson error = 0; \ 373105694Srwatson element = instring; \ 374105694Srwatson while ((element_name = strsep(&element, ",")) != NULL) { \ 375105694Srwatson element_data = element_name; \ 376105694Srwatson element_name = strsep(&element_data, "/"); \ 377105694Srwatson if (element_data == NULL) { \ 378105694Srwatson error = EINVAL; \ 379105694Srwatson break; \ 380105694Srwatson } \ 381105694Srwatson claimed = 0; \ 382105694Srwatson MAC_CHECK(internalize_ ## type, label, element_name, \ 383105694Srwatson element_data, &claimed); \ 384105694Srwatson if (error) \ 385105694Srwatson break; \ 386105694Srwatson if (claimed != 1) { \ 387105694Srwatson /* XXXMAC: Another error here? */ \ 388105694Srwatson error = EINVAL; \ 389105694Srwatson break; \ 390105694Srwatson } \ 391105694Srwatson } \ 392105694Srwatson} while (0) 393105694Srwatson 394100979Srwatson/* 395100979Srwatson * MAC_PERFORM performs the designated operation by walking the policy 396100979Srwatson * module list and invoking that operation for each policy. 397100979Srwatson */ 398100979Srwatson#define MAC_PERFORM(operation, args...) do { \ 399100979Srwatson struct mac_policy_conf *mpc; \ 400100979Srwatson \ 401100979Srwatson MAC_POLICY_LIST_BUSY(); \ 402100979Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 403100979Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 404100979Srwatson mpc->mpc_ops->mpo_ ## operation (args); \ 405100979Srwatson } \ 406100979Srwatson MAC_POLICY_LIST_UNBUSY(); \ 407100979Srwatson} while (0) 408100979Srwatson 409100979Srwatson/* 410100979Srwatson * Initialize the MAC subsystem, including appropriate SMP locks. 411100979Srwatson */ 412100979Srwatsonstatic void 413100979Srwatsonmac_init(void) 414100979Srwatson{ 415100979Srwatson 416100979Srwatson LIST_INIT(&mac_policy_list); 417100979Srwatson MAC_POLICY_LIST_LOCKINIT(); 418100979Srwatson} 419100979Srwatson 420100979Srwatson/* 421100979Srwatson * For the purposes of modules that want to know if they were loaded 422100979Srwatson * "early", set the mac_late flag once we've processed modules either 423100979Srwatson * linked into the kernel, or loaded before the kernel startup. 424100979Srwatson */ 425100979Srwatsonstatic void 426100979Srwatsonmac_late_init(void) 427100979Srwatson{ 428100979Srwatson 429100979Srwatson mac_late = 1; 430100979Srwatson} 431100979Srwatson 432100979Srwatson/* 433100979Srwatson * Allow MAC policy modules to register during boot, etc. 434100979Srwatson */ 435100894Srwatsonint 436100979Srwatsonmac_policy_modevent(module_t mod, int type, void *data) 437100979Srwatson{ 438100979Srwatson struct mac_policy_conf *mpc; 439100979Srwatson int error; 440100979Srwatson 441100979Srwatson error = 0; 442100979Srwatson mpc = (struct mac_policy_conf *) data; 443100979Srwatson 444100979Srwatson switch (type) { 445100979Srwatson case MOD_LOAD: 446100979Srwatson if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && 447100979Srwatson mac_late) { 448100979Srwatson printf("mac_policy_modevent: can't load %s policy " 449100979Srwatson "after booting\n", mpc->mpc_name); 450100979Srwatson error = EBUSY; 451100979Srwatson break; 452100979Srwatson } 453100979Srwatson error = mac_policy_register(mpc); 454100979Srwatson break; 455100979Srwatson case MOD_UNLOAD: 456100979Srwatson /* Don't unregister the module if it was never registered. */ 457100979Srwatson if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) 458100979Srwatson != 0) 459100979Srwatson error = mac_policy_unregister(mpc); 460100979Srwatson else 461100979Srwatson error = 0; 462100979Srwatson break; 463100979Srwatson default: 464100979Srwatson break; 465100979Srwatson } 466100979Srwatson 467100979Srwatson return (error); 468100979Srwatson} 469100979Srwatson 470100979Srwatsonstatic int 471100979Srwatsonmac_policy_register(struct mac_policy_conf *mpc) 472100979Srwatson{ 473100979Srwatson struct mac_policy_conf *tmpc; 474100979Srwatson struct mac_policy_op_entry *mpe; 475100979Srwatson int slot; 476100979Srwatson 477103570Srwatson MALLOC(mpc->mpc_ops, struct mac_policy_ops *, sizeof(*mpc->mpc_ops), 478103570Srwatson M_MACOPVEC, M_WAITOK | M_ZERO); 479100979Srwatson for (mpe = mpc->mpc_entries; mpe->mpe_constant != MAC_OP_LAST; mpe++) { 480100979Srwatson switch (mpe->mpe_constant) { 481100979Srwatson case MAC_OP_LAST: 482100979Srwatson /* 483100979Srwatson * Doesn't actually happen, but this allows checking 484100979Srwatson * that all enumerated values are handled. 485100979Srwatson */ 486100979Srwatson break; 487100979Srwatson case MAC_DESTROY: 488100979Srwatson mpc->mpc_ops->mpo_destroy = 489100979Srwatson mpe->mpe_function; 490100979Srwatson break; 491100979Srwatson case MAC_INIT: 492100979Srwatson mpc->mpc_ops->mpo_init = 493100979Srwatson mpe->mpe_function; 494100979Srwatson break; 495102123Srwatson case MAC_SYSCALL: 496102123Srwatson mpc->mpc_ops->mpo_syscall = 497102123Srwatson mpe->mpe_function; 498102123Srwatson break; 499104514Srwatson case MAC_INIT_BPFDESC_LABEL: 500104514Srwatson mpc->mpc_ops->mpo_init_bpfdesc_label = 501100979Srwatson mpe->mpe_function; 502100979Srwatson break; 503104514Srwatson case MAC_INIT_CRED_LABEL: 504104514Srwatson mpc->mpc_ops->mpo_init_cred_label = 505100979Srwatson mpe->mpe_function; 506100979Srwatson break; 507104514Srwatson case MAC_INIT_DEVFSDIRENT_LABEL: 508104514Srwatson mpc->mpc_ops->mpo_init_devfsdirent_label = 509100979Srwatson mpe->mpe_function; 510100979Srwatson break; 511104514Srwatson case MAC_INIT_IFNET_LABEL: 512104514Srwatson mpc->mpc_ops->mpo_init_ifnet_label = 513100979Srwatson mpe->mpe_function; 514100979Srwatson break; 515104514Srwatson case MAC_INIT_IPQ_LABEL: 516104514Srwatson mpc->mpc_ops->mpo_init_ipq_label = 517100979Srwatson mpe->mpe_function; 518100979Srwatson break; 519104514Srwatson case MAC_INIT_MBUF_LABEL: 520104514Srwatson mpc->mpc_ops->mpo_init_mbuf_label = 521100979Srwatson mpe->mpe_function; 522100979Srwatson break; 523104514Srwatson case MAC_INIT_MOUNT_LABEL: 524104514Srwatson mpc->mpc_ops->mpo_init_mount_label = 525100979Srwatson mpe->mpe_function; 526100979Srwatson break; 527104514Srwatson case MAC_INIT_MOUNT_FS_LABEL: 528104514Srwatson mpc->mpc_ops->mpo_init_mount_fs_label = 529100979Srwatson mpe->mpe_function; 530100979Srwatson break; 531104514Srwatson case MAC_INIT_PIPE_LABEL: 532104514Srwatson mpc->mpc_ops->mpo_init_pipe_label = 533100979Srwatson mpe->mpe_function; 534100979Srwatson break; 535104514Srwatson case MAC_INIT_SOCKET_LABEL: 536104514Srwatson mpc->mpc_ops->mpo_init_socket_label = 537100979Srwatson mpe->mpe_function; 538100979Srwatson break; 539104514Srwatson case MAC_INIT_SOCKET_PEER_LABEL: 540104514Srwatson mpc->mpc_ops->mpo_init_socket_peer_label = 541100979Srwatson mpe->mpe_function; 542100979Srwatson break; 543104514Srwatson case MAC_INIT_VNODE_LABEL: 544104514Srwatson mpc->mpc_ops->mpo_init_vnode_label = 545100979Srwatson mpe->mpe_function; 546100979Srwatson break; 547104514Srwatson case MAC_DESTROY_BPFDESC_LABEL: 548104514Srwatson mpc->mpc_ops->mpo_destroy_bpfdesc_label = 549100979Srwatson mpe->mpe_function; 550100979Srwatson break; 551104514Srwatson case MAC_DESTROY_CRED_LABEL: 552104514Srwatson mpc->mpc_ops->mpo_destroy_cred_label = 553100979Srwatson mpe->mpe_function; 554100979Srwatson break; 555104514Srwatson case MAC_DESTROY_DEVFSDIRENT_LABEL: 556104514Srwatson mpc->mpc_ops->mpo_destroy_devfsdirent_label = 557100979Srwatson mpe->mpe_function; 558100979Srwatson break; 559104514Srwatson case MAC_DESTROY_IFNET_LABEL: 560104514Srwatson mpc->mpc_ops->mpo_destroy_ifnet_label = 561100979Srwatson mpe->mpe_function; 562100979Srwatson break; 563104514Srwatson case MAC_DESTROY_IPQ_LABEL: 564104514Srwatson mpc->mpc_ops->mpo_destroy_ipq_label = 565100979Srwatson mpe->mpe_function; 566100979Srwatson break; 567104514Srwatson case MAC_DESTROY_MBUF_LABEL: 568104514Srwatson mpc->mpc_ops->mpo_destroy_mbuf_label = 569100979Srwatson mpe->mpe_function; 570100979Srwatson break; 571104514Srwatson case MAC_DESTROY_MOUNT_LABEL: 572104514Srwatson mpc->mpc_ops->mpo_destroy_mount_label = 573100979Srwatson mpe->mpe_function; 574100979Srwatson break; 575104514Srwatson case MAC_DESTROY_MOUNT_FS_LABEL: 576104514Srwatson mpc->mpc_ops->mpo_destroy_mount_fs_label = 577100979Srwatson mpe->mpe_function; 578100979Srwatson break; 579104514Srwatson case MAC_DESTROY_PIPE_LABEL: 580104514Srwatson mpc->mpc_ops->mpo_destroy_pipe_label = 581100979Srwatson mpe->mpe_function; 582100979Srwatson break; 583104514Srwatson case MAC_DESTROY_SOCKET_LABEL: 584104514Srwatson mpc->mpc_ops->mpo_destroy_socket_label = 585104514Srwatson mpe->mpe_function; 586104514Srwatson break; 587104514Srwatson case MAC_DESTROY_SOCKET_PEER_LABEL: 588104514Srwatson mpc->mpc_ops->mpo_destroy_socket_peer_label = 589104514Srwatson mpe->mpe_function; 590104514Srwatson break; 591104514Srwatson case MAC_DESTROY_VNODE_LABEL: 592104514Srwatson mpc->mpc_ops->mpo_destroy_vnode_label = 593104514Srwatson mpe->mpe_function; 594104514Srwatson break; 595105694Srwatson case MAC_COPY_PIPE_LABEL: 596105694Srwatson mpc->mpc_ops->mpo_copy_pipe_label = 597100979Srwatson mpe->mpe_function; 598100979Srwatson break; 599105694Srwatson case MAC_COPY_VNODE_LABEL: 600105694Srwatson mpc->mpc_ops->mpo_copy_vnode_label = 601100979Srwatson mpe->mpe_function; 602100979Srwatson break; 603105694Srwatson case MAC_EXTERNALIZE_CRED_LABEL: 604105694Srwatson mpc->mpc_ops->mpo_externalize_cred_label = 605105694Srwatson mpe->mpe_function; 606105694Srwatson break; 607105694Srwatson case MAC_EXTERNALIZE_IFNET_LABEL: 608105694Srwatson mpc->mpc_ops->mpo_externalize_ifnet_label = 609105694Srwatson mpe->mpe_function; 610105694Srwatson break; 611105694Srwatson case MAC_EXTERNALIZE_PIPE_LABEL: 612105694Srwatson mpc->mpc_ops->mpo_externalize_pipe_label = 613105694Srwatson mpe->mpe_function; 614105694Srwatson break; 615105694Srwatson case MAC_EXTERNALIZE_SOCKET_LABEL: 616105694Srwatson mpc->mpc_ops->mpo_externalize_socket_label = 617105694Srwatson mpe->mpe_function; 618105694Srwatson break; 619105694Srwatson case MAC_EXTERNALIZE_SOCKET_PEER_LABEL: 620105694Srwatson mpc->mpc_ops->mpo_externalize_socket_peer_label = 621105694Srwatson mpe->mpe_function; 622105694Srwatson break; 623105694Srwatson case MAC_EXTERNALIZE_VNODE_LABEL: 624105694Srwatson mpc->mpc_ops->mpo_externalize_vnode_label = 625105694Srwatson mpe->mpe_function; 626105694Srwatson break; 627105694Srwatson case MAC_INTERNALIZE_CRED_LABEL: 628105694Srwatson mpc->mpc_ops->mpo_internalize_cred_label = 629105694Srwatson mpe->mpe_function; 630105694Srwatson break; 631105694Srwatson case MAC_INTERNALIZE_IFNET_LABEL: 632105694Srwatson mpc->mpc_ops->mpo_internalize_ifnet_label = 633105694Srwatson mpe->mpe_function; 634105694Srwatson break; 635105694Srwatson case MAC_INTERNALIZE_PIPE_LABEL: 636105694Srwatson mpc->mpc_ops->mpo_internalize_pipe_label = 637105694Srwatson mpe->mpe_function; 638105694Srwatson break; 639105694Srwatson case MAC_INTERNALIZE_SOCKET_LABEL: 640105694Srwatson mpc->mpc_ops->mpo_internalize_socket_label = 641105694Srwatson mpe->mpe_function; 642105694Srwatson break; 643105694Srwatson case MAC_INTERNALIZE_VNODE_LABEL: 644105694Srwatson mpc->mpc_ops->mpo_internalize_vnode_label = 645105694Srwatson mpe->mpe_function; 646105694Srwatson break; 647100979Srwatson case MAC_CREATE_DEVFS_DEVICE: 648100979Srwatson mpc->mpc_ops->mpo_create_devfs_device = 649100979Srwatson mpe->mpe_function; 650100979Srwatson break; 651100979Srwatson case MAC_CREATE_DEVFS_DIRECTORY: 652100979Srwatson mpc->mpc_ops->mpo_create_devfs_directory = 653100979Srwatson mpe->mpe_function; 654100979Srwatson break; 655104533Srwatson case MAC_CREATE_DEVFS_SYMLINK: 656104533Srwatson mpc->mpc_ops->mpo_create_devfs_symlink = 657104533Srwatson mpe->mpe_function; 658104533Srwatson break; 659100979Srwatson case MAC_CREATE_DEVFS_VNODE: 660100979Srwatson mpc->mpc_ops->mpo_create_devfs_vnode = 661100979Srwatson mpe->mpe_function; 662100979Srwatson break; 663100979Srwatson case MAC_CREATE_MOUNT: 664100979Srwatson mpc->mpc_ops->mpo_create_mount = 665100979Srwatson mpe->mpe_function; 666100979Srwatson break; 667100979Srwatson case MAC_CREATE_ROOT_MOUNT: 668100979Srwatson mpc->mpc_ops->mpo_create_root_mount = 669100979Srwatson mpe->mpe_function; 670100979Srwatson break; 671100979Srwatson case MAC_RELABEL_VNODE: 672100979Srwatson mpc->mpc_ops->mpo_relabel_vnode = 673100979Srwatson mpe->mpe_function; 674100979Srwatson break; 675100979Srwatson case MAC_UPDATE_DEVFSDIRENT: 676100979Srwatson mpc->mpc_ops->mpo_update_devfsdirent = 677100979Srwatson mpe->mpe_function; 678100979Srwatson break; 679105988Srwatson case MAC_ASSOCIATE_VNODE_DEVFS: 680105988Srwatson mpc->mpc_ops->mpo_associate_vnode_devfs = 681100979Srwatson mpe->mpe_function; 682100979Srwatson break; 683105988Srwatson case MAC_ASSOCIATE_VNODE_EXTATTR: 684105988Srwatson mpc->mpc_ops->mpo_associate_vnode_extattr = 685100979Srwatson mpe->mpe_function; 686100979Srwatson break; 687105988Srwatson case MAC_ASSOCIATE_VNODE_SINGLELABEL: 688105988Srwatson mpc->mpc_ops->mpo_associate_vnode_singlelabel = 689100979Srwatson mpe->mpe_function; 690100979Srwatson break; 691105988Srwatson case MAC_CREATE_VNODE_EXTATTR: 692105988Srwatson mpc->mpc_ops->mpo_create_vnode_extattr = 693100979Srwatson mpe->mpe_function; 694100979Srwatson break; 695105988Srwatson case MAC_SETLABEL_VNODE_EXTATTR: 696105988Srwatson mpc->mpc_ops->mpo_setlabel_vnode_extattr = 697105988Srwatson mpe->mpe_function; 698105988Srwatson break; 699100979Srwatson case MAC_CREATE_MBUF_FROM_SOCKET: 700100979Srwatson mpc->mpc_ops->mpo_create_mbuf_from_socket = 701100979Srwatson mpe->mpe_function; 702100979Srwatson break; 703100979Srwatson case MAC_CREATE_PIPE: 704100979Srwatson mpc->mpc_ops->mpo_create_pipe = 705100979Srwatson mpe->mpe_function; 706100979Srwatson break; 707100979Srwatson case MAC_CREATE_SOCKET: 708100979Srwatson mpc->mpc_ops->mpo_create_socket = 709100979Srwatson mpe->mpe_function; 710100979Srwatson break; 711100979Srwatson case MAC_CREATE_SOCKET_FROM_SOCKET: 712100979Srwatson mpc->mpc_ops->mpo_create_socket_from_socket = 713100979Srwatson mpe->mpe_function; 714100979Srwatson break; 715100979Srwatson case MAC_RELABEL_PIPE: 716100979Srwatson mpc->mpc_ops->mpo_relabel_pipe = 717100979Srwatson mpe->mpe_function; 718100979Srwatson break; 719100979Srwatson case MAC_RELABEL_SOCKET: 720100979Srwatson mpc->mpc_ops->mpo_relabel_socket = 721100979Srwatson mpe->mpe_function; 722100979Srwatson break; 723100979Srwatson case MAC_SET_SOCKET_PEER_FROM_MBUF: 724100979Srwatson mpc->mpc_ops->mpo_set_socket_peer_from_mbuf = 725100979Srwatson mpe->mpe_function; 726100979Srwatson break; 727100979Srwatson case MAC_SET_SOCKET_PEER_FROM_SOCKET: 728100979Srwatson mpc->mpc_ops->mpo_set_socket_peer_from_socket = 729100979Srwatson mpe->mpe_function; 730100979Srwatson break; 731100979Srwatson case MAC_CREATE_BPFDESC: 732100979Srwatson mpc->mpc_ops->mpo_create_bpfdesc = 733100979Srwatson mpe->mpe_function; 734100979Srwatson break; 735100979Srwatson case MAC_CREATE_DATAGRAM_FROM_IPQ: 736100979Srwatson mpc->mpc_ops->mpo_create_datagram_from_ipq = 737100979Srwatson mpe->mpe_function; 738100979Srwatson break; 739100979Srwatson case MAC_CREATE_FRAGMENT: 740100979Srwatson mpc->mpc_ops->mpo_create_fragment = 741100979Srwatson mpe->mpe_function; 742100979Srwatson break; 743100979Srwatson case MAC_CREATE_IFNET: 744100979Srwatson mpc->mpc_ops->mpo_create_ifnet = 745100979Srwatson mpe->mpe_function; 746100979Srwatson break; 747100979Srwatson case MAC_CREATE_IPQ: 748100979Srwatson mpc->mpc_ops->mpo_create_ipq = 749100979Srwatson mpe->mpe_function; 750100979Srwatson break; 751100979Srwatson case MAC_CREATE_MBUF_FROM_MBUF: 752100979Srwatson mpc->mpc_ops->mpo_create_mbuf_from_mbuf = 753100979Srwatson mpe->mpe_function; 754100979Srwatson break; 755100979Srwatson case MAC_CREATE_MBUF_LINKLAYER: 756100979Srwatson mpc->mpc_ops->mpo_create_mbuf_linklayer = 757100979Srwatson mpe->mpe_function; 758100979Srwatson break; 759100979Srwatson case MAC_CREATE_MBUF_FROM_BPFDESC: 760100979Srwatson mpc->mpc_ops->mpo_create_mbuf_from_bpfdesc = 761100979Srwatson mpe->mpe_function; 762100979Srwatson break; 763100979Srwatson case MAC_CREATE_MBUF_FROM_IFNET: 764100979Srwatson mpc->mpc_ops->mpo_create_mbuf_from_ifnet = 765100979Srwatson mpe->mpe_function; 766100979Srwatson break; 767100979Srwatson case MAC_CREATE_MBUF_MULTICAST_ENCAP: 768100979Srwatson mpc->mpc_ops->mpo_create_mbuf_multicast_encap = 769100979Srwatson mpe->mpe_function; 770100979Srwatson break; 771100979Srwatson case MAC_CREATE_MBUF_NETLAYER: 772100979Srwatson mpc->mpc_ops->mpo_create_mbuf_netlayer = 773100979Srwatson mpe->mpe_function; 774100979Srwatson break; 775100979Srwatson case MAC_FRAGMENT_MATCH: 776100979Srwatson mpc->mpc_ops->mpo_fragment_match = 777100979Srwatson mpe->mpe_function; 778100979Srwatson break; 779100979Srwatson case MAC_RELABEL_IFNET: 780100979Srwatson mpc->mpc_ops->mpo_relabel_ifnet = 781100979Srwatson mpe->mpe_function; 782100979Srwatson break; 783100979Srwatson case MAC_UPDATE_IPQ: 784100979Srwatson mpc->mpc_ops->mpo_update_ipq = 785100979Srwatson mpe->mpe_function; 786100979Srwatson break; 787100979Srwatson case MAC_CREATE_CRED: 788100979Srwatson mpc->mpc_ops->mpo_create_cred = 789100979Srwatson mpe->mpe_function; 790100979Srwatson break; 791100979Srwatson case MAC_EXECVE_TRANSITION: 792100979Srwatson mpc->mpc_ops->mpo_execve_transition = 793100979Srwatson mpe->mpe_function; 794100979Srwatson break; 795100979Srwatson case MAC_EXECVE_WILL_TRANSITION: 796100979Srwatson mpc->mpc_ops->mpo_execve_will_transition = 797100979Srwatson mpe->mpe_function; 798100979Srwatson break; 799100979Srwatson case MAC_CREATE_PROC0: 800104518Srwatson mpc->mpc_ops->mpo_create_proc0 = 801104518Srwatson mpe->mpe_function; 802100979Srwatson break; 803100979Srwatson case MAC_CREATE_PROC1: 804104518Srwatson mpc->mpc_ops->mpo_create_proc1 = 805104518Srwatson mpe->mpe_function; 806100979Srwatson break; 807100979Srwatson case MAC_RELABEL_CRED: 808100979Srwatson mpc->mpc_ops->mpo_relabel_cred = 809100979Srwatson mpe->mpe_function; 810100979Srwatson break; 811104338Srwatson case MAC_THREAD_USERRET: 812104338Srwatson mpc->mpc_ops->mpo_thread_userret = 813104338Srwatson mpe->mpe_function; 814104338Srwatson break; 815100979Srwatson case MAC_CHECK_BPFDESC_RECEIVE: 816100979Srwatson mpc->mpc_ops->mpo_check_bpfdesc_receive = 817100979Srwatson mpe->mpe_function; 818100979Srwatson break; 819100979Srwatson case MAC_CHECK_CRED_RELABEL: 820100979Srwatson mpc->mpc_ops->mpo_check_cred_relabel = 821100979Srwatson mpe->mpe_function; 822100979Srwatson break; 823100979Srwatson case MAC_CHECK_CRED_VISIBLE: 824100979Srwatson mpc->mpc_ops->mpo_check_cred_visible = 825100979Srwatson mpe->mpe_function; 826100979Srwatson break; 827100979Srwatson case MAC_CHECK_IFNET_RELABEL: 828100979Srwatson mpc->mpc_ops->mpo_check_ifnet_relabel = 829100979Srwatson mpe->mpe_function; 830100979Srwatson break; 831100979Srwatson case MAC_CHECK_IFNET_TRANSMIT: 832100979Srwatson mpc->mpc_ops->mpo_check_ifnet_transmit = 833100979Srwatson mpe->mpe_function; 834100979Srwatson break; 835100979Srwatson case MAC_CHECK_MOUNT_STAT: 836100979Srwatson mpc->mpc_ops->mpo_check_mount_stat = 837100979Srwatson mpe->mpe_function; 838100979Srwatson break; 839100979Srwatson case MAC_CHECK_PIPE_IOCTL: 840100979Srwatson mpc->mpc_ops->mpo_check_pipe_ioctl = 841100979Srwatson mpe->mpe_function; 842100979Srwatson break; 843102115Srwatson case MAC_CHECK_PIPE_POLL: 844102115Srwatson mpc->mpc_ops->mpo_check_pipe_poll = 845100979Srwatson mpe->mpe_function; 846100979Srwatson break; 847102115Srwatson case MAC_CHECK_PIPE_READ: 848102115Srwatson mpc->mpc_ops->mpo_check_pipe_read = 849102115Srwatson mpe->mpe_function; 850102115Srwatson break; 851100979Srwatson case MAC_CHECK_PIPE_RELABEL: 852100979Srwatson mpc->mpc_ops->mpo_check_pipe_relabel = 853100979Srwatson mpe->mpe_function; 854100979Srwatson break; 855102115Srwatson case MAC_CHECK_PIPE_STAT: 856102115Srwatson mpc->mpc_ops->mpo_check_pipe_stat = 857102115Srwatson mpe->mpe_function; 858102115Srwatson break; 859102115Srwatson case MAC_CHECK_PIPE_WRITE: 860102115Srwatson mpc->mpc_ops->mpo_check_pipe_write = 861102115Srwatson mpe->mpe_function; 862102115Srwatson break; 863100979Srwatson case MAC_CHECK_PROC_DEBUG: 864100979Srwatson mpc->mpc_ops->mpo_check_proc_debug = 865100979Srwatson mpe->mpe_function; 866100979Srwatson break; 867100979Srwatson case MAC_CHECK_PROC_SCHED: 868100979Srwatson mpc->mpc_ops->mpo_check_proc_sched = 869100979Srwatson mpe->mpe_function; 870100979Srwatson break; 871100979Srwatson case MAC_CHECK_PROC_SIGNAL: 872100979Srwatson mpc->mpc_ops->mpo_check_proc_signal = 873100979Srwatson mpe->mpe_function; 874100979Srwatson break; 875100979Srwatson case MAC_CHECK_SOCKET_BIND: 876100979Srwatson mpc->mpc_ops->mpo_check_socket_bind = 877100979Srwatson mpe->mpe_function; 878100979Srwatson break; 879100979Srwatson case MAC_CHECK_SOCKET_CONNECT: 880100979Srwatson mpc->mpc_ops->mpo_check_socket_connect = 881100979Srwatson mpe->mpe_function; 882100979Srwatson break; 883101933Srwatson case MAC_CHECK_SOCKET_DELIVER: 884101933Srwatson mpc->mpc_ops->mpo_check_socket_deliver = 885101933Srwatson mpe->mpe_function; 886101933Srwatson break; 887100979Srwatson case MAC_CHECK_SOCKET_LISTEN: 888100979Srwatson mpc->mpc_ops->mpo_check_socket_listen = 889100979Srwatson mpe->mpe_function; 890100979Srwatson break; 891104571Srwatson case MAC_CHECK_SOCKET_RECEIVE: 892104571Srwatson mpc->mpc_ops->mpo_check_socket_receive = 893104571Srwatson mpe->mpe_function; 894104571Srwatson break; 895100979Srwatson case MAC_CHECK_SOCKET_RELABEL: 896100979Srwatson mpc->mpc_ops->mpo_check_socket_relabel = 897100979Srwatson mpe->mpe_function; 898100979Srwatson break; 899104571Srwatson case MAC_CHECK_SOCKET_SEND: 900104571Srwatson mpc->mpc_ops->mpo_check_socket_send = 901104571Srwatson mpe->mpe_function; 902104571Srwatson break; 903100979Srwatson case MAC_CHECK_SOCKET_VISIBLE: 904100979Srwatson mpc->mpc_ops->mpo_check_socket_visible = 905100979Srwatson mpe->mpe_function; 906100979Srwatson break; 907106024Srwatson case MAC_CHECK_SYSTEM_REBOOT: 908106024Srwatson mpc->mpc_ops->mpo_check_system_reboot = 909106024Srwatson mpe->mpe_function; 910106024Srwatson break; 911106023Srwatson case MAC_CHECK_SYSTEM_SWAPON: 912106023Srwatson mpc->mpc_ops->mpo_check_system_swapon = 913106023Srwatson mpe->mpe_function; 914106023Srwatson break; 915100979Srwatson case MAC_CHECK_VNODE_ACCESS: 916100979Srwatson mpc->mpc_ops->mpo_check_vnode_access = 917100979Srwatson mpe->mpe_function; 918100979Srwatson break; 919100979Srwatson case MAC_CHECK_VNODE_CHDIR: 920100979Srwatson mpc->mpc_ops->mpo_check_vnode_chdir = 921100979Srwatson mpe->mpe_function; 922100979Srwatson break; 923100979Srwatson case MAC_CHECK_VNODE_CHROOT: 924100979Srwatson mpc->mpc_ops->mpo_check_vnode_chroot = 925100979Srwatson mpe->mpe_function; 926100979Srwatson break; 927100979Srwatson case MAC_CHECK_VNODE_CREATE: 928100979Srwatson mpc->mpc_ops->mpo_check_vnode_create = 929100979Srwatson mpe->mpe_function; 930100979Srwatson break; 931100979Srwatson case MAC_CHECK_VNODE_DELETE: 932100979Srwatson mpc->mpc_ops->mpo_check_vnode_delete = 933100979Srwatson mpe->mpe_function; 934100979Srwatson break; 935100979Srwatson case MAC_CHECK_VNODE_DELETEACL: 936100979Srwatson mpc->mpc_ops->mpo_check_vnode_deleteacl = 937100979Srwatson mpe->mpe_function; 938100979Srwatson break; 939100979Srwatson case MAC_CHECK_VNODE_EXEC: 940100979Srwatson mpc->mpc_ops->mpo_check_vnode_exec = 941100979Srwatson mpe->mpe_function; 942100979Srwatson break; 943100979Srwatson case MAC_CHECK_VNODE_GETACL: 944100979Srwatson mpc->mpc_ops->mpo_check_vnode_getacl = 945100979Srwatson mpe->mpe_function; 946100979Srwatson break; 947100979Srwatson case MAC_CHECK_VNODE_GETEXTATTR: 948100979Srwatson mpc->mpc_ops->mpo_check_vnode_getextattr = 949100979Srwatson mpe->mpe_function; 950100979Srwatson break; 951104529Srwatson case MAC_CHECK_VNODE_LINK: 952104529Srwatson mpc->mpc_ops->mpo_check_vnode_link = 953104529Srwatson mpe->mpe_function; 954104529Srwatson break; 955100979Srwatson case MAC_CHECK_VNODE_LOOKUP: 956100979Srwatson mpc->mpc_ops->mpo_check_vnode_lookup = 957100979Srwatson mpe->mpe_function; 958100979Srwatson break; 959104546Srwatson case MAC_CHECK_VNODE_MMAP: 960104546Srwatson mpc->mpc_ops->mpo_check_vnode_mmap = 961100979Srwatson mpe->mpe_function; 962100979Srwatson break; 963104546Srwatson case MAC_CHECK_VNODE_MMAP_DOWNGRADE: 964104546Srwatson mpc->mpc_ops->mpo_check_vnode_mmap_downgrade = 965104546Srwatson mpe->mpe_function; 966104546Srwatson break; 967104546Srwatson case MAC_CHECK_VNODE_MPROTECT: 968104546Srwatson mpc->mpc_ops->mpo_check_vnode_mprotect = 969104546Srwatson mpe->mpe_function; 970104546Srwatson break; 971100979Srwatson case MAC_CHECK_VNODE_OPEN: 972100979Srwatson mpc->mpc_ops->mpo_check_vnode_open = 973100979Srwatson mpe->mpe_function; 974100979Srwatson break; 975102112Srwatson case MAC_CHECK_VNODE_POLL: 976102112Srwatson mpc->mpc_ops->mpo_check_vnode_poll = 977102112Srwatson mpe->mpe_function; 978102112Srwatson break; 979102112Srwatson case MAC_CHECK_VNODE_READ: 980102112Srwatson mpc->mpc_ops->mpo_check_vnode_read = 981102112Srwatson mpe->mpe_function; 982102112Srwatson break; 983100979Srwatson case MAC_CHECK_VNODE_READDIR: 984100979Srwatson mpc->mpc_ops->mpo_check_vnode_readdir = 985100979Srwatson mpe->mpe_function; 986100979Srwatson break; 987100979Srwatson case MAC_CHECK_VNODE_READLINK: 988100979Srwatson mpc->mpc_ops->mpo_check_vnode_readlink = 989100979Srwatson mpe->mpe_function; 990100979Srwatson break; 991100979Srwatson case MAC_CHECK_VNODE_RELABEL: 992100979Srwatson mpc->mpc_ops->mpo_check_vnode_relabel = 993100979Srwatson mpe->mpe_function; 994100979Srwatson break; 995100979Srwatson case MAC_CHECK_VNODE_RENAME_FROM: 996100979Srwatson mpc->mpc_ops->mpo_check_vnode_rename_from = 997100979Srwatson mpe->mpe_function; 998100979Srwatson break; 999100979Srwatson case MAC_CHECK_VNODE_RENAME_TO: 1000100979Srwatson mpc->mpc_ops->mpo_check_vnode_rename_to = 1001100979Srwatson mpe->mpe_function; 1002100979Srwatson break; 1003100979Srwatson case MAC_CHECK_VNODE_REVOKE: 1004100979Srwatson mpc->mpc_ops->mpo_check_vnode_revoke = 1005100979Srwatson mpe->mpe_function; 1006100979Srwatson break; 1007100979Srwatson case MAC_CHECK_VNODE_SETACL: 1008100979Srwatson mpc->mpc_ops->mpo_check_vnode_setacl = 1009100979Srwatson mpe->mpe_function; 1010100979Srwatson break; 1011100979Srwatson case MAC_CHECK_VNODE_SETEXTATTR: 1012100979Srwatson mpc->mpc_ops->mpo_check_vnode_setextattr = 1013100979Srwatson mpe->mpe_function; 1014100979Srwatson break; 1015100979Srwatson case MAC_CHECK_VNODE_SETFLAGS: 1016100979Srwatson mpc->mpc_ops->mpo_check_vnode_setflags = 1017100979Srwatson mpe->mpe_function; 1018100979Srwatson break; 1019100979Srwatson case MAC_CHECK_VNODE_SETMODE: 1020100979Srwatson mpc->mpc_ops->mpo_check_vnode_setmode = 1021100979Srwatson mpe->mpe_function; 1022100979Srwatson break; 1023100979Srwatson case MAC_CHECK_VNODE_SETOWNER: 1024100979Srwatson mpc->mpc_ops->mpo_check_vnode_setowner = 1025100979Srwatson mpe->mpe_function; 1026100979Srwatson break; 1027100979Srwatson case MAC_CHECK_VNODE_SETUTIMES: 1028100979Srwatson mpc->mpc_ops->mpo_check_vnode_setutimes = 1029100979Srwatson mpe->mpe_function; 1030100979Srwatson break; 1031100979Srwatson case MAC_CHECK_VNODE_STAT: 1032100979Srwatson mpc->mpc_ops->mpo_check_vnode_stat = 1033100979Srwatson mpe->mpe_function; 1034100979Srwatson break; 1035102112Srwatson case MAC_CHECK_VNODE_WRITE: 1036102112Srwatson mpc->mpc_ops->mpo_check_vnode_write = 1037102112Srwatson mpe->mpe_function; 1038102112Srwatson break; 1039100979Srwatson/* 1040100979Srwatson default: 1041100979Srwatson printf("MAC policy `%s': unknown operation %d\n", 1042100979Srwatson mpc->mpc_name, mpe->mpe_constant); 1043100979Srwatson return (EINVAL); 1044100979Srwatson*/ 1045100979Srwatson } 1046100979Srwatson } 1047100979Srwatson MAC_POLICY_LIST_LOCK(); 1048100979Srwatson if (mac_policy_list_busy > 0) { 1049100979Srwatson MAC_POLICY_LIST_UNLOCK(); 1050100979Srwatson FREE(mpc->mpc_ops, M_MACOPVEC); 1051100979Srwatson mpc->mpc_ops = NULL; 1052100979Srwatson return (EBUSY); 1053100979Srwatson } 1054100979Srwatson LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 1055100979Srwatson if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 1056100979Srwatson MAC_POLICY_LIST_UNLOCK(); 1057100979Srwatson FREE(mpc->mpc_ops, M_MACOPVEC); 1058100979Srwatson mpc->mpc_ops = NULL; 1059100979Srwatson return (EEXIST); 1060100979Srwatson } 1061100979Srwatson } 1062100979Srwatson if (mpc->mpc_field_off != NULL) { 1063100979Srwatson slot = ffs(mac_policy_offsets_free); 1064100979Srwatson if (slot == 0) { 1065100979Srwatson MAC_POLICY_LIST_UNLOCK(); 1066100979Srwatson FREE(mpc->mpc_ops, M_MACOPVEC); 1067100979Srwatson mpc->mpc_ops = NULL; 1068100979Srwatson return (ENOMEM); 1069100979Srwatson } 1070100979Srwatson slot--; 1071100979Srwatson mac_policy_offsets_free &= ~(1 << slot); 1072100979Srwatson *mpc->mpc_field_off = slot; 1073100979Srwatson } 1074100979Srwatson mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; 1075100979Srwatson LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); 1076100979Srwatson 1077100979Srwatson /* Per-policy initialization. */ 1078100979Srwatson if (mpc->mpc_ops->mpo_init != NULL) 1079100979Srwatson (*(mpc->mpc_ops->mpo_init))(mpc); 1080100979Srwatson MAC_POLICY_LIST_UNLOCK(); 1081100979Srwatson 1082100979Srwatson printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, 1083100979Srwatson mpc->mpc_name); 1084100979Srwatson 1085100979Srwatson return (0); 1086100979Srwatson} 1087100979Srwatson 1088100979Srwatsonstatic int 1089100979Srwatsonmac_policy_unregister(struct mac_policy_conf *mpc) 1090100979Srwatson{ 1091100979Srwatson 1092104520Srwatson /* 1093104520Srwatson * If we fail the load, we may get a request to unload. Check 1094104520Srwatson * to see if we did the run-time registration, and if not, 1095104520Srwatson * silently succeed. 1096104520Srwatson */ 1097104520Srwatson MAC_POLICY_LIST_LOCK(); 1098104520Srwatson if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) { 1099104520Srwatson MAC_POLICY_LIST_UNLOCK(); 1100104520Srwatson return (0); 1101104520Srwatson } 1102100979Srwatson#if 0 1103100979Srwatson /* 1104100979Srwatson * Don't allow unloading modules with private data. 1105100979Srwatson */ 1106104520Srwatson if (mpc->mpc_field_off != NULL) { 1107104520Srwatson MAC_POLICY_LIST_UNLOCK(); 1108100979Srwatson return (EBUSY); 1109104520Srwatson } 1110100979Srwatson#endif 1111104520Srwatson /* 1112104520Srwatson * Only allow the unload to proceed if the module is unloadable 1113104520Srwatson * by its own definition. 1114104520Srwatson */ 1115104520Srwatson if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) { 1116104520Srwatson MAC_POLICY_LIST_UNLOCK(); 1117100979Srwatson return (EBUSY); 1118104520Srwatson } 1119104520Srwatson /* 1120104520Srwatson * Right now, we EBUSY if the list is in use. In the future, 1121104520Srwatson * for reliability reasons, we might want to sleep and wakeup 1122104520Srwatson * later to try again. 1123104520Srwatson */ 1124100979Srwatson if (mac_policy_list_busy > 0) { 1125100979Srwatson MAC_POLICY_LIST_UNLOCK(); 1126100979Srwatson return (EBUSY); 1127100979Srwatson } 1128100979Srwatson if (mpc->mpc_ops->mpo_destroy != NULL) 1129100979Srwatson (*(mpc->mpc_ops->mpo_destroy))(mpc); 1130100979Srwatson 1131100979Srwatson LIST_REMOVE(mpc, mpc_list); 1132100979Srwatson MAC_POLICY_LIST_UNLOCK(); 1133100979Srwatson 1134100979Srwatson FREE(mpc->mpc_ops, M_MACOPVEC); 1135100979Srwatson mpc->mpc_ops = NULL; 1136105474Srwatson mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED; 1137100979Srwatson 1138100979Srwatson printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, 1139100979Srwatson mpc->mpc_name); 1140100979Srwatson 1141100979Srwatson return (0); 1142100979Srwatson} 1143100979Srwatson 1144100979Srwatson/* 1145100979Srwatson * Define an error value precedence, and given two arguments, selects the 1146100979Srwatson * value with the higher precedence. 1147100979Srwatson */ 1148100979Srwatsonstatic int 1149100979Srwatsonerror_select(int error1, int error2) 1150100979Srwatson{ 1151100979Srwatson 1152100979Srwatson /* Certain decision-making errors take top priority. */ 1153100979Srwatson if (error1 == EDEADLK || error2 == EDEADLK) 1154100979Srwatson return (EDEADLK); 1155100979Srwatson 1156100979Srwatson /* Invalid arguments should be reported where possible. */ 1157100979Srwatson if (error1 == EINVAL || error2 == EINVAL) 1158100979Srwatson return (EINVAL); 1159100979Srwatson 1160100979Srwatson /* Precedence goes to "visibility", with both process and file. */ 1161100979Srwatson if (error1 == ESRCH || error2 == ESRCH) 1162100979Srwatson return (ESRCH); 1163100979Srwatson 1164100979Srwatson if (error1 == ENOENT || error2 == ENOENT) 1165100979Srwatson return (ENOENT); 1166100979Srwatson 1167100979Srwatson /* Precedence goes to DAC/MAC protections. */ 1168100979Srwatson if (error1 == EACCES || error2 == EACCES) 1169100979Srwatson return (EACCES); 1170100979Srwatson 1171100979Srwatson /* Precedence goes to privilege. */ 1172100979Srwatson if (error1 == EPERM || error2 == EPERM) 1173100979Srwatson return (EPERM); 1174100979Srwatson 1175100979Srwatson /* Precedence goes to error over success; otherwise, arbitrary. */ 1176100979Srwatson if (error1 != 0) 1177100979Srwatson return (error1); 1178100979Srwatson return (error2); 1179100979Srwatson} 1180100979Srwatson 1181104521Srwatsonstatic void 1182104521Srwatsonmac_init_label(struct label *label) 1183104521Srwatson{ 1184104521Srwatson 1185104521Srwatson bzero(label, sizeof(*label)); 1186104521Srwatson label->l_flags = MAC_FLAG_INITIALIZED; 1187104521Srwatson} 1188104521Srwatson 1189104521Srwatsonstatic void 1190104521Srwatsonmac_destroy_label(struct label *label) 1191104521Srwatson{ 1192104521Srwatson 1193104521Srwatson KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 1194104521Srwatson ("destroying uninitialized label")); 1195104521Srwatson 1196104521Srwatson bzero(label, sizeof(*label)); 1197104521Srwatson /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 1198104521Srwatson} 1199104521Srwatson 1200100979Srwatsonvoid 1201104527Srwatsonmac_init_bpfdesc(struct bpf_d *bpf_d) 1202104521Srwatson{ 1203104521Srwatson 1204104527Srwatson mac_init_label(&bpf_d->bd_label); 1205104527Srwatson MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label); 1206104521Srwatson#ifdef MAC_DEBUG 1207104527Srwatson atomic_add_int(&nmacbpfdescs, 1); 1208104521Srwatson#endif 1209104521Srwatson} 1210104521Srwatson 1211105694Srwatsonstatic void 1212105694Srwatsonmac_init_cred_label(struct label *label) 1213104521Srwatson{ 1214104521Srwatson 1215105694Srwatson mac_init_label(label); 1216105694Srwatson MAC_PERFORM(init_cred_label, label); 1217104521Srwatson#ifdef MAC_DEBUG 1218104521Srwatson atomic_add_int(&nmaccreds, 1); 1219104521Srwatson#endif 1220104521Srwatson} 1221104521Srwatson 1222104521Srwatsonvoid 1223105694Srwatsonmac_init_cred(struct ucred *cred) 1224105694Srwatson{ 1225105694Srwatson 1226105694Srwatson mac_init_cred_label(&cred->cr_label); 1227105694Srwatson} 1228105694Srwatson 1229105694Srwatsonvoid 1230104527Srwatsonmac_init_devfsdirent(struct devfs_dirent *de) 1231104521Srwatson{ 1232104521Srwatson 1233104527Srwatson mac_init_label(&de->de_label); 1234104527Srwatson MAC_PERFORM(init_devfsdirent_label, &de->de_label); 1235104521Srwatson#ifdef MAC_DEBUG 1236104527Srwatson atomic_add_int(&nmacdevfsdirents, 1); 1237104521Srwatson#endif 1238104521Srwatson} 1239104521Srwatson 1240105694Srwatsonstatic void 1241105694Srwatsonmac_init_ifnet_label(struct label *label) 1242104521Srwatson{ 1243104521Srwatson 1244105694Srwatson mac_init_label(label); 1245105694Srwatson MAC_PERFORM(init_ifnet_label, label); 1246104521Srwatson#ifdef MAC_DEBUG 1247104521Srwatson atomic_add_int(&nmacifnets, 1); 1248104521Srwatson#endif 1249104521Srwatson} 1250104521Srwatson 1251104521Srwatsonvoid 1252105694Srwatsonmac_init_ifnet(struct ifnet *ifp) 1253105694Srwatson{ 1254105694Srwatson 1255105694Srwatson mac_init_ifnet_label(&ifp->if_label); 1256105694Srwatson} 1257105694Srwatson 1258105694Srwatsonvoid 1259104527Srwatsonmac_init_ipq(struct ipq *ipq) 1260104521Srwatson{ 1261104521Srwatson 1262104527Srwatson mac_init_label(&ipq->ipq_label); 1263104527Srwatson MAC_PERFORM(init_ipq_label, &ipq->ipq_label); 1264104521Srwatson#ifdef MAC_DEBUG 1265104527Srwatson atomic_add_int(&nmacipqs, 1); 1266104521Srwatson#endif 1267104521Srwatson} 1268104521Srwatson 1269104527Srwatsonint 1270104527Srwatsonmac_init_mbuf(struct mbuf *m, int flag) 1271104527Srwatson{ 1272104528Srwatson int error; 1273104528Srwatson 1274104527Srwatson KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf")); 1275104527Srwatson 1276104527Srwatson mac_init_label(&m->m_pkthdr.label); 1277104527Srwatson 1278104528Srwatson MAC_CHECK(init_mbuf_label, &m->m_pkthdr.label, flag); 1279104528Srwatson if (error) { 1280104528Srwatson MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 1281104528Srwatson mac_destroy_label(&m->m_pkthdr.label); 1282104528Srwatson } 1283104528Srwatson 1284104527Srwatson#ifdef MAC_DEBUG 1285104528Srwatson if (error == 0) 1286104528Srwatson atomic_add_int(&nmacmbufs, 1); 1287104527Srwatson#endif 1288104528Srwatson return (error); 1289104527Srwatson} 1290104527Srwatson 1291104521Srwatsonvoid 1292104527Srwatsonmac_init_mount(struct mount *mp) 1293104521Srwatson{ 1294104521Srwatson 1295104527Srwatson mac_init_label(&mp->mnt_mntlabel); 1296104527Srwatson mac_init_label(&mp->mnt_fslabel); 1297104527Srwatson MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel); 1298104527Srwatson MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel); 1299104521Srwatson#ifdef MAC_DEBUG 1300104527Srwatson atomic_add_int(&nmacmounts, 1); 1301104521Srwatson#endif 1302104521Srwatson} 1303104521Srwatson 1304105694Srwatsonstatic void 1305105694Srwatsonmac_init_pipe_label(struct label *label) 1306105694Srwatson{ 1307105694Srwatson 1308105694Srwatson mac_init_label(label); 1309105694Srwatson MAC_PERFORM(init_pipe_label, label); 1310105694Srwatson#ifdef MAC_DEBUG 1311105694Srwatson atomic_add_int(&nmacpipes, 1); 1312105694Srwatson#endif 1313105694Srwatson} 1314105694Srwatson 1315104521Srwatsonvoid 1316104527Srwatsonmac_init_pipe(struct pipe *pipe) 1317104521Srwatson{ 1318104527Srwatson struct label *label; 1319104521Srwatson 1320104527Srwatson label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 1321104527Srwatson pipe->pipe_label = label; 1322104527Srwatson pipe->pipe_peer->pipe_label = label; 1323105694Srwatson mac_init_pipe_label(label); 1324104521Srwatson} 1325104521Srwatson 1326104541Srwatsonstatic int 1327104541Srwatsonmac_init_socket_label(struct label *label, int flag) 1328104521Srwatson{ 1329104541Srwatson int error; 1330104521Srwatson 1331104541Srwatson mac_init_label(label); 1332104541Srwatson 1333104541Srwatson MAC_CHECK(init_socket_label, label, flag); 1334104541Srwatson if (error) { 1335104541Srwatson MAC_PERFORM(destroy_socket_label, label); 1336104541Srwatson mac_destroy_label(label); 1337104541Srwatson } 1338104541Srwatson 1339104521Srwatson#ifdef MAC_DEBUG 1340104541Srwatson if (error == 0) 1341104541Srwatson atomic_add_int(&nmacsockets, 1); 1342104521Srwatson#endif 1343104541Srwatson 1344104541Srwatson return (error); 1345104521Srwatson} 1346104521Srwatson 1347104541Srwatsonstatic int 1348104541Srwatsonmac_init_socket_peer_label(struct label *label, int flag) 1349104541Srwatson{ 1350104541Srwatson int error; 1351104541Srwatson 1352104541Srwatson mac_init_label(label); 1353104541Srwatson 1354104541Srwatson MAC_CHECK(init_socket_peer_label, label, flag); 1355104541Srwatson if (error) { 1356104541Srwatson MAC_PERFORM(destroy_socket_label, label); 1357104541Srwatson mac_destroy_label(label); 1358104541Srwatson } 1359104541Srwatson 1360104541Srwatson return (error); 1361104541Srwatson} 1362104541Srwatson 1363104541Srwatsonint 1364104541Srwatsonmac_init_socket(struct socket *socket, int flag) 1365104541Srwatson{ 1366104541Srwatson int error; 1367104541Srwatson 1368104541Srwatson error = mac_init_socket_label(&socket->so_label, flag); 1369104541Srwatson if (error) 1370104541Srwatson return (error); 1371104541Srwatson 1372104541Srwatson error = mac_init_socket_peer_label(&socket->so_peerlabel, flag); 1373104541Srwatson if (error) 1374104541Srwatson mac_destroy_socket_label(&socket->so_label); 1375104541Srwatson 1376104541Srwatson return (error); 1377104541Srwatson} 1378104541Srwatson 1379105988Srwatsonvoid 1380105694Srwatsonmac_init_vnode_label(struct label *label) 1381104521Srwatson{ 1382104521Srwatson 1383104527Srwatson mac_init_label(label); 1384105694Srwatson MAC_PERFORM(init_vnode_label, label); 1385104521Srwatson#ifdef MAC_DEBUG 1386105694Srwatson atomic_add_int(&nmacvnodes, 1); 1387104521Srwatson#endif 1388104521Srwatson} 1389104521Srwatson 1390104521Srwatsonvoid 1391104527Srwatsonmac_init_vnode(struct vnode *vp) 1392104521Srwatson{ 1393104521Srwatson 1394105694Srwatson mac_init_vnode_label(&vp->v_label); 1395104521Srwatson} 1396104521Srwatson 1397104521Srwatsonvoid 1398104527Srwatsonmac_destroy_bpfdesc(struct bpf_d *bpf_d) 1399104521Srwatson{ 1400104521Srwatson 1401104527Srwatson MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label); 1402104527Srwatson mac_destroy_label(&bpf_d->bd_label); 1403104521Srwatson#ifdef MAC_DEBUG 1404104527Srwatson atomic_subtract_int(&nmacbpfdescs, 1); 1405104521Srwatson#endif 1406104521Srwatson} 1407104521Srwatson 1408105694Srwatsonstatic void 1409105694Srwatsonmac_destroy_cred_label(struct label *label) 1410104521Srwatson{ 1411104521Srwatson 1412105694Srwatson MAC_PERFORM(destroy_cred_label, label); 1413105694Srwatson mac_destroy_label(label); 1414104521Srwatson#ifdef MAC_DEBUG 1415104527Srwatson atomic_subtract_int(&nmaccreds, 1); 1416104521Srwatson#endif 1417104521Srwatson} 1418104521Srwatson 1419104521Srwatsonvoid 1420105694Srwatsonmac_destroy_cred(struct ucred *cred) 1421105694Srwatson{ 1422105694Srwatson 1423105694Srwatson mac_destroy_cred_label(&cred->cr_label); 1424105694Srwatson} 1425105694Srwatson 1426105694Srwatsonvoid 1427104527Srwatsonmac_destroy_devfsdirent(struct devfs_dirent *de) 1428104521Srwatson{ 1429104521Srwatson 1430104527Srwatson MAC_PERFORM(destroy_devfsdirent_label, &de->de_label); 1431104527Srwatson mac_destroy_label(&de->de_label); 1432104521Srwatson#ifdef MAC_DEBUG 1433104527Srwatson atomic_subtract_int(&nmacdevfsdirents, 1); 1434104521Srwatson#endif 1435104521Srwatson} 1436104521Srwatson 1437105694Srwatsonstatic void 1438105694Srwatsonmac_destroy_ifnet_label(struct label *label) 1439104521Srwatson{ 1440104521Srwatson 1441105694Srwatson MAC_PERFORM(destroy_ifnet_label, label); 1442105694Srwatson mac_destroy_label(label); 1443104521Srwatson#ifdef MAC_DEBUG 1444104527Srwatson atomic_subtract_int(&nmacifnets, 1); 1445104521Srwatson#endif 1446104521Srwatson} 1447104521Srwatson 1448104521Srwatsonvoid 1449105694Srwatsonmac_destroy_ifnet(struct ifnet *ifp) 1450105694Srwatson{ 1451105694Srwatson 1452105694Srwatson mac_destroy_ifnet_label(&ifp->if_label); 1453105694Srwatson} 1454105694Srwatson 1455105694Srwatsonvoid 1456104527Srwatsonmac_destroy_ipq(struct ipq *ipq) 1457104521Srwatson{ 1458104521Srwatson 1459104527Srwatson MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 1460104527Srwatson mac_destroy_label(&ipq->ipq_label); 1461104521Srwatson#ifdef MAC_DEBUG 1462104527Srwatson atomic_subtract_int(&nmacipqs, 1); 1463104521Srwatson#endif 1464104521Srwatson} 1465104521Srwatson 1466104527Srwatsonvoid 1467104527Srwatsonmac_destroy_mbuf(struct mbuf *m) 1468104521Srwatson{ 1469104521Srwatson 1470104527Srwatson MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 1471104527Srwatson mac_destroy_label(&m->m_pkthdr.label); 1472104521Srwatson#ifdef MAC_DEBUG 1473104527Srwatson atomic_subtract_int(&nmacmbufs, 1); 1474104521Srwatson#endif 1475104521Srwatson} 1476104521Srwatson 1477104527Srwatsonvoid 1478104527Srwatsonmac_destroy_mount(struct mount *mp) 1479104521Srwatson{ 1480104521Srwatson 1481104527Srwatson MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel); 1482104527Srwatson MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel); 1483104527Srwatson mac_destroy_label(&mp->mnt_fslabel); 1484104527Srwatson mac_destroy_label(&mp->mnt_mntlabel); 1485104521Srwatson#ifdef MAC_DEBUG 1486104527Srwatson atomic_subtract_int(&nmacmounts, 1); 1487104521Srwatson#endif 1488104521Srwatson} 1489104521Srwatson 1490105694Srwatsonstatic void 1491105694Srwatsonmac_destroy_pipe_label(struct label *label) 1492104521Srwatson{ 1493104521Srwatson 1494105694Srwatson MAC_PERFORM(destroy_pipe_label, label); 1495105694Srwatson mac_destroy_label(label); 1496104521Srwatson#ifdef MAC_DEBUG 1497104527Srwatson atomic_subtract_int(&nmacpipes, 1); 1498104521Srwatson#endif 1499104521Srwatson} 1500104521Srwatson 1501105694Srwatsonvoid 1502105694Srwatsonmac_destroy_pipe(struct pipe *pipe) 1503105694Srwatson{ 1504105694Srwatson 1505105694Srwatson mac_destroy_pipe_label(pipe->pipe_label); 1506105694Srwatson free(pipe->pipe_label, M_MACPIPELABEL); 1507105694Srwatson} 1508105694Srwatson 1509104541Srwatsonstatic void 1510104541Srwatsonmac_destroy_socket_label(struct label *label) 1511104521Srwatson{ 1512104521Srwatson 1513104541Srwatson MAC_PERFORM(destroy_socket_label, label); 1514104541Srwatson mac_destroy_label(label); 1515104521Srwatson#ifdef MAC_DEBUG 1516104527Srwatson atomic_subtract_int(&nmacsockets, 1); 1517104521Srwatson#endif 1518104521Srwatson} 1519104521Srwatson 1520104527Srwatsonstatic void 1521104541Srwatsonmac_destroy_socket_peer_label(struct label *label) 1522104541Srwatson{ 1523104541Srwatson 1524104541Srwatson MAC_PERFORM(destroy_socket_peer_label, label); 1525104541Srwatson mac_destroy_label(label); 1526104541Srwatson} 1527104541Srwatson 1528104541Srwatsonvoid 1529104541Srwatsonmac_destroy_socket(struct socket *socket) 1530104541Srwatson{ 1531104541Srwatson 1532104541Srwatson mac_destroy_socket_label(&socket->so_label); 1533104541Srwatson mac_destroy_socket_peer_label(&socket->so_peerlabel); 1534104541Srwatson} 1535104541Srwatson 1536105988Srwatsonvoid 1537105694Srwatsonmac_destroy_vnode_label(struct label *label) 1538104521Srwatson{ 1539104521Srwatson 1540105694Srwatson MAC_PERFORM(destroy_vnode_label, label); 1541104527Srwatson mac_destroy_label(label); 1542104521Srwatson#ifdef MAC_DEBUG 1543105694Srwatson atomic_subtract_int(&nmacvnodes, 1); 1544104521Srwatson#endif 1545104521Srwatson} 1546104521Srwatson 1547104521Srwatsonvoid 1548104527Srwatsonmac_destroy_vnode(struct vnode *vp) 1549104521Srwatson{ 1550104521Srwatson 1551105694Srwatson mac_destroy_vnode_label(&vp->v_label); 1552104521Srwatson} 1553104521Srwatson 1554105694Srwatsonstatic void 1555105694Srwatsonmac_copy_pipe_label(struct label *src, struct label *dest) 1556105694Srwatson{ 1557105694Srwatson 1558105694Srwatson MAC_PERFORM(copy_pipe_label, src, dest); 1559105694Srwatson} 1560105694Srwatson 1561105988Srwatsonvoid 1562105694Srwatsonmac_copy_vnode_label(struct label *src, struct label *dest) 1563105694Srwatson{ 1564105694Srwatson 1565105694Srwatson MAC_PERFORM(copy_vnode_label, src, dest); 1566105694Srwatson} 1567105694Srwatson 1568104522Srwatsonstatic int 1569105694Srwatsonmac_check_structmac_consistent(struct mac *mac) 1570104522Srwatson{ 1571105694Srwatson 1572105694Srwatson if (mac->m_buflen > MAC_MAX_LABEL_BUF_LEN) 1573105694Srwatson return (EINVAL); 1574105694Srwatson 1575105694Srwatson return (0); 1576105694Srwatson} 1577105694Srwatson 1578105694Srwatsonstatic int 1579105694Srwatsonmac_externalize_cred_label(struct label *label, char *elements, 1580105694Srwatson char *outbuf, size_t outbuflen, int flags) 1581105694Srwatson{ 1582104522Srwatson int error; 1583104522Srwatson 1584105694Srwatson MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen); 1585104522Srwatson 1586104522Srwatson return (error); 1587104522Srwatson} 1588104522Srwatson 1589104522Srwatsonstatic int 1590105694Srwatsonmac_externalize_ifnet_label(struct label *label, char *elements, 1591105694Srwatson char *outbuf, size_t outbuflen, int flags) 1592104522Srwatson{ 1593104522Srwatson int error; 1594104522Srwatson 1595105694Srwatson MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen); 1596104522Srwatson 1597104522Srwatson return (error); 1598104522Srwatson} 1599104522Srwatson 1600105694Srwatsonstatic int 1601105694Srwatsonmac_externalize_pipe_label(struct label *label, char *elements, 1602105694Srwatson char *outbuf, size_t outbuflen, int flags) 1603105694Srwatson{ 1604105694Srwatson int error; 1605105694Srwatson 1606105694Srwatson MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen); 1607105694Srwatson 1608105694Srwatson return (error); 1609105694Srwatson} 1610105694Srwatson 1611105694Srwatsonstatic int 1612105694Srwatsonmac_externalize_socket_label(struct label *label, char *elements, 1613105694Srwatson char *outbuf, size_t outbuflen, int flags) 1614105694Srwatson{ 1615105694Srwatson int error; 1616105694Srwatson 1617105694Srwatson MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen); 1618105694Srwatson 1619105694Srwatson return (error); 1620105694Srwatson} 1621105694Srwatson 1622105694Srwatsonstatic int 1623105694Srwatsonmac_externalize_socket_peer_label(struct label *label, char *elements, 1624105694Srwatson char *outbuf, size_t outbuflen, int flags) 1625105694Srwatson{ 1626105694Srwatson int error; 1627105694Srwatson 1628105694Srwatson MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen); 1629105694Srwatson 1630105694Srwatson return (error); 1631105694Srwatson} 1632105694Srwatson 1633105694Srwatsonstatic int 1634105694Srwatsonmac_externalize_vnode_label(struct label *label, char *elements, 1635105694Srwatson char *outbuf, size_t outbuflen, int flags) 1636105694Srwatson{ 1637105694Srwatson int error; 1638105694Srwatson 1639105694Srwatson MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen); 1640105694Srwatson 1641105694Srwatson return (error); 1642105694Srwatson} 1643105694Srwatson 1644105694Srwatsonstatic int 1645105694Srwatsonmac_internalize_cred_label(struct label *label, char *string) 1646105694Srwatson{ 1647105694Srwatson int error; 1648105694Srwatson 1649105694Srwatson MAC_INTERNALIZE(cred_label, label, string); 1650105694Srwatson 1651105694Srwatson return (error); 1652105694Srwatson} 1653105694Srwatson 1654105694Srwatsonstatic int 1655105694Srwatsonmac_internalize_ifnet_label(struct label *label, char *string) 1656105694Srwatson{ 1657105694Srwatson int error; 1658105694Srwatson 1659105694Srwatson MAC_INTERNALIZE(ifnet_label, label, string); 1660105694Srwatson 1661105694Srwatson return (error); 1662105694Srwatson} 1663105694Srwatson 1664105694Srwatsonstatic int 1665105694Srwatsonmac_internalize_pipe_label(struct label *label, char *string) 1666105694Srwatson{ 1667105694Srwatson int error; 1668105694Srwatson 1669105694Srwatson MAC_INTERNALIZE(pipe_label, label, string); 1670105694Srwatson 1671105694Srwatson return (error); 1672105694Srwatson} 1673105694Srwatson 1674105694Srwatsonstatic int 1675105694Srwatsonmac_internalize_socket_label(struct label *label, char *string) 1676105694Srwatson{ 1677105694Srwatson int error; 1678105694Srwatson 1679105694Srwatson MAC_INTERNALIZE(socket_label, label, string); 1680105694Srwatson 1681105694Srwatson return (error); 1682105694Srwatson} 1683105694Srwatson 1684105694Srwatsonstatic int 1685105694Srwatsonmac_internalize_vnode_label(struct label *label, char *string) 1686105694Srwatson{ 1687105694Srwatson int error; 1688105694Srwatson 1689105694Srwatson MAC_INTERNALIZE(vnode_label, label, string); 1690105694Srwatson 1691105694Srwatson return (error); 1692105694Srwatson} 1693105694Srwatson 1694104522Srwatson/* 1695104522Srwatson * Initialize MAC label for the first kernel process, from which other 1696104522Srwatson * kernel processes and threads are spawned. 1697104522Srwatson */ 1698104521Srwatsonvoid 1699104522Srwatsonmac_create_proc0(struct ucred *cred) 1700104522Srwatson{ 1701104522Srwatson 1702104522Srwatson MAC_PERFORM(create_proc0, cred); 1703104522Srwatson} 1704104522Srwatson 1705104522Srwatson/* 1706104522Srwatson * Initialize MAC label for the first userland process, from which other 1707104522Srwatson * userland processes and threads are spawned. 1708104522Srwatson */ 1709104522Srwatsonvoid 1710104522Srwatsonmac_create_proc1(struct ucred *cred) 1711104522Srwatson{ 1712104522Srwatson 1713104522Srwatson MAC_PERFORM(create_proc1, cred); 1714104522Srwatson} 1715104522Srwatson 1716104522Srwatsonvoid 1717104522Srwatsonmac_thread_userret(struct thread *td) 1718104522Srwatson{ 1719104522Srwatson 1720104522Srwatson MAC_PERFORM(thread_userret, td); 1721104522Srwatson} 1722104522Srwatson 1723104522Srwatson/* 1724104522Srwatson * When a new process is created, its label must be initialized. Generally, 1725104522Srwatson * this involves inheritence from the parent process, modulo possible 1726104522Srwatson * deltas. This function allows that processing to take place. 1727104522Srwatson */ 1728104522Srwatsonvoid 1729104522Srwatsonmac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 1730104522Srwatson{ 1731104522Srwatson 1732104522Srwatson MAC_PERFORM(create_cred, parent_cred, child_cred); 1733104522Srwatson} 1734104522Srwatson 1735104522Srwatsonvoid 1736100979Srwatsonmac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp) 1737100979Srwatson{ 1738100979Srwatson 1739100979Srwatson MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label); 1740100979Srwatson} 1741100979Srwatson 1742100979Srwatsonvoid 1743105988Srwatsonmac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, 1744105988Srwatson struct vnode *vp) 1745100979Srwatson{ 1746100979Srwatson 1747105988Srwatson MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de, 1748105988Srwatson &de->de_label, vp, &vp->v_label); 1749100979Srwatson} 1750100979Srwatson 1751105988Srwatsonint 1752105988Srwatsonmac_associate_vnode_extattr(struct mount *mp, struct vnode *vp) 1753100979Srwatson{ 1754100979Srwatson int error; 1755100979Srwatson 1756105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr"); 1757100979Srwatson 1758105988Srwatson MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp, 1759105988Srwatson &vp->v_label); 1760100979Srwatson 1761100979Srwatson return (error); 1762100979Srwatson} 1763100979Srwatson 1764100979Srwatsonvoid 1765105988Srwatsonmac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp) 1766100979Srwatson{ 1767100979Srwatson 1768105988Srwatson MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp, 1769105988Srwatson &vp->v_label); 1770100979Srwatson} 1771100979Srwatson 1772100979Srwatsonint 1773105988Srwatsonmac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1774105988Srwatson struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 1775100979Srwatson{ 1776105988Srwatson int error; 1777100979Srwatson 1778105988Srwatson ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr"); 1779105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr"); 1780100979Srwatson 1781105988Srwatson error = VOP_OPENEXTATTR(vp, cred, curthread); 1782105988Srwatson if (error == EOPNOTSUPP) { 1783105988Srwatson /* XXX: Optionally abort if transactions not supported. */ 1784105988Srwatson if (ea_warn_once == 0) { 1785105988Srwatson printf("Warning: transactions not supported " 1786105988Srwatson "in EA write.\n"); 1787105988Srwatson ea_warn_once = 1; 1788105988Srwatson } 1789105988Srwatson } else if (error) 1790100979Srwatson return (error); 1791100979Srwatson 1792105988Srwatson MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel, 1793105988Srwatson dvp, &dvp->v_label, vp, &vp->v_label, cnp); 1794100979Srwatson 1795105988Srwatson if (error) { 1796105988Srwatson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1797100979Srwatson return (error); 1798100979Srwatson } 1799100979Srwatson 1800105988Srwatson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1801100979Srwatson 1802105988Srwatson if (error == EOPNOTSUPP) 1803105988Srwatson error = 0; /* XXX */ 1804100979Srwatson 1805100979Srwatson return (error); 1806100979Srwatson} 1807100979Srwatson 1808100979Srwatsonstatic int 1809105988Srwatsonmac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1810105988Srwatson struct label *intlabel) 1811100979Srwatson{ 1812100979Srwatson int error; 1813100979Srwatson 1814105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr"); 1815100979Srwatson 1816105988Srwatson error = VOP_OPENEXTATTR(vp, cred, curthread); 1817105988Srwatson if (error == EOPNOTSUPP) { 1818105988Srwatson /* XXX: Optionally abort if transactions not supported. */ 1819105988Srwatson if (ea_warn_once == 0) { 1820105988Srwatson printf("Warning: transactions not supported " 1821105988Srwatson "in EA write.\n"); 1822105988Srwatson ea_warn_once = 1; 1823105988Srwatson } 1824105988Srwatson } else if (error) 1825105988Srwatson return (error); 1826100979Srwatson 1827105988Srwatson MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel); 1828100979Srwatson 1829105988Srwatson if (error) { 1830105988Srwatson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1831100979Srwatson return (error); 1832100979Srwatson } 1833100979Srwatson 1834105988Srwatson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1835100979Srwatson 1836105988Srwatson if (error == EOPNOTSUPP) 1837105988Srwatson error = 0; /* XXX */ 1838100979Srwatson 1839105988Srwatson return (error); 1840100979Srwatson} 1841100979Srwatson 1842100979Srwatsonvoid 1843100979Srwatsonmac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp) 1844100979Srwatson{ 1845100979Srwatson 1846100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1847100979Srwatson 1848100979Srwatson MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label); 1849100979Srwatson} 1850100979Srwatson 1851100979Srwatsonint 1852100979Srwatsonmac_execve_will_transition(struct ucred *old, struct vnode *vp) 1853100979Srwatson{ 1854105988Srwatson int result; 1855100979Srwatson 1856100979Srwatson result = 0; 1857100979Srwatson MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label); 1858100979Srwatson 1859100979Srwatson return (result); 1860100979Srwatson} 1861100979Srwatson 1862100979Srwatsonint 1863100979Srwatsonmac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags) 1864100979Srwatson{ 1865100979Srwatson int error; 1866100979Srwatson 1867100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1868100979Srwatson 1869100979Srwatson if (!mac_enforce_fs) 1870100979Srwatson return (0); 1871100979Srwatson 1872100979Srwatson MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags); 1873100979Srwatson return (error); 1874100979Srwatson} 1875100979Srwatson 1876100979Srwatsonint 1877100979Srwatsonmac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 1878100979Srwatson{ 1879100979Srwatson int error; 1880100979Srwatson 1881100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 1882100979Srwatson 1883100979Srwatson if (!mac_enforce_fs) 1884100979Srwatson return (0); 1885100979Srwatson 1886100979Srwatson MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 1887100979Srwatson return (error); 1888100979Srwatson} 1889100979Srwatson 1890100979Srwatsonint 1891100979Srwatsonmac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 1892100979Srwatson{ 1893100979Srwatson int error; 1894100979Srwatson 1895100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 1896100979Srwatson 1897100979Srwatson if (!mac_enforce_fs) 1898100979Srwatson return (0); 1899100979Srwatson 1900100979Srwatson MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1901100979Srwatson return (error); 1902100979Srwatson} 1903100979Srwatson 1904100979Srwatsonint 1905100979Srwatsonmac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1906100979Srwatson struct componentname *cnp, struct vattr *vap) 1907100979Srwatson{ 1908100979Srwatson int error; 1909100979Srwatson 1910100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1911100979Srwatson 1912100979Srwatson if (!mac_enforce_fs) 1913100979Srwatson return (0); 1914100979Srwatson 1915100979Srwatson MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 1916100979Srwatson return (error); 1917100979Srwatson} 1918100979Srwatson 1919100979Srwatsonint 1920100979Srwatsonmac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 1921100979Srwatson struct componentname *cnp) 1922100979Srwatson{ 1923100979Srwatson int error; 1924100979Srwatson 1925100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 1926100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 1927100979Srwatson 1928100979Srwatson if (!mac_enforce_fs) 1929100979Srwatson return (0); 1930100979Srwatson 1931100979Srwatson MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1932100979Srwatson &vp->v_label, cnp); 1933100979Srwatson return (error); 1934100979Srwatson} 1935100979Srwatson 1936100979Srwatsonint 1937100979Srwatsonmac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1938100979Srwatson acl_type_t type) 1939100979Srwatson{ 1940100979Srwatson int error; 1941100979Srwatson 1942100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1943100979Srwatson 1944100979Srwatson if (!mac_enforce_fs) 1945100979Srwatson return (0); 1946100979Srwatson 1947100979Srwatson MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1948100979Srwatson return (error); 1949100979Srwatson} 1950100979Srwatson 1951100979Srwatsonint 1952100979Srwatsonmac_check_vnode_exec(struct ucred *cred, struct vnode *vp) 1953100979Srwatson{ 1954100979Srwatson int error; 1955100979Srwatson 1956102102Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1957102102Srwatson 1958100979Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1959100979Srwatson return (0); 1960100979Srwatson 1961100979Srwatson MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label); 1962100979Srwatson 1963100979Srwatson return (error); 1964100979Srwatson} 1965100979Srwatson 1966100979Srwatsonint 1967100979Srwatsonmac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1968100979Srwatson{ 1969100979Srwatson int error; 1970100979Srwatson 1971100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1972100979Srwatson 1973100979Srwatson if (!mac_enforce_fs) 1974100979Srwatson return (0); 1975100979Srwatson 1976100979Srwatson MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1977100979Srwatson return (error); 1978100979Srwatson} 1979100979Srwatson 1980100979Srwatsonint 1981100979Srwatsonmac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1982100979Srwatson int attrnamespace, const char *name, struct uio *uio) 1983100979Srwatson{ 1984100979Srwatson int error; 1985100979Srwatson 1986100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1987100979Srwatson 1988100979Srwatson if (!mac_enforce_fs) 1989100979Srwatson return (0); 1990100979Srwatson 1991100979Srwatson MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1992100979Srwatson attrnamespace, name, uio); 1993100979Srwatson return (error); 1994100979Srwatson} 1995100979Srwatson 1996100979Srwatsonint 1997104529Srwatsonmac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 1998104529Srwatson struct vnode *vp, struct componentname *cnp) 1999104529Srwatson{ 2000104529Srwatson int error; 2001104529Srwatson 2002104529Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link"); 2003104529Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link"); 2004104529Srwatson 2005104529Srwatson if (!mac_enforce_fs) 2006104529Srwatson return (0); 2007104529Srwatson 2008104529Srwatson MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp, 2009104529Srwatson &vp->v_label, cnp); 2010104529Srwatson return (error); 2011104529Srwatson} 2012104529Srwatson 2013104529Srwatsonint 2014100979Srwatsonmac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2015100979Srwatson struct componentname *cnp) 2016100979Srwatson{ 2017100979Srwatson int error; 2018100979Srwatson 2019100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 2020100979Srwatson 2021100979Srwatson if (!mac_enforce_fs) 2022100979Srwatson return (0); 2023100979Srwatson 2024100979Srwatson MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 2025100979Srwatson return (error); 2026100979Srwatson} 2027100979Srwatson 2028104546Srwatsonint 2029104546Srwatsonmac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) 2030100979Srwatson{ 2031104546Srwatson int error; 2032100979Srwatson 2033104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); 2034103514Srwatson 2035104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 2036104546Srwatson return (0); 2037104546Srwatson 2038104546Srwatson MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); 2039104546Srwatson return (error); 2040100979Srwatson} 2041100979Srwatson 2042104546Srwatsonvoid 2043104546Srwatsonmac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) 2044104546Srwatson{ 2045104546Srwatson int result = *prot; 2046104546Srwatson 2047104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); 2048104546Srwatson 2049104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 2050104546Srwatson return; 2051104546Srwatson 2052104546Srwatson MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, 2053104546Srwatson &result); 2054104546Srwatson 2055104546Srwatson *prot = result; 2056104546Srwatson} 2057104546Srwatson 2058100979Srwatsonint 2059104546Srwatsonmac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) 2060104546Srwatson{ 2061104546Srwatson int error; 2062104546Srwatson 2063104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); 2064104546Srwatson 2065104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 2066104546Srwatson return (0); 2067104546Srwatson 2068104546Srwatson MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); 2069104546Srwatson return (error); 2070104546Srwatson} 2071104546Srwatson 2072104546Srwatsonint 2073102112Srwatsonmac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode) 2074100979Srwatson{ 2075100979Srwatson int error; 2076100979Srwatson 2077102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 2078102112Srwatson 2079100979Srwatson if (!mac_enforce_fs) 2080100979Srwatson return (0); 2081100979Srwatson 2082102112Srwatson MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 2083102112Srwatson return (error); 2084102112Srwatson} 2085102112Srwatson 2086102112Srwatsonint 2087102129Srwatsonmac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2088102129Srwatson struct vnode *vp) 2089102112Srwatson{ 2090102112Srwatson int error; 2091102112Srwatson 2092102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 2093102112Srwatson 2094102112Srwatson if (!mac_enforce_fs) 2095102112Srwatson return (0); 2096102112Srwatson 2097102129Srwatson MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 2098102129Srwatson &vp->v_label); 2099100979Srwatson 2100100979Srwatson return (error); 2101100979Srwatson} 2102100979Srwatson 2103100979Srwatsonint 2104102129Srwatsonmac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2105102129Srwatson struct vnode *vp) 2106100979Srwatson{ 2107100979Srwatson int error; 2108100979Srwatson 2109102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 2110100979Srwatson 2111100979Srwatson if (!mac_enforce_fs) 2112100979Srwatson return (0); 2113100979Srwatson 2114102129Srwatson MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 2115102129Srwatson &vp->v_label); 2116102112Srwatson 2117100979Srwatson return (error); 2118100979Srwatson} 2119100979Srwatson 2120100979Srwatsonint 2121100979Srwatsonmac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 2122100979Srwatson{ 2123100979Srwatson int error; 2124100979Srwatson 2125100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 2126100979Srwatson 2127100979Srwatson if (!mac_enforce_fs) 2128100979Srwatson return (0); 2129100979Srwatson 2130100979Srwatson MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 2131100979Srwatson return (error); 2132100979Srwatson} 2133100979Srwatson 2134100979Srwatsonint 2135100979Srwatsonmac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 2136100979Srwatson{ 2137100979Srwatson int error; 2138100979Srwatson 2139100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 2140100979Srwatson 2141100979Srwatson if (!mac_enforce_fs) 2142100979Srwatson return (0); 2143100979Srwatson 2144100979Srwatson MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 2145100979Srwatson return (error); 2146100979Srwatson} 2147100979Srwatson 2148100979Srwatsonstatic int 2149100979Srwatsonmac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2150100979Srwatson struct label *newlabel) 2151100979Srwatson{ 2152100979Srwatson int error; 2153100979Srwatson 2154100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 2155100979Srwatson 2156100979Srwatson MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 2157100979Srwatson 2158100979Srwatson return (error); 2159100979Srwatson} 2160100979Srwatson 2161100979Srwatsonint 2162100979Srwatsonmac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2163100979Srwatson struct vnode *vp, struct componentname *cnp) 2164100979Srwatson{ 2165100979Srwatson int error; 2166100979Srwatson 2167100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 2168100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 2169100979Srwatson 2170100979Srwatson if (!mac_enforce_fs) 2171100979Srwatson return (0); 2172100979Srwatson 2173100979Srwatson MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 2174100979Srwatson &vp->v_label, cnp); 2175100979Srwatson return (error); 2176100979Srwatson} 2177100979Srwatson 2178100979Srwatsonint 2179100979Srwatsonmac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2180100979Srwatson struct vnode *vp, int samedir, struct componentname *cnp) 2181100979Srwatson{ 2182100979Srwatson int error; 2183100979Srwatson 2184100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 2185100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 2186100979Srwatson 2187100979Srwatson if (!mac_enforce_fs) 2188100979Srwatson return (0); 2189100979Srwatson 2190100979Srwatson MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 2191100979Srwatson vp != NULL ? &vp->v_label : NULL, samedir, cnp); 2192100979Srwatson return (error); 2193100979Srwatson} 2194100979Srwatson 2195100979Srwatsonint 2196100979Srwatsonmac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 2197100979Srwatson{ 2198100979Srwatson int error; 2199100979Srwatson 2200100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 2201100979Srwatson 2202100979Srwatson if (!mac_enforce_fs) 2203100979Srwatson return (0); 2204100979Srwatson 2205100979Srwatson MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 2206100979Srwatson return (error); 2207100979Srwatson} 2208100979Srwatson 2209100979Srwatsonint 2210100979Srwatsonmac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 2211100979Srwatson struct acl *acl) 2212100979Srwatson{ 2213100979Srwatson int error; 2214100979Srwatson 2215100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 2216100979Srwatson 2217100979Srwatson if (!mac_enforce_fs) 2218100979Srwatson return (0); 2219100979Srwatson 2220100979Srwatson MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 2221100979Srwatson return (error); 2222100979Srwatson} 2223100979Srwatson 2224100979Srwatsonint 2225100979Srwatsonmac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2226100979Srwatson int attrnamespace, const char *name, struct uio *uio) 2227100979Srwatson{ 2228100979Srwatson int error; 2229100979Srwatson 2230100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 2231100979Srwatson 2232100979Srwatson if (!mac_enforce_fs) 2233100979Srwatson return (0); 2234100979Srwatson 2235100979Srwatson MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 2236100979Srwatson attrnamespace, name, uio); 2237100979Srwatson return (error); 2238100979Srwatson} 2239100979Srwatson 2240100979Srwatsonint 2241100979Srwatsonmac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 2242100979Srwatson{ 2243100979Srwatson int error; 2244100979Srwatson 2245100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 2246100979Srwatson 2247100979Srwatson if (!mac_enforce_fs) 2248100979Srwatson return (0); 2249100979Srwatson 2250100979Srwatson MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 2251100979Srwatson return (error); 2252100979Srwatson} 2253100979Srwatson 2254100979Srwatsonint 2255100979Srwatsonmac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 2256100979Srwatson{ 2257100979Srwatson int error; 2258100979Srwatson 2259100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 2260100979Srwatson 2261100979Srwatson if (!mac_enforce_fs) 2262100979Srwatson return (0); 2263100979Srwatson 2264100979Srwatson MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 2265100979Srwatson return (error); 2266100979Srwatson} 2267100979Srwatson 2268100979Srwatsonint 2269100979Srwatsonmac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 2270100979Srwatson gid_t gid) 2271100979Srwatson{ 2272100979Srwatson int error; 2273100979Srwatson 2274100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 2275100979Srwatson 2276100979Srwatson if (!mac_enforce_fs) 2277100979Srwatson return (0); 2278100979Srwatson 2279100979Srwatson MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 2280100979Srwatson return (error); 2281100979Srwatson} 2282100979Srwatson 2283100979Srwatsonint 2284100979Srwatsonmac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2285100979Srwatson struct timespec atime, struct timespec mtime) 2286100979Srwatson{ 2287100979Srwatson int error; 2288100979Srwatson 2289100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 2290100979Srwatson 2291100979Srwatson if (!mac_enforce_fs) 2292100979Srwatson return (0); 2293100979Srwatson 2294100979Srwatson MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 2295100979Srwatson mtime); 2296100979Srwatson return (error); 2297100979Srwatson} 2298100979Srwatson 2299100979Srwatsonint 2300102129Srwatsonmac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2301102129Srwatson struct vnode *vp) 2302100979Srwatson{ 2303100979Srwatson int error; 2304100979Srwatson 2305100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 2306100979Srwatson 2307100979Srwatson if (!mac_enforce_fs) 2308100979Srwatson return (0); 2309100979Srwatson 2310102129Srwatson MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 2311102129Srwatson &vp->v_label); 2312100979Srwatson return (error); 2313100979Srwatson} 2314100979Srwatson 2315102112Srwatsonint 2316102129Srwatsonmac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 2317102129Srwatson struct vnode *vp) 2318102112Srwatson{ 2319102112Srwatson int error; 2320102112Srwatson 2321102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 2322102112Srwatson 2323102112Srwatson if (!mac_enforce_fs) 2324102112Srwatson return (0); 2325102112Srwatson 2326102129Srwatson MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 2327102129Srwatson &vp->v_label); 2328102112Srwatson 2329102112Srwatson return (error); 2330102112Srwatson} 2331102112Srwatson 2332100979Srwatson/* 2333100979Srwatson * When relabeling a process, call out to the policies for the maximum 2334100979Srwatson * permission allowed for each object type we know about in its 2335100979Srwatson * memory space, and revoke access (in the least surprising ways we 2336100979Srwatson * know) when necessary. The process lock is not held here. 2337100979Srwatson */ 2338100979Srwatsonstatic void 2339100979Srwatsonmac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 2340100979Srwatson{ 2341100979Srwatson 2342100979Srwatson /* XXX freeze all other threads */ 2343100979Srwatson mac_cred_mmapped_drop_perms_recurse(td, cred, 2344100979Srwatson &td->td_proc->p_vmspace->vm_map); 2345100979Srwatson /* XXX allow other threads to continue */ 2346100979Srwatson} 2347100979Srwatson 2348100979Srwatsonstatic __inline const char * 2349100979Srwatsonprot2str(vm_prot_t prot) 2350100979Srwatson{ 2351100979Srwatson 2352100979Srwatson switch (prot & VM_PROT_ALL) { 2353100979Srwatson case VM_PROT_READ: 2354100979Srwatson return ("r--"); 2355100979Srwatson case VM_PROT_READ | VM_PROT_WRITE: 2356100979Srwatson return ("rw-"); 2357100979Srwatson case VM_PROT_READ | VM_PROT_EXECUTE: 2358100979Srwatson return ("r-x"); 2359100979Srwatson case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 2360100979Srwatson return ("rwx"); 2361100979Srwatson case VM_PROT_WRITE: 2362100979Srwatson return ("-w-"); 2363100979Srwatson case VM_PROT_EXECUTE: 2364100979Srwatson return ("--x"); 2365100979Srwatson case VM_PROT_WRITE | VM_PROT_EXECUTE: 2366100979Srwatson return ("-wx"); 2367100979Srwatson default: 2368100979Srwatson return ("---"); 2369100979Srwatson } 2370100979Srwatson} 2371100979Srwatson 2372100979Srwatsonstatic void 2373100979Srwatsonmac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 2374100979Srwatson struct vm_map *map) 2375100979Srwatson{ 2376100979Srwatson struct vm_map_entry *vme; 2377104546Srwatson int result; 2378104546Srwatson vm_prot_t revokeperms; 2379100979Srwatson vm_object_t object; 2380100979Srwatson vm_ooffset_t offset; 2381100979Srwatson struct vnode *vp; 2382100979Srwatson 2383103136Srwatson if (!mac_mmap_revocation) 2384103136Srwatson return; 2385103136Srwatson 2386100979Srwatson vm_map_lock_read(map); 2387100979Srwatson for (vme = map->header.next; vme != &map->header; vme = vme->next) { 2388100979Srwatson if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 2389100979Srwatson mac_cred_mmapped_drop_perms_recurse(td, cred, 2390100979Srwatson vme->object.sub_map); 2391100979Srwatson continue; 2392100979Srwatson } 2393100979Srwatson /* 2394100979Srwatson * Skip over entries that obviously are not shared. 2395100979Srwatson */ 2396100979Srwatson if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 2397100979Srwatson !vme->max_protection) 2398100979Srwatson continue; 2399100979Srwatson /* 2400100979Srwatson * Drill down to the deepest backing object. 2401100979Srwatson */ 2402100979Srwatson offset = vme->offset; 2403100979Srwatson object = vme->object.vm_object; 2404100979Srwatson if (object == NULL) 2405100979Srwatson continue; 2406100979Srwatson while (object->backing_object != NULL) { 2407100979Srwatson object = object->backing_object; 2408100979Srwatson offset += object->backing_object_offset; 2409100979Srwatson } 2410100979Srwatson /* 2411100979Srwatson * At the moment, vm_maps and objects aren't considered 2412100979Srwatson * by the MAC system, so only things with backing by a 2413100979Srwatson * normal object (read: vnodes) are checked. 2414100979Srwatson */ 2415100979Srwatson if (object->type != OBJT_VNODE) 2416100979Srwatson continue; 2417100979Srwatson vp = (struct vnode *)object->handle; 2418100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2419104546Srwatson result = vme->max_protection; 2420104546Srwatson mac_check_vnode_mmap_downgrade(cred, vp, &result); 2421100979Srwatson VOP_UNLOCK(vp, 0, td); 2422100979Srwatson /* 2423100979Srwatson * Find out what maximum protection we may be allowing 2424100979Srwatson * now but a policy needs to get removed. 2425100979Srwatson */ 2426100979Srwatson revokeperms = vme->max_protection & ~result; 2427100979Srwatson if (!revokeperms) 2428100979Srwatson continue; 2429102949Sbde printf("pid %ld: revoking %s perms from %#lx:%ld " 2430102949Sbde "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 2431102949Sbde prot2str(revokeperms), (u_long)vme->start, 2432102949Sbde (long)(vme->end - vme->start), 2433100979Srwatson prot2str(vme->max_protection), prot2str(vme->protection)); 2434100979Srwatson vm_map_lock_upgrade(map); 2435100979Srwatson /* 2436100979Srwatson * This is the really simple case: if a map has more 2437100979Srwatson * max_protection than is allowed, but it's not being 2438100979Srwatson * actually used (that is, the current protection is 2439100979Srwatson * still allowed), we can just wipe it out and do 2440100979Srwatson * nothing more. 2441100979Srwatson */ 2442100979Srwatson if ((vme->protection & revokeperms) == 0) { 2443100979Srwatson vme->max_protection -= revokeperms; 2444100979Srwatson } else { 2445100979Srwatson if (revokeperms & VM_PROT_WRITE) { 2446100979Srwatson /* 2447100979Srwatson * In the more complicated case, flush out all 2448100979Srwatson * pending changes to the object then turn it 2449100979Srwatson * copy-on-write. 2450100979Srwatson */ 2451100979Srwatson vm_object_reference(object); 2452100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2453100979Srwatson vm_object_page_clean(object, 2454100979Srwatson OFF_TO_IDX(offset), 2455100979Srwatson OFF_TO_IDX(offset + vme->end - vme->start + 2456100979Srwatson PAGE_MASK), 2457100979Srwatson OBJPC_SYNC); 2458100979Srwatson VOP_UNLOCK(vp, 0, td); 2459100979Srwatson vm_object_deallocate(object); 2460100979Srwatson /* 2461100979Srwatson * Why bother if there's no read permissions 2462100979Srwatson * anymore? For the rest, we need to leave 2463100979Srwatson * the write permissions on for COW, or 2464100979Srwatson * remove them entirely if configured to. 2465100979Srwatson */ 2466100979Srwatson if (!mac_mmap_revocation_via_cow) { 2467100979Srwatson vme->max_protection &= ~VM_PROT_WRITE; 2468100979Srwatson vme->protection &= ~VM_PROT_WRITE; 2469100979Srwatson } if ((revokeperms & VM_PROT_READ) == 0) 2470100979Srwatson vme->eflags |= MAP_ENTRY_COW | 2471100979Srwatson MAP_ENTRY_NEEDS_COPY; 2472100979Srwatson } 2473100979Srwatson if (revokeperms & VM_PROT_EXECUTE) { 2474100979Srwatson vme->max_protection &= ~VM_PROT_EXECUTE; 2475100979Srwatson vme->protection &= ~VM_PROT_EXECUTE; 2476100979Srwatson } 2477100979Srwatson if (revokeperms & VM_PROT_READ) { 2478100979Srwatson vme->max_protection = 0; 2479100979Srwatson vme->protection = 0; 2480100979Srwatson } 2481100979Srwatson pmap_protect(map->pmap, vme->start, vme->end, 2482100979Srwatson vme->protection & ~revokeperms); 2483100979Srwatson vm_map_simplify_entry(map, vme); 2484100979Srwatson } 2485100979Srwatson vm_map_lock_downgrade(map); 2486100979Srwatson } 2487100979Srwatson vm_map_unlock_read(map); 2488100979Srwatson} 2489100979Srwatson 2490100979Srwatson/* 2491100979Srwatson * When the subject's label changes, it may require revocation of privilege 2492100979Srwatson * to mapped objects. This can't be done on-the-fly later with a unified 2493100979Srwatson * buffer cache. 2494100979Srwatson */ 2495100979Srwatsonstatic void 2496100979Srwatsonmac_relabel_cred(struct ucred *cred, struct label *newlabel) 2497100979Srwatson{ 2498100979Srwatson 2499100979Srwatson MAC_PERFORM(relabel_cred, cred, newlabel); 2500100979Srwatson} 2501100979Srwatson 2502100979Srwatsonvoid 2503100979Srwatsonmac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 2504100979Srwatson{ 2505100979Srwatson 2506100979Srwatson MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 2507100979Srwatson} 2508100979Srwatson 2509100979Srwatsonvoid 2510100979Srwatsonmac_create_ifnet(struct ifnet *ifnet) 2511100979Srwatson{ 2512100979Srwatson 2513100979Srwatson MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2514100979Srwatson} 2515100979Srwatson 2516100979Srwatsonvoid 2517100979Srwatsonmac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2518100979Srwatson{ 2519100979Srwatson 2520100979Srwatson MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2521100979Srwatson} 2522100979Srwatson 2523100979Srwatsonvoid 2524100979Srwatsonmac_create_socket(struct ucred *cred, struct socket *socket) 2525100979Srwatson{ 2526100979Srwatson 2527100979Srwatson MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2528100979Srwatson} 2529100979Srwatson 2530100979Srwatsonvoid 2531100979Srwatsonmac_create_pipe(struct ucred *cred, struct pipe *pipe) 2532100979Srwatson{ 2533100979Srwatson 2534100979Srwatson MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2535100979Srwatson} 2536100979Srwatson 2537100979Srwatsonvoid 2538100979Srwatsonmac_create_socket_from_socket(struct socket *oldsocket, 2539100979Srwatson struct socket *newsocket) 2540100979Srwatson{ 2541100979Srwatson 2542100979Srwatson MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2543100979Srwatson newsocket, &newsocket->so_label); 2544100979Srwatson} 2545100979Srwatson 2546100979Srwatsonstatic void 2547100979Srwatsonmac_relabel_socket(struct ucred *cred, struct socket *socket, 2548100979Srwatson struct label *newlabel) 2549100979Srwatson{ 2550100979Srwatson 2551100979Srwatson MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2552100979Srwatson} 2553100979Srwatson 2554100979Srwatsonstatic void 2555100979Srwatsonmac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2556100979Srwatson{ 2557100979Srwatson 2558100979Srwatson MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2559100979Srwatson} 2560100979Srwatson 2561100979Srwatsonvoid 2562100979Srwatsonmac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2563100979Srwatson{ 2564100979Srwatson 2565100979Srwatson MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label, 2566100979Srwatson socket, &socket->so_peerlabel); 2567100979Srwatson} 2568100979Srwatson 2569100979Srwatsonvoid 2570100979Srwatsonmac_set_socket_peer_from_socket(struct socket *oldsocket, 2571100979Srwatson struct socket *newsocket) 2572100979Srwatson{ 2573100979Srwatson 2574100979Srwatson MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2575100979Srwatson &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2576100979Srwatson} 2577100979Srwatson 2578100979Srwatsonvoid 2579100979Srwatsonmac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2580100979Srwatson{ 2581100979Srwatson 2582100979Srwatson MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2583100979Srwatson datagram, &datagram->m_pkthdr.label); 2584100979Srwatson} 2585100979Srwatson 2586100979Srwatsonvoid 2587100979Srwatsonmac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2588100979Srwatson{ 2589100979Srwatson 2590100979Srwatson MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label, 2591100979Srwatson fragment, &fragment->m_pkthdr.label); 2592100979Srwatson} 2593100979Srwatson 2594100979Srwatsonvoid 2595100979Srwatsonmac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2596100979Srwatson{ 2597100979Srwatson 2598100979Srwatson MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2599100979Srwatson &ipq->ipq_label); 2600100979Srwatson} 2601100979Srwatson 2602100979Srwatsonvoid 2603100979Srwatsonmac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2604100979Srwatson{ 2605100979Srwatson 2606100979Srwatson MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label, 2607100979Srwatson newmbuf, &newmbuf->m_pkthdr.label); 2608100979Srwatson} 2609100979Srwatson 2610100979Srwatsonvoid 2611100979Srwatsonmac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2612100979Srwatson{ 2613100979Srwatson 2614100979Srwatson MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2615100979Srwatson &mbuf->m_pkthdr.label); 2616100979Srwatson} 2617100979Srwatson 2618100979Srwatsonvoid 2619100979Srwatsonmac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2620100979Srwatson{ 2621100979Srwatson 2622100979Srwatson MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2623100979Srwatson &mbuf->m_pkthdr.label); 2624100979Srwatson} 2625100979Srwatson 2626100979Srwatsonvoid 2627100979Srwatsonmac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2628100979Srwatson{ 2629100979Srwatson 2630100979Srwatson MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2631100979Srwatson &mbuf->m_pkthdr.label); 2632100979Srwatson} 2633100979Srwatson 2634100979Srwatsonvoid 2635100979Srwatsonmac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2636100979Srwatson struct mbuf *newmbuf) 2637100979Srwatson{ 2638100979Srwatson 2639100979Srwatson MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, 2640100979Srwatson &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf, 2641100979Srwatson &newmbuf->m_pkthdr.label); 2642100979Srwatson} 2643100979Srwatson 2644100979Srwatsonvoid 2645100979Srwatsonmac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2646100979Srwatson{ 2647100979Srwatson 2648100979Srwatson MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label, 2649100979Srwatson newmbuf, &newmbuf->m_pkthdr.label); 2650100979Srwatson} 2651100979Srwatson 2652100979Srwatsonint 2653100979Srwatsonmac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2654100979Srwatson{ 2655100979Srwatson int result; 2656100979Srwatson 2657100979Srwatson result = 1; 2658100979Srwatson MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label, 2659100979Srwatson ipq, &ipq->ipq_label); 2660100979Srwatson 2661100979Srwatson return (result); 2662100979Srwatson} 2663100979Srwatson 2664100979Srwatsonvoid 2665100979Srwatsonmac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2666100979Srwatson{ 2667100979Srwatson 2668100979Srwatson MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2669100979Srwatson &ipq->ipq_label); 2670100979Srwatson} 2671100979Srwatson 2672100979Srwatsonvoid 2673100979Srwatsonmac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2674100979Srwatson{ 2675100979Srwatson 2676100979Srwatson MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2677100979Srwatson &mbuf->m_pkthdr.label); 2678100979Srwatson} 2679100979Srwatson 2680100979Srwatsonvoid 2681100979Srwatsonmac_create_mount(struct ucred *cred, struct mount *mp) 2682100979Srwatson{ 2683100979Srwatson 2684100979Srwatson MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2685100979Srwatson &mp->mnt_fslabel); 2686100979Srwatson} 2687100979Srwatson 2688100979Srwatsonvoid 2689100979Srwatsonmac_create_root_mount(struct ucred *cred, struct mount *mp) 2690100979Srwatson{ 2691100979Srwatson 2692100979Srwatson MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2693100979Srwatson &mp->mnt_fslabel); 2694100979Srwatson} 2695100979Srwatson 2696100979Srwatsonint 2697100979Srwatsonmac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2698100979Srwatson{ 2699100979Srwatson int error; 2700100979Srwatson 2701100979Srwatson if (!mac_enforce_network) 2702100979Srwatson return (0); 2703100979Srwatson 2704100979Srwatson MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2705100979Srwatson &ifnet->if_label); 2706100979Srwatson 2707100979Srwatson return (error); 2708100979Srwatson} 2709100979Srwatson 2710100979Srwatsonstatic int 2711100979Srwatsonmac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2712100979Srwatson{ 2713100979Srwatson int error; 2714100979Srwatson 2715100979Srwatson MAC_CHECK(check_cred_relabel, cred, newlabel); 2716100979Srwatson 2717100979Srwatson return (error); 2718100979Srwatson} 2719100979Srwatson 2720100979Srwatsonint 2721100979Srwatsonmac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2722100979Srwatson{ 2723100979Srwatson int error; 2724100979Srwatson 2725100979Srwatson if (!mac_enforce_process) 2726100979Srwatson return (0); 2727100979Srwatson 2728100979Srwatson MAC_CHECK(check_cred_visible, u1, u2); 2729100979Srwatson 2730100979Srwatson return (error); 2731100979Srwatson} 2732100979Srwatson 2733100979Srwatsonint 2734100979Srwatsonmac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2735100979Srwatson{ 2736100979Srwatson int error; 2737100979Srwatson 2738100979Srwatson if (!mac_enforce_network) 2739100979Srwatson return (0); 2740100979Srwatson 2741100979Srwatson KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr")); 2742100979Srwatson if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED)) 2743105598Sbrooks if_printf(ifnet, "not initialized\n"); 2744100979Srwatson 2745100979Srwatson MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2746100979Srwatson &mbuf->m_pkthdr.label); 2747100979Srwatson 2748100979Srwatson return (error); 2749100979Srwatson} 2750100979Srwatson 2751100979Srwatsonint 2752100979Srwatsonmac_check_mount_stat(struct ucred *cred, struct mount *mount) 2753100979Srwatson{ 2754100979Srwatson int error; 2755100979Srwatson 2756100979Srwatson if (!mac_enforce_fs) 2757100979Srwatson return (0); 2758100979Srwatson 2759100979Srwatson MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2760100979Srwatson 2761100979Srwatson return (error); 2762100979Srwatson} 2763100979Srwatson 2764100979Srwatsonint 2765100979Srwatsonmac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2766100979Srwatson void *data) 2767100979Srwatson{ 2768100979Srwatson int error; 2769100979Srwatson 2770104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2771104269Srwatson 2772104269Srwatson if (!mac_enforce_pipe) 2773104269Srwatson return (0); 2774104269Srwatson 2775100979Srwatson MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2776100979Srwatson 2777100979Srwatson return (error); 2778100979Srwatson} 2779100979Srwatson 2780100979Srwatsonint 2781102115Srwatsonmac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2782100979Srwatson{ 2783100979Srwatson int error; 2784100979Srwatson 2785104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2786104269Srwatson 2787104269Srwatson if (!mac_enforce_pipe) 2788104269Srwatson return (0); 2789104269Srwatson 2790102115Srwatson MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2791100979Srwatson 2792100979Srwatson return (error); 2793100979Srwatson} 2794100979Srwatson 2795102115Srwatsonint 2796102115Srwatsonmac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2797102115Srwatson{ 2798102115Srwatson int error; 2799102115Srwatson 2800104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2801104269Srwatson 2802104269Srwatson if (!mac_enforce_pipe) 2803104269Srwatson return (0); 2804104269Srwatson 2805102115Srwatson MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2806102115Srwatson 2807102115Srwatson return (error); 2808102115Srwatson} 2809102115Srwatson 2810100979Srwatsonstatic int 2811100979Srwatsonmac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2812100979Srwatson struct label *newlabel) 2813100979Srwatson{ 2814100979Srwatson int error; 2815100979Srwatson 2816104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2817104269Srwatson 2818104269Srwatson if (!mac_enforce_pipe) 2819104269Srwatson return (0); 2820104269Srwatson 2821100979Srwatson MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2822100979Srwatson 2823100979Srwatson return (error); 2824100979Srwatson} 2825100979Srwatson 2826100979Srwatsonint 2827102115Srwatsonmac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2828102115Srwatson{ 2829102115Srwatson int error; 2830102115Srwatson 2831104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2832104269Srwatson 2833104269Srwatson if (!mac_enforce_pipe) 2834104269Srwatson return (0); 2835104269Srwatson 2836102115Srwatson MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2837102115Srwatson 2838102115Srwatson return (error); 2839102115Srwatson} 2840102115Srwatson 2841102115Srwatsonint 2842102115Srwatsonmac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2843102115Srwatson{ 2844102115Srwatson int error; 2845102115Srwatson 2846104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2847104269Srwatson 2848104269Srwatson if (!mac_enforce_pipe) 2849104269Srwatson return (0); 2850104269Srwatson 2851102115Srwatson MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2852102115Srwatson 2853102115Srwatson return (error); 2854102115Srwatson} 2855102115Srwatson 2856102115Srwatsonint 2857100979Srwatsonmac_check_proc_debug(struct ucred *cred, struct proc *proc) 2858100979Srwatson{ 2859100979Srwatson int error; 2860100979Srwatson 2861102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2862102103Srwatson 2863100979Srwatson if (!mac_enforce_process) 2864100979Srwatson return (0); 2865100979Srwatson 2866100979Srwatson MAC_CHECK(check_proc_debug, cred, proc); 2867100979Srwatson 2868100979Srwatson return (error); 2869100979Srwatson} 2870100979Srwatson 2871100979Srwatsonint 2872100979Srwatsonmac_check_proc_sched(struct ucred *cred, struct proc *proc) 2873100979Srwatson{ 2874100979Srwatson int error; 2875100979Srwatson 2876102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2877102103Srwatson 2878100979Srwatson if (!mac_enforce_process) 2879100979Srwatson return (0); 2880100979Srwatson 2881100979Srwatson MAC_CHECK(check_proc_sched, cred, proc); 2882100979Srwatson 2883100979Srwatson return (error); 2884100979Srwatson} 2885100979Srwatson 2886100979Srwatsonint 2887100979Srwatsonmac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2888100979Srwatson{ 2889100979Srwatson int error; 2890100979Srwatson 2891102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2892102103Srwatson 2893100979Srwatson if (!mac_enforce_process) 2894100979Srwatson return (0); 2895100979Srwatson 2896100979Srwatson MAC_CHECK(check_proc_signal, cred, proc, signum); 2897100979Srwatson 2898100979Srwatson return (error); 2899100979Srwatson} 2900100979Srwatson 2901100979Srwatsonint 2902100979Srwatsonmac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2903100979Srwatson struct sockaddr *sockaddr) 2904100979Srwatson{ 2905100979Srwatson int error; 2906100979Srwatson 2907100979Srwatson if (!mac_enforce_socket) 2908100979Srwatson return (0); 2909100979Srwatson 2910100979Srwatson MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2911100979Srwatson sockaddr); 2912100979Srwatson 2913100979Srwatson return (error); 2914100979Srwatson} 2915100979Srwatson 2916100979Srwatsonint 2917100979Srwatsonmac_check_socket_connect(struct ucred *cred, struct socket *socket, 2918100979Srwatson struct sockaddr *sockaddr) 2919100979Srwatson{ 2920100979Srwatson int error; 2921100979Srwatson 2922100979Srwatson if (!mac_enforce_socket) 2923100979Srwatson return (0); 2924100979Srwatson 2925100979Srwatson MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2926100979Srwatson sockaddr); 2927100979Srwatson 2928100979Srwatson return (error); 2929100979Srwatson} 2930100979Srwatson 2931100979Srwatsonint 2932101933Srwatsonmac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2933100979Srwatson{ 2934100979Srwatson int error; 2935100979Srwatson 2936100979Srwatson if (!mac_enforce_socket) 2937100979Srwatson return (0); 2938100979Srwatson 2939101933Srwatson MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2940101933Srwatson &mbuf->m_pkthdr.label); 2941101933Srwatson 2942100979Srwatson return (error); 2943100979Srwatson} 2944100979Srwatson 2945100979Srwatsonint 2946101933Srwatsonmac_check_socket_listen(struct ucred *cred, struct socket *socket) 2947100979Srwatson{ 2948100979Srwatson int error; 2949100979Srwatson 2950100979Srwatson if (!mac_enforce_socket) 2951100979Srwatson return (0); 2952100979Srwatson 2953101933Srwatson MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2954100979Srwatson return (error); 2955100979Srwatson} 2956100979Srwatson 2957104571Srwatsonint 2958104571Srwatsonmac_check_socket_receive(struct ucred *cred, struct socket *so) 2959104571Srwatson{ 2960104571Srwatson int error; 2961104571Srwatson 2962104571Srwatson if (!mac_enforce_socket) 2963104571Srwatson return (0); 2964104571Srwatson 2965104571Srwatson MAC_CHECK(check_socket_receive, cred, so, &so->so_label); 2966104571Srwatson 2967104571Srwatson return (error); 2968104571Srwatson} 2969104571Srwatson 2970100979Srwatsonstatic int 2971100979Srwatsonmac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2972100979Srwatson struct label *newlabel) 2973100979Srwatson{ 2974100979Srwatson int error; 2975100979Srwatson 2976100979Srwatson MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2977100979Srwatson newlabel); 2978100979Srwatson 2979100979Srwatson return (error); 2980100979Srwatson} 2981100979Srwatson 2982100979Srwatsonint 2983104571Srwatsonmac_check_socket_send(struct ucred *cred, struct socket *so) 2984104571Srwatson{ 2985104571Srwatson int error; 2986104571Srwatson 2987104571Srwatson if (!mac_enforce_socket) 2988104571Srwatson return (0); 2989104571Srwatson 2990104571Srwatson MAC_CHECK(check_socket_send, cred, so, &so->so_label); 2991104571Srwatson 2992104571Srwatson return (error); 2993104571Srwatson} 2994104571Srwatson 2995104571Srwatsonint 2996100979Srwatsonmac_check_socket_visible(struct ucred *cred, struct socket *socket) 2997100979Srwatson{ 2998100979Srwatson int error; 2999100979Srwatson 3000100979Srwatson if (!mac_enforce_socket) 3001100979Srwatson return (0); 3002105694Srwatson 3003100979Srwatson MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 3004105694Srwatson 3005100979Srwatson return (error); 3006100979Srwatson} 3007100979Srwatson 3008100979Srwatsonint 3009106024Srwatsonmac_check_system_reboot(struct ucred *cred, int howto) 3010106024Srwatson{ 3011106024Srwatson int error; 3012106024Srwatson 3013106024Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_reboot"); 3014106024Srwatson 3015106024Srwatson if (!mac_enforce_reboot) 3016106024Srwatson return (0); 3017106024Srwatson 3018106024Srwatson MAC_CHECK(check_system_reboot, cred, howto); 3019106024Srwatson return (error); 3020106024Srwatson} 3021106024Srwatson 3022106024Srwatsonint 3023106023Srwatsonmac_check_system_swapon(struct ucred *cred, struct vnode *vp) 3024106023Srwatson{ 3025106023Srwatson int error; 3026106023Srwatson 3027106023Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon"); 3028106023Srwatson 3029106023Srwatson if (!mac_enforce_fs) 3030106023Srwatson return (0); 3031106023Srwatson 3032106023Srwatson MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label); 3033106023Srwatson return (error); 3034106023Srwatson} 3035106023Srwatson 3036106023Srwatsonint 3037100979Srwatsonmac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 3038100979Srwatson struct ifnet *ifnet) 3039100979Srwatson{ 3040105694Srwatson char *elements, *buffer; 3041105694Srwatson struct mac mac; 3042100979Srwatson int error; 3043100979Srwatson 3044105694Srwatson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 3045100979Srwatson if (error) 3046100979Srwatson return (error); 3047100979Srwatson 3048105694Srwatson error = mac_check_structmac_consistent(&mac); 3049105694Srwatson if (error) 3050105694Srwatson return (error); 3051105694Srwatson 3052105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3053105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3054105694Srwatson if (error) { 3055105694Srwatson free(elements, M_MACTEMP); 3056105694Srwatson return (error); 3057105694Srwatson } 3058105694Srwatson 3059105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3060105694Srwatson error = mac_externalize_ifnet_label(&ifnet->if_label, elements, 3061105694Srwatson buffer, mac.m_buflen, M_WAITOK); 3062105694Srwatson if (error == 0) 3063105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3064105694Srwatson 3065105694Srwatson free(buffer, M_MACTEMP); 3066105694Srwatson free(elements, M_MACTEMP); 3067105694Srwatson 3068105694Srwatson return (error); 3069100979Srwatson} 3070100979Srwatson 3071100979Srwatsonint 3072100979Srwatsonmac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 3073100979Srwatson struct ifnet *ifnet) 3074100979Srwatson{ 3075100979Srwatson struct label intlabel; 3076105694Srwatson struct mac mac; 3077105694Srwatson char *buffer; 3078100979Srwatson int error; 3079100979Srwatson 3080105694Srwatson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 3081100979Srwatson if (error) 3082100979Srwatson return (error); 3083100979Srwatson 3084105694Srwatson error = mac_check_structmac_consistent(&mac); 3085100979Srwatson if (error) 3086100979Srwatson return (error); 3087100979Srwatson 3088105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3089105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3090105694Srwatson if (error) { 3091105694Srwatson free(buffer, M_MACTEMP); 3092105694Srwatson return (error); 3093105694Srwatson } 3094105694Srwatson 3095105694Srwatson mac_init_ifnet_label(&intlabel); 3096105694Srwatson error = mac_internalize_ifnet_label(&intlabel, buffer); 3097105694Srwatson free(buffer, M_MACTEMP); 3098105694Srwatson if (error) { 3099105694Srwatson mac_destroy_ifnet_label(&intlabel); 3100105694Srwatson return (error); 3101105694Srwatson } 3102105694Srwatson 3103100979Srwatson /* 3104100979Srwatson * XXX: Note that this is a redundant privilege check, since 3105100979Srwatson * policies impose this check themselves if required by the 3106100979Srwatson * policy. Eventually, this should go away. 3107100979Srwatson */ 3108100979Srwatson error = suser_cred(cred, 0); 3109105694Srwatson if (error) { 3110105694Srwatson mac_destroy_ifnet_label(&intlabel); 3111105694Srwatson return (error); 3112105694Srwatson } 3113100979Srwatson 3114100979Srwatson MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 3115100979Srwatson &intlabel); 3116105694Srwatson if (error) { 3117105694Srwatson mac_destroy_ifnet_label(&intlabel); 3118105694Srwatson return (error); 3119105694Srwatson } 3120100979Srwatson 3121100979Srwatson MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 3122100979Srwatson 3123105694Srwatson mac_destroy_ifnet_label(&intlabel); 3124105694Srwatson return (0); 3125100979Srwatson} 3126100979Srwatson 3127100979Srwatsonvoid 3128100979Srwatsonmac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp) 3129100979Srwatson{ 3130100979Srwatson 3131100979Srwatson MAC_PERFORM(create_devfs_vnode, de, &de->de_label, vp, &vp->v_label); 3132100979Srwatson} 3133100979Srwatson 3134100979Srwatsonvoid 3135100979Srwatsonmac_create_devfs_device(dev_t dev, struct devfs_dirent *de) 3136100979Srwatson{ 3137100979Srwatson 3138100979Srwatson MAC_PERFORM(create_devfs_device, dev, de, &de->de_label); 3139100979Srwatson} 3140100979Srwatson 3141104533Srwatsonvoid 3142104533Srwatsonmac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd, 3143104533Srwatson struct devfs_dirent *de) 3144104533Srwatson{ 3145104533Srwatson 3146104533Srwatson MAC_PERFORM(create_devfs_symlink, cred, dd, &dd->de_label, de, 3147104533Srwatson &de->de_label); 3148104533Srwatson} 3149104533Srwatson 3150100979Srwatsonvoid 3151100979Srwatsonmac_create_devfs_directory(char *dirname, int dirnamelen, 3152100979Srwatson struct devfs_dirent *de) 3153100979Srwatson{ 3154100979Srwatson 3155100979Srwatson MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de, 3156100979Srwatson &de->de_label); 3157100979Srwatson} 3158100979Srwatson 3159100979Srwatsonint 3160100979Srwatsonmac_setsockopt_label_set(struct ucred *cred, struct socket *so, 3161105694Srwatson struct mac *mac) 3162100979Srwatson{ 3163100979Srwatson struct label intlabel; 3164105694Srwatson char *buffer; 3165100979Srwatson int error; 3166100979Srwatson 3167105694Srwatson error = mac_check_structmac_consistent(mac); 3168100979Srwatson if (error) 3169100979Srwatson return (error); 3170100979Srwatson 3171105694Srwatson buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3172105694Srwatson error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); 3173105694Srwatson if (error) { 3174105694Srwatson free(buffer, M_MACTEMP); 3175105694Srwatson return (error); 3176105694Srwatson } 3177105694Srwatson 3178105694Srwatson mac_init_socket_label(&intlabel, M_WAITOK); 3179105694Srwatson error = mac_internalize_socket_label(&intlabel, buffer); 3180105694Srwatson free(buffer, M_MACTEMP); 3181105694Srwatson if (error) { 3182105694Srwatson mac_destroy_socket_label(&intlabel); 3183105694Srwatson return (error); 3184105694Srwatson } 3185105694Srwatson 3186100979Srwatson mac_check_socket_relabel(cred, so, &intlabel); 3187100979Srwatson if (error) { 3188105694Srwatson mac_destroy_socket_label(&intlabel); 3189100979Srwatson return (error); 3190100979Srwatson } 3191100979Srwatson 3192100979Srwatson mac_relabel_socket(cred, so, &intlabel); 3193100979Srwatson 3194105694Srwatson mac_destroy_socket_label(&intlabel); 3195100979Srwatson return (0); 3196100979Srwatson} 3197100979Srwatson 3198100979Srwatsonint 3199100979Srwatsonmac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 3200100979Srwatson{ 3201100979Srwatson int error; 3202100979Srwatson 3203104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 3204104269Srwatson 3205100979Srwatson error = mac_check_pipe_relabel(cred, pipe, label); 3206100979Srwatson if (error) 3207100979Srwatson return (error); 3208100979Srwatson 3209100979Srwatson mac_relabel_pipe(cred, pipe, label); 3210100979Srwatson 3211100979Srwatson return (0); 3212100979Srwatson} 3213100979Srwatson 3214100979Srwatsonint 3215100979Srwatsonmac_getsockopt_label_get(struct ucred *cred, struct socket *so, 3216105694Srwatson struct mac *mac) 3217100979Srwatson{ 3218105694Srwatson char *buffer, *elements; 3219105694Srwatson int error; 3220100979Srwatson 3221105694Srwatson error = mac_check_structmac_consistent(mac); 3222105694Srwatson if (error) 3223105694Srwatson return (error); 3224105694Srwatson 3225105694Srwatson elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3226105694Srwatson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3227105694Srwatson if (error) { 3228105694Srwatson free(elements, M_MACTEMP); 3229105694Srwatson return (error); 3230105694Srwatson } 3231105694Srwatson 3232105694Srwatson buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3233105694Srwatson error = mac_externalize_socket_label(&so->so_label, elements, 3234105694Srwatson buffer, mac->m_buflen, M_WAITOK); 3235105694Srwatson if (error == 0) 3236105694Srwatson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3237105694Srwatson 3238105694Srwatson free(buffer, M_MACTEMP); 3239105694Srwatson free(elements, M_MACTEMP); 3240105694Srwatson 3241105694Srwatson return (error); 3242100979Srwatson} 3243100979Srwatson 3244100979Srwatsonint 3245100979Srwatsonmac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 3246105694Srwatson struct mac *mac) 3247100979Srwatson{ 3248105694Srwatson char *elements, *buffer; 3249105694Srwatson int error; 3250100979Srwatson 3251105694Srwatson error = mac_check_structmac_consistent(mac); 3252105694Srwatson if (error) 3253105694Srwatson return (error); 3254105694Srwatson 3255105694Srwatson elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3256105694Srwatson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3257105694Srwatson if (error) { 3258105694Srwatson free(elements, M_MACTEMP); 3259105694Srwatson return (error); 3260105694Srwatson } 3261105694Srwatson 3262105694Srwatson buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3263105694Srwatson error = mac_externalize_socket_peer_label(&so->so_peerlabel, 3264105694Srwatson elements, buffer, mac->m_buflen, M_WAITOK); 3265105694Srwatson if (error == 0) 3266105694Srwatson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3267105694Srwatson 3268105694Srwatson free(buffer, M_MACTEMP); 3269105694Srwatson free(elements, M_MACTEMP); 3270105694Srwatson 3271105694Srwatson return (error); 3272100979Srwatson} 3273100979Srwatson 3274100979Srwatson/* 3275100979Srwatson * Implementation of VOP_SETLABEL() that relies on extended attributes 3276100979Srwatson * to store label data. Can be referenced by filesystems supporting 3277100979Srwatson * extended attributes. 3278100979Srwatson */ 3279100979Srwatsonint 3280100979Srwatsonvop_stdsetlabel_ea(struct vop_setlabel_args *ap) 3281100979Srwatson{ 3282100979Srwatson struct vnode *vp = ap->a_vp; 3283100979Srwatson struct label *intlabel = ap->a_label; 3284100979Srwatson int error; 3285100979Srwatson 3286100979Srwatson ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 3287100979Srwatson 3288105988Srwatson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3289105988Srwatson return (EOPNOTSUPP); 3290100979Srwatson 3291105988Srwatson error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel); 3292100979Srwatson if (error) 3293100979Srwatson return (error); 3294100979Srwatson 3295100979Srwatson mac_relabel_vnode(ap->a_cred, vp, intlabel); 3296100979Srwatson 3297100979Srwatson return (0); 3298100979Srwatson} 3299100979Srwatson 3300100979Srwatsonstatic int 3301100979Srwatsonvn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 3302100979Srwatson{ 3303100979Srwatson int error; 3304100979Srwatson 3305100979Srwatson if (vp->v_mount == NULL) { 3306100979Srwatson /* printf("vn_setlabel: null v_mount\n"); */ 3307103314Snjl if (vp->v_type != VNON) 3308103314Snjl printf("vn_setlabel: null v_mount with non-VNON\n"); 3309100979Srwatson return (EBADF); 3310100979Srwatson } 3311100979Srwatson 3312100979Srwatson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3313100979Srwatson return (EOPNOTSUPP); 3314100979Srwatson 3315100979Srwatson /* 3316100979Srwatson * Multi-phase commit. First check the policies to confirm the 3317100979Srwatson * change is OK. Then commit via the filesystem. Finally, 3318100979Srwatson * update the actual vnode label. Question: maybe the filesystem 3319100979Srwatson * should update the vnode at the end as part of VOP_SETLABEL()? 3320100979Srwatson */ 3321100979Srwatson error = mac_check_vnode_relabel(cred, vp, intlabel); 3322100979Srwatson if (error) 3323100979Srwatson return (error); 3324100979Srwatson 3325100979Srwatson /* 3326100979Srwatson * VADMIN provides the opportunity for the filesystem to make 3327100979Srwatson * decisions about who is and is not able to modify labels 3328100979Srwatson * and protections on files. This might not be right. We can't 3329100979Srwatson * assume VOP_SETLABEL() will do it, because we might implement 3330100979Srwatson * that as part of vop_stdsetlabel_ea(). 3331100979Srwatson */ 3332100979Srwatson error = VOP_ACCESS(vp, VADMIN, cred, curthread); 3333100979Srwatson if (error) 3334100979Srwatson return (error); 3335100979Srwatson 3336100979Srwatson error = VOP_SETLABEL(vp, intlabel, cred, curthread); 3337100979Srwatson if (error) 3338100979Srwatson return (error); 3339100979Srwatson 3340100979Srwatson return (0); 3341100979Srwatson} 3342100979Srwatson 3343105694Srwatsonint 3344105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3345105694Srwatson{ 3346105694Srwatson char *elements, *buffer; 3347105694Srwatson struct mac mac; 3348105694Srwatson struct proc *tproc; 3349105694Srwatson struct ucred *tcred; 3350105694Srwatson int error; 3351105694Srwatson 3352105694Srwatson error = copyin(SCARG(uap, mac_p), &mac, sizeof(mac)); 3353105694Srwatson if (error) 3354105694Srwatson return (error); 3355105694Srwatson 3356105694Srwatson error = mac_check_structmac_consistent(&mac); 3357105694Srwatson if (error) 3358105694Srwatson return (error); 3359105694Srwatson 3360105694Srwatson tproc = pfind(uap->pid); 3361105694Srwatson if (tproc == NULL) 3362105694Srwatson return (ESRCH); 3363105694Srwatson 3364105694Srwatson tcred = NULL; /* Satisfy gcc. */ 3365105694Srwatson error = p_cansee(td, tproc); 3366105694Srwatson if (error == 0) 3367105694Srwatson tcred = crhold(tproc->p_ucred); 3368105694Srwatson PROC_UNLOCK(tproc); 3369105694Srwatson if (error) 3370105694Srwatson return (error); 3371105694Srwatson 3372105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3373105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3374105694Srwatson if (error) { 3375105694Srwatson free(elements, M_MACTEMP); 3376105694Srwatson crfree(tcred); 3377105694Srwatson return (error); 3378105694Srwatson } 3379105694Srwatson 3380105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3381105694Srwatson error = mac_externalize_cred_label(&tcred->cr_label, elements, 3382105694Srwatson buffer, mac.m_buflen, M_WAITOK); 3383105694Srwatson if (error == 0) 3384105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3385105694Srwatson 3386105694Srwatson free(buffer, M_MACTEMP); 3387105694Srwatson free(elements, M_MACTEMP); 3388105694Srwatson crfree(tcred); 3389105694Srwatson return (error); 3390105694Srwatson} 3391105694Srwatson 3392100979Srwatson/* 3393100979Srwatson * MPSAFE 3394100979Srwatson */ 3395100979Srwatsonint 3396100894Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3397100894Srwatson{ 3398105694Srwatson char *elements, *buffer; 3399105694Srwatson struct mac mac; 3400100979Srwatson int error; 3401100894Srwatson 3402105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3403105694Srwatson if (error) 3404105694Srwatson return (error); 3405105694Srwatson 3406105694Srwatson error = mac_check_structmac_consistent(&mac); 3407105694Srwatson if (error) 3408105694Srwatson return (error); 3409105694Srwatson 3410105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3411105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3412105694Srwatson if (error) { 3413105694Srwatson free(elements, M_MACTEMP); 3414105694Srwatson return (error); 3415105694Srwatson } 3416105694Srwatson 3417105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3418105694Srwatson error = mac_externalize_cred_label(&td->td_ucred->cr_label, 3419105694Srwatson elements, buffer, mac.m_buflen, M_WAITOK); 3420100979Srwatson if (error == 0) 3421105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3422100979Srwatson 3423105694Srwatson free(buffer, M_MACTEMP); 3424105694Srwatson free(elements, M_MACTEMP); 3425100979Srwatson return (error); 3426100979Srwatson} 3427100979Srwatson 3428100979Srwatson/* 3429100979Srwatson * MPSAFE 3430100979Srwatson */ 3431100979Srwatsonint 3432100979Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3433100979Srwatson{ 3434100979Srwatson struct ucred *newcred, *oldcred; 3435105694Srwatson struct label intlabel; 3436100979Srwatson struct proc *p; 3437105694Srwatson struct mac mac; 3438105694Srwatson char *buffer; 3439100979Srwatson int error; 3440100979Srwatson 3441105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3442100979Srwatson if (error) 3443100979Srwatson return (error); 3444100979Srwatson 3445105694Srwatson error = mac_check_structmac_consistent(&mac); 3446100979Srwatson if (error) 3447100979Srwatson return (error); 3448100979Srwatson 3449105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3450105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3451105694Srwatson if (error) { 3452105694Srwatson free(buffer, M_MACTEMP); 3453105694Srwatson return (error); 3454105694Srwatson } 3455105694Srwatson 3456105694Srwatson mac_init_cred_label(&intlabel); 3457105694Srwatson error = mac_internalize_cred_label(&intlabel, buffer); 3458105694Srwatson free(buffer, M_MACTEMP); 3459105694Srwatson if (error) { 3460105694Srwatson mac_destroy_cred_label(&intlabel); 3461105694Srwatson return (error); 3462105694Srwatson } 3463105694Srwatson 3464100979Srwatson newcred = crget(); 3465100979Srwatson 3466100979Srwatson p = td->td_proc; 3467100979Srwatson PROC_LOCK(p); 3468100979Srwatson oldcred = p->p_ucred; 3469100979Srwatson 3470100979Srwatson error = mac_check_cred_relabel(oldcred, &intlabel); 3471100979Srwatson if (error) { 3472100979Srwatson PROC_UNLOCK(p); 3473100979Srwatson crfree(newcred); 3474105694Srwatson goto out; 3475100979Srwatson } 3476100979Srwatson 3477100979Srwatson setsugid(p); 3478100979Srwatson crcopy(newcred, oldcred); 3479100979Srwatson mac_relabel_cred(newcred, &intlabel); 3480102136Srwatson p->p_ucred = newcred; 3481100979Srwatson 3482102136Srwatson /* 3483102136Srwatson * Grab additional reference for use while revoking mmaps, prior 3484102136Srwatson * to releasing the proc lock and sharing the cred. 3485102136Srwatson */ 3486102136Srwatson crhold(newcred); 3487100979Srwatson PROC_UNLOCK(p); 3488102136Srwatson 3489105694Srwatson if (mac_enforce_vm) { 3490105694Srwatson mtx_lock(&Giant); 3491105694Srwatson mac_cred_mmapped_drop_perms(td, newcred); 3492105694Srwatson mtx_unlock(&Giant); 3493105694Srwatson } 3494102136Srwatson 3495102136Srwatson crfree(newcred); /* Free revocation reference. */ 3496100979Srwatson crfree(oldcred); 3497105694Srwatson 3498105694Srwatsonout: 3499105694Srwatson mac_destroy_cred_label(&intlabel); 3500105694Srwatson return (error); 3501100979Srwatson} 3502100979Srwatson 3503100979Srwatson/* 3504100979Srwatson * MPSAFE 3505100979Srwatson */ 3506100979Srwatsonint 3507100979Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3508100979Srwatson{ 3509105694Srwatson char *elements, *buffer; 3510105694Srwatson struct label intlabel; 3511100979Srwatson struct file *fp; 3512105694Srwatson struct mac mac; 3513100979Srwatson struct vnode *vp; 3514100979Srwatson struct pipe *pipe; 3515105694Srwatson short label_type; 3516100979Srwatson int error; 3517100979Srwatson 3518105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3519105694Srwatson if (error) 3520105694Srwatson return (error); 3521100979Srwatson 3522105694Srwatson error = mac_check_structmac_consistent(&mac); 3523105694Srwatson if (error) 3524105694Srwatson return (error); 3525105694Srwatson 3526105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3527105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3528105694Srwatson if (error) { 3529105694Srwatson free(elements, M_MACTEMP); 3530105694Srwatson return (error); 3531105694Srwatson } 3532105694Srwatson 3533105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3534105694Srwatson mtx_lock(&Giant); /* VFS */ 3535100979Srwatson error = fget(td, SCARG(uap, fd), &fp); 3536100979Srwatson if (error) 3537100979Srwatson goto out; 3538100979Srwatson 3539105694Srwatson label_type = fp->f_type; 3540100979Srwatson switch (fp->f_type) { 3541100979Srwatson case DTYPE_FIFO: 3542100979Srwatson case DTYPE_VNODE: 3543100979Srwatson vp = (struct vnode *)fp->f_data; 3544100979Srwatson 3545105694Srwatson mac_init_vnode_label(&intlabel); 3546105694Srwatson 3547100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3548105988Srwatson mac_copy_vnode_label(&vp->v_label, &intlabel); 3549100979Srwatson VOP_UNLOCK(vp, 0, td); 3550105694Srwatson 3551100979Srwatson break; 3552100979Srwatson case DTYPE_PIPE: 3553100979Srwatson pipe = (struct pipe *)fp->f_data; 3554105694Srwatson 3555105694Srwatson mac_init_pipe_label(&intlabel); 3556105694Srwatson 3557105694Srwatson PIPE_LOCK(pipe); 3558105694Srwatson mac_copy_pipe_label(pipe->pipe_label, &intlabel); 3559105694Srwatson PIPE_UNLOCK(pipe); 3560100979Srwatson break; 3561100979Srwatson default: 3562100979Srwatson error = EINVAL; 3563105694Srwatson fdrop(fp, td); 3564105694Srwatson goto out; 3565100979Srwatson } 3566105694Srwatson fdrop(fp, td); 3567100979Srwatson 3568105694Srwatson switch (label_type) { 3569105694Srwatson case DTYPE_FIFO: 3570105694Srwatson case DTYPE_VNODE: 3571105694Srwatson if (error == 0) 3572105694Srwatson error = mac_externalize_vnode_label(&intlabel, 3573105694Srwatson elements, buffer, mac.m_buflen, M_WAITOK); 3574105694Srwatson mac_destroy_vnode_label(&intlabel); 3575105694Srwatson break; 3576105694Srwatson case DTYPE_PIPE: 3577105694Srwatson error = mac_externalize_pipe_label(&intlabel, elements, 3578105694Srwatson buffer, mac.m_buflen, M_WAITOK); 3579105694Srwatson mac_destroy_pipe_label(&intlabel); 3580105694Srwatson break; 3581105694Srwatson default: 3582105694Srwatson panic("__mac_get_fd: corrupted label_type"); 3583105694Srwatson } 3584105694Srwatson 3585100979Srwatson if (error == 0) 3586105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3587100979Srwatson 3588105694Srwatsonout: 3589105694Srwatson mtx_unlock(&Giant); /* VFS */ 3590105694Srwatson free(buffer, M_MACTEMP); 3591105694Srwatson free(elements, M_MACTEMP); 3592100979Srwatson 3593100979Srwatson return (error); 3594100979Srwatson} 3595100979Srwatson 3596100979Srwatson/* 3597100979Srwatson * MPSAFE 3598100979Srwatson */ 3599100979Srwatsonint 3600100979Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3601100979Srwatson{ 3602105694Srwatson char *elements, *buffer; 3603100979Srwatson struct nameidata nd; 3604105694Srwatson struct label intlabel; 3605105694Srwatson struct mac mac; 3606100979Srwatson int error; 3607100979Srwatson 3608105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3609105694Srwatson if (error) 3610105694Srwatson return (error); 3611105694Srwatson 3612105694Srwatson error = mac_check_structmac_consistent(&mac); 3613105694Srwatson if (error) 3614105694Srwatson return (error); 3615105694Srwatson 3616105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3617105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3618105694Srwatson if (error) { 3619105694Srwatson free(elements, M_MACTEMP); 3620105694Srwatson return (error); 3621105694Srwatson } 3622105694Srwatson 3623105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3624105694Srwatson mtx_lock(&Giant); /* VFS */ 3625105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3626105694Srwatson td); 3627100979Srwatson error = namei(&nd); 3628100979Srwatson if (error) 3629100979Srwatson goto out; 3630100979Srwatson 3631105694Srwatson mac_init_vnode_label(&intlabel); 3632105988Srwatson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3633105988Srwatson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3634105988Srwatson mac.m_buflen, M_WAITOK); 3635105694Srwatson 3636100979Srwatson NDFREE(&nd, 0); 3637105694Srwatson mac_destroy_vnode_label(&intlabel); 3638105694Srwatson 3639105694Srwatson if (error == 0) 3640105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3641105694Srwatson 3642105694Srwatsonout: 3643105694Srwatson mtx_unlock(&Giant); /* VFS */ 3644105694Srwatson 3645105694Srwatson free(buffer, M_MACTEMP); 3646105694Srwatson free(elements, M_MACTEMP); 3647105694Srwatson 3648105694Srwatson return (error); 3649105694Srwatson} 3650105694Srwatson 3651105694Srwatson/* 3652105694Srwatson * MPSAFE 3653105694Srwatson */ 3654105694Srwatsonint 3655105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3656105694Srwatson{ 3657105694Srwatson char *elements, *buffer; 3658105694Srwatson struct nameidata nd; 3659105694Srwatson struct label intlabel; 3660105694Srwatson struct mac mac; 3661105694Srwatson int error; 3662105694Srwatson 3663105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3664100979Srwatson if (error) 3665105694Srwatson return (error); 3666105694Srwatson 3667105694Srwatson error = mac_check_structmac_consistent(&mac); 3668105694Srwatson if (error) 3669105694Srwatson return (error); 3670105694Srwatson 3671105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3672105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3673105694Srwatson if (error) { 3674105694Srwatson free(elements, M_MACTEMP); 3675105694Srwatson return (error); 3676105694Srwatson } 3677105694Srwatson 3678105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3679105694Srwatson mtx_lock(&Giant); /* VFS */ 3680105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3681105694Srwatson td); 3682105694Srwatson error = namei(&nd); 3683105694Srwatson if (error) 3684100979Srwatson goto out; 3685100979Srwatson 3686105694Srwatson mac_init_vnode_label(&intlabel); 3687105988Srwatson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3688105988Srwatson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3689105988Srwatson mac.m_buflen, M_WAITOK); 3690105694Srwatson NDFREE(&nd, 0); 3691105694Srwatson mac_destroy_vnode_label(&intlabel); 3692100979Srwatson 3693105694Srwatson if (error == 0) 3694105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3695105694Srwatson 3696100979Srwatsonout: 3697105694Srwatson mtx_unlock(&Giant); /* VFS */ 3698105694Srwatson 3699105694Srwatson free(buffer, M_MACTEMP); 3700105694Srwatson free(elements, M_MACTEMP); 3701105694Srwatson 3702100979Srwatson return (error); 3703100979Srwatson} 3704100979Srwatson 3705100979Srwatson/* 3706100979Srwatson * MPSAFE 3707100979Srwatson */ 3708100979Srwatsonint 3709100979Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3710100979Srwatson{ 3711105694Srwatson struct label intlabel; 3712105694Srwatson struct pipe *pipe; 3713100979Srwatson struct file *fp; 3714100979Srwatson struct mount *mp; 3715100979Srwatson struct vnode *vp; 3716105694Srwatson struct mac mac; 3717105694Srwatson char *buffer; 3718100979Srwatson int error; 3719100979Srwatson 3720105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3721100979Srwatson if (error) 3722105694Srwatson return (error); 3723100979Srwatson 3724105694Srwatson error = mac_check_structmac_consistent(&mac); 3725100979Srwatson if (error) 3726105694Srwatson return (error); 3727100979Srwatson 3728105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3729105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3730105694Srwatson if (error) { 3731105694Srwatson free(buffer, M_MACTEMP); 3732105694Srwatson return (error); 3733105694Srwatson } 3734105694Srwatson 3735105694Srwatson mtx_lock(&Giant); /* VFS */ 3736105694Srwatson 3737105694Srwatson error = fget(td, SCARG(uap, fd), &fp); 3738100979Srwatson if (error) 3739105694Srwatson goto out; 3740100979Srwatson 3741100979Srwatson switch (fp->f_type) { 3742100979Srwatson case DTYPE_FIFO: 3743100979Srwatson case DTYPE_VNODE: 3744105694Srwatson mac_init_vnode_label(&intlabel); 3745105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3746105694Srwatson if (error) { 3747105694Srwatson mac_destroy_vnode_label(&intlabel); 3748105694Srwatson break; 3749105694Srwatson } 3750105694Srwatson 3751100979Srwatson vp = (struct vnode *)fp->f_data; 3752100979Srwatson error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3753105694Srwatson if (error != 0) { 3754105694Srwatson mac_destroy_vnode_label(&intlabel); 3755100979Srwatson break; 3756105694Srwatson } 3757100979Srwatson 3758100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3759100979Srwatson error = vn_setlabel(vp, &intlabel, td->td_ucred); 3760100979Srwatson VOP_UNLOCK(vp, 0, td); 3761100979Srwatson vn_finished_write(mp); 3762105694Srwatson 3763105694Srwatson mac_destroy_vnode_label(&intlabel); 3764100979Srwatson break; 3765105694Srwatson 3766100979Srwatson case DTYPE_PIPE: 3767105694Srwatson mac_init_pipe_label(&intlabel); 3768105694Srwatson error = mac_internalize_pipe_label(&intlabel, buffer); 3769105694Srwatson if (error == 0) { 3770105694Srwatson pipe = (struct pipe *)fp->f_data; 3771105694Srwatson PIPE_LOCK(pipe); 3772105694Srwatson error = mac_pipe_label_set(td->td_ucred, pipe, 3773105694Srwatson &intlabel); 3774105694Srwatson PIPE_UNLOCK(pipe); 3775105694Srwatson } 3776105694Srwatson 3777105694Srwatson mac_destroy_pipe_label(&intlabel); 3778100979Srwatson break; 3779105694Srwatson 3780100979Srwatson default: 3781100979Srwatson error = EINVAL; 3782100979Srwatson } 3783100979Srwatson 3784100979Srwatson fdrop(fp, td); 3785105694Srwatsonout: 3786105694Srwatson mtx_unlock(&Giant); /* VFS */ 3787105694Srwatson 3788105694Srwatson free(buffer, M_MACTEMP); 3789105694Srwatson 3790100979Srwatson return (error); 3791100979Srwatson} 3792100979Srwatson 3793100979Srwatson/* 3794100979Srwatson * MPSAFE 3795100979Srwatson */ 3796100979Srwatsonint 3797100979Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3798100979Srwatson{ 3799105694Srwatson struct label intlabel; 3800100979Srwatson struct nameidata nd; 3801100979Srwatson struct mount *mp; 3802105694Srwatson struct mac mac; 3803105694Srwatson char *buffer; 3804100979Srwatson int error; 3805100979Srwatson 3806105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3807100979Srwatson if (error) 3808105694Srwatson return (error); 3809100979Srwatson 3810105694Srwatson error = mac_check_structmac_consistent(&mac); 3811100979Srwatson if (error) 3812105694Srwatson return (error); 3813100979Srwatson 3814105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3815105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3816105694Srwatson if (error) { 3817105694Srwatson free(buffer, M_MACTEMP); 3818105694Srwatson return (error); 3819105694Srwatson } 3820105694Srwatson 3821105694Srwatson mac_init_vnode_label(&intlabel); 3822105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3823105694Srwatson free(buffer, M_MACTEMP); 3824105694Srwatson if (error) { 3825105694Srwatson mac_destroy_vnode_label(&intlabel); 3826105694Srwatson return (error); 3827105694Srwatson } 3828105694Srwatson 3829105694Srwatson mtx_lock(&Giant); /* VFS */ 3830105694Srwatson 3831105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3832105694Srwatson td); 3833100979Srwatson error = namei(&nd); 3834105694Srwatson if (error == 0) { 3835105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3836105694Srwatson if (error == 0) 3837105694Srwatson error = vn_setlabel(nd.ni_vp, &intlabel, 3838105694Srwatson td->td_ucred); 3839105694Srwatson vn_finished_write(mp); 3840105694Srwatson } 3841105694Srwatson 3842105694Srwatson NDFREE(&nd, 0); 3843105694Srwatson mtx_unlock(&Giant); /* VFS */ 3844105694Srwatson mac_destroy_vnode_label(&intlabel); 3845105694Srwatson 3846105694Srwatson return (error); 3847105694Srwatson} 3848105694Srwatson 3849105694Srwatson/* 3850105694Srwatson * MPSAFE 3851105694Srwatson */ 3852105694Srwatsonint 3853105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3854105694Srwatson{ 3855105694Srwatson struct label intlabel; 3856105694Srwatson struct nameidata nd; 3857105694Srwatson struct mount *mp; 3858105694Srwatson struct mac mac; 3859105694Srwatson char *buffer; 3860105694Srwatson int error; 3861105694Srwatson 3862105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3863100979Srwatson if (error) 3864105694Srwatson return (error); 3865105694Srwatson 3866105694Srwatson error = mac_check_structmac_consistent(&mac); 3867100979Srwatson if (error) 3868105694Srwatson return (error); 3869100979Srwatson 3870105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3871105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3872105694Srwatson if (error) { 3873105694Srwatson free(buffer, M_MACTEMP); 3874105694Srwatson return (error); 3875105694Srwatson } 3876105694Srwatson 3877105694Srwatson mac_init_vnode_label(&intlabel); 3878105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3879105694Srwatson free(buffer, M_MACTEMP); 3880105694Srwatson if (error) { 3881105694Srwatson mac_destroy_vnode_label(&intlabel); 3882105694Srwatson return (error); 3883105694Srwatson } 3884105694Srwatson 3885105694Srwatson mtx_lock(&Giant); /* VFS */ 3886105694Srwatson 3887105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3888105694Srwatson td); 3889105694Srwatson error = namei(&nd); 3890105694Srwatson if (error == 0) { 3891105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3892105694Srwatson if (error == 0) 3893105694Srwatson error = vn_setlabel(nd.ni_vp, &intlabel, 3894105694Srwatson td->td_ucred); 3895105694Srwatson vn_finished_write(mp); 3896105694Srwatson } 3897105694Srwatson 3898100979Srwatson NDFREE(&nd, 0); 3899105694Srwatson mtx_unlock(&Giant); /* VFS */ 3900105694Srwatson mac_destroy_vnode_label(&intlabel); 3901105694Srwatson 3902100979Srwatson return (error); 3903100979Srwatson} 3904100979Srwatson 3905105694Srwatson/* 3906105694Srwatson * MPSAFE 3907105694Srwatson */ 3908102123Srwatsonint 3909102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap) 3910102123Srwatson{ 3911102123Srwatson struct mac_policy_conf *mpc; 3912102123Srwatson char target[MAC_MAX_POLICY_NAME]; 3913102123Srwatson int error; 3914102123Srwatson 3915102123Srwatson error = copyinstr(SCARG(uap, policy), target, sizeof(target), NULL); 3916102123Srwatson if (error) 3917102123Srwatson return (error); 3918102123Srwatson 3919102123Srwatson error = ENOSYS; 3920102123Srwatson MAC_POLICY_LIST_BUSY(); 3921102123Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3922102123Srwatson if (strcmp(mpc->mpc_name, target) == 0 && 3923102123Srwatson mpc->mpc_ops->mpo_syscall != NULL) { 3924102123Srwatson error = mpc->mpc_ops->mpo_syscall(td, 3925102123Srwatson SCARG(uap, call), SCARG(uap, arg)); 3926102123Srwatson goto out; 3927102123Srwatson } 3928102123Srwatson } 3929102123Srwatson 3930102123Srwatsonout: 3931102123Srwatson MAC_POLICY_LIST_UNBUSY(); 3932102123Srwatson return (error); 3933102123Srwatson} 3934102123Srwatson 3935100979SrwatsonSYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3936100979SrwatsonSYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3937100979Srwatson 3938100979Srwatson#else /* !MAC */ 3939100979Srwatson 3940100979Srwatsonint 3941105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3942105694Srwatson{ 3943105694Srwatson 3944105694Srwatson return (ENOSYS); 3945105694Srwatson} 3946105694Srwatson 3947105694Srwatsonint 3948100979Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3949100979Srwatson{ 3950100979Srwatson 3951100894Srwatson return (ENOSYS); 3952100894Srwatson} 3953100894Srwatson 3954100894Srwatsonint 3955100894Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3956100894Srwatson{ 3957100894Srwatson 3958100894Srwatson return (ENOSYS); 3959100894Srwatson} 3960100894Srwatson 3961100894Srwatsonint 3962100894Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3963100894Srwatson{ 3964100894Srwatson 3965100894Srwatson return (ENOSYS); 3966100894Srwatson} 3967100894Srwatson 3968100894Srwatsonint 3969100894Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3970100894Srwatson{ 3971100894Srwatson 3972100894Srwatson return (ENOSYS); 3973100894Srwatson} 3974100894Srwatson 3975100894Srwatsonint 3976105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3977105694Srwatson{ 3978105694Srwatson 3979105694Srwatson return (ENOSYS); 3980105694Srwatson} 3981105694Srwatson 3982105694Srwatsonint 3983100894Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3984100894Srwatson{ 3985100894Srwatson 3986100894Srwatson return (ENOSYS); 3987100894Srwatson} 3988100894Srwatson 3989100894Srwatsonint 3990100894Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3991100894Srwatson{ 3992100894Srwatson 3993100894Srwatson return (ENOSYS); 3994100894Srwatson} 3995100979Srwatson 3996102123Srwatsonint 3997105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3998105694Srwatson{ 3999105694Srwatson 4000105694Srwatson return (ENOSYS); 4001105694Srwatson} 4002105694Srwatson 4003105694Srwatsonint 4004102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap) 4005102123Srwatson{ 4006102123Srwatson 4007102123Srwatson return (ENOSYS); 4008102123Srwatson} 4009102123Srwatson 4010105694Srwatson#endif 4011