mac_cred.c revision 106045
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 106045 2002-10-27 15:50:49Z 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 144100979Srwatsonstatic int mac_enforce_socket = 1; 145100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 146100979Srwatson &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 147100979SrwatsonTUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 148100979Srwatson 149106045Srwatsonstatic int mac_enforce_system = 1; 150106045SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_system, CTLFLAG_RW, 151106045Srwatson &mac_enforce_system, 0, "Enforce MAC policy on system operations"); 152106045SrwatsonTUNABLE_INT("security.mac.enforce_system", &mac_enforce_system); 153106025Srwatson 154106045Srwatsonstatic 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; 915106025Srwatson case MAC_CHECK_SYSTEM_SYSCTL: 916106025Srwatson mpc->mpc_ops->mpo_check_system_sysctl = 917106025Srwatson mpe->mpe_function; 918106025Srwatson break; 919100979Srwatson case MAC_CHECK_VNODE_ACCESS: 920100979Srwatson mpc->mpc_ops->mpo_check_vnode_access = 921100979Srwatson mpe->mpe_function; 922100979Srwatson break; 923100979Srwatson case MAC_CHECK_VNODE_CHDIR: 924100979Srwatson mpc->mpc_ops->mpo_check_vnode_chdir = 925100979Srwatson mpe->mpe_function; 926100979Srwatson break; 927100979Srwatson case MAC_CHECK_VNODE_CHROOT: 928100979Srwatson mpc->mpc_ops->mpo_check_vnode_chroot = 929100979Srwatson mpe->mpe_function; 930100979Srwatson break; 931100979Srwatson case MAC_CHECK_VNODE_CREATE: 932100979Srwatson mpc->mpc_ops->mpo_check_vnode_create = 933100979Srwatson mpe->mpe_function; 934100979Srwatson break; 935100979Srwatson case MAC_CHECK_VNODE_DELETE: 936100979Srwatson mpc->mpc_ops->mpo_check_vnode_delete = 937100979Srwatson mpe->mpe_function; 938100979Srwatson break; 939100979Srwatson case MAC_CHECK_VNODE_DELETEACL: 940100979Srwatson mpc->mpc_ops->mpo_check_vnode_deleteacl = 941100979Srwatson mpe->mpe_function; 942100979Srwatson break; 943100979Srwatson case MAC_CHECK_VNODE_EXEC: 944100979Srwatson mpc->mpc_ops->mpo_check_vnode_exec = 945100979Srwatson mpe->mpe_function; 946100979Srwatson break; 947100979Srwatson case MAC_CHECK_VNODE_GETACL: 948100979Srwatson mpc->mpc_ops->mpo_check_vnode_getacl = 949100979Srwatson mpe->mpe_function; 950100979Srwatson break; 951100979Srwatson case MAC_CHECK_VNODE_GETEXTATTR: 952100979Srwatson mpc->mpc_ops->mpo_check_vnode_getextattr = 953100979Srwatson mpe->mpe_function; 954100979Srwatson break; 955104529Srwatson case MAC_CHECK_VNODE_LINK: 956104529Srwatson mpc->mpc_ops->mpo_check_vnode_link = 957104529Srwatson mpe->mpe_function; 958104529Srwatson break; 959100979Srwatson case MAC_CHECK_VNODE_LOOKUP: 960100979Srwatson mpc->mpc_ops->mpo_check_vnode_lookup = 961100979Srwatson mpe->mpe_function; 962100979Srwatson break; 963104546Srwatson case MAC_CHECK_VNODE_MMAP: 964104546Srwatson mpc->mpc_ops->mpo_check_vnode_mmap = 965100979Srwatson mpe->mpe_function; 966100979Srwatson break; 967104546Srwatson case MAC_CHECK_VNODE_MMAP_DOWNGRADE: 968104546Srwatson mpc->mpc_ops->mpo_check_vnode_mmap_downgrade = 969104546Srwatson mpe->mpe_function; 970104546Srwatson break; 971104546Srwatson case MAC_CHECK_VNODE_MPROTECT: 972104546Srwatson mpc->mpc_ops->mpo_check_vnode_mprotect = 973104546Srwatson mpe->mpe_function; 974104546Srwatson break; 975100979Srwatson case MAC_CHECK_VNODE_OPEN: 976100979Srwatson mpc->mpc_ops->mpo_check_vnode_open = 977100979Srwatson mpe->mpe_function; 978100979Srwatson break; 979102112Srwatson case MAC_CHECK_VNODE_POLL: 980102112Srwatson mpc->mpc_ops->mpo_check_vnode_poll = 981102112Srwatson mpe->mpe_function; 982102112Srwatson break; 983102112Srwatson case MAC_CHECK_VNODE_READ: 984102112Srwatson mpc->mpc_ops->mpo_check_vnode_read = 985102112Srwatson mpe->mpe_function; 986102112Srwatson break; 987100979Srwatson case MAC_CHECK_VNODE_READDIR: 988100979Srwatson mpc->mpc_ops->mpo_check_vnode_readdir = 989100979Srwatson mpe->mpe_function; 990100979Srwatson break; 991100979Srwatson case MAC_CHECK_VNODE_READLINK: 992100979Srwatson mpc->mpc_ops->mpo_check_vnode_readlink = 993100979Srwatson mpe->mpe_function; 994100979Srwatson break; 995100979Srwatson case MAC_CHECK_VNODE_RELABEL: 996100979Srwatson mpc->mpc_ops->mpo_check_vnode_relabel = 997100979Srwatson mpe->mpe_function; 998100979Srwatson break; 999100979Srwatson case MAC_CHECK_VNODE_RENAME_FROM: 1000100979Srwatson mpc->mpc_ops->mpo_check_vnode_rename_from = 1001100979Srwatson mpe->mpe_function; 1002100979Srwatson break; 1003100979Srwatson case MAC_CHECK_VNODE_RENAME_TO: 1004100979Srwatson mpc->mpc_ops->mpo_check_vnode_rename_to = 1005100979Srwatson mpe->mpe_function; 1006100979Srwatson break; 1007100979Srwatson case MAC_CHECK_VNODE_REVOKE: 1008100979Srwatson mpc->mpc_ops->mpo_check_vnode_revoke = 1009100979Srwatson mpe->mpe_function; 1010100979Srwatson break; 1011100979Srwatson case MAC_CHECK_VNODE_SETACL: 1012100979Srwatson mpc->mpc_ops->mpo_check_vnode_setacl = 1013100979Srwatson mpe->mpe_function; 1014100979Srwatson break; 1015100979Srwatson case MAC_CHECK_VNODE_SETEXTATTR: 1016100979Srwatson mpc->mpc_ops->mpo_check_vnode_setextattr = 1017100979Srwatson mpe->mpe_function; 1018100979Srwatson break; 1019100979Srwatson case MAC_CHECK_VNODE_SETFLAGS: 1020100979Srwatson mpc->mpc_ops->mpo_check_vnode_setflags = 1021100979Srwatson mpe->mpe_function; 1022100979Srwatson break; 1023100979Srwatson case MAC_CHECK_VNODE_SETMODE: 1024100979Srwatson mpc->mpc_ops->mpo_check_vnode_setmode = 1025100979Srwatson mpe->mpe_function; 1026100979Srwatson break; 1027100979Srwatson case MAC_CHECK_VNODE_SETOWNER: 1028100979Srwatson mpc->mpc_ops->mpo_check_vnode_setowner = 1029100979Srwatson mpe->mpe_function; 1030100979Srwatson break; 1031100979Srwatson case MAC_CHECK_VNODE_SETUTIMES: 1032100979Srwatson mpc->mpc_ops->mpo_check_vnode_setutimes = 1033100979Srwatson mpe->mpe_function; 1034100979Srwatson break; 1035100979Srwatson case MAC_CHECK_VNODE_STAT: 1036100979Srwatson mpc->mpc_ops->mpo_check_vnode_stat = 1037100979Srwatson mpe->mpe_function; 1038100979Srwatson break; 1039102112Srwatson case MAC_CHECK_VNODE_WRITE: 1040102112Srwatson mpc->mpc_ops->mpo_check_vnode_write = 1041102112Srwatson mpe->mpe_function; 1042102112Srwatson break; 1043100979Srwatson/* 1044100979Srwatson default: 1045100979Srwatson printf("MAC policy `%s': unknown operation %d\n", 1046100979Srwatson mpc->mpc_name, mpe->mpe_constant); 1047100979Srwatson return (EINVAL); 1048100979Srwatson*/ 1049100979Srwatson } 1050100979Srwatson } 1051100979Srwatson MAC_POLICY_LIST_LOCK(); 1052100979Srwatson if (mac_policy_list_busy > 0) { 1053100979Srwatson MAC_POLICY_LIST_UNLOCK(); 1054100979Srwatson FREE(mpc->mpc_ops, M_MACOPVEC); 1055100979Srwatson mpc->mpc_ops = NULL; 1056100979Srwatson return (EBUSY); 1057100979Srwatson } 1058100979Srwatson LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 1059100979Srwatson if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 1060100979Srwatson MAC_POLICY_LIST_UNLOCK(); 1061100979Srwatson FREE(mpc->mpc_ops, M_MACOPVEC); 1062100979Srwatson mpc->mpc_ops = NULL; 1063100979Srwatson return (EEXIST); 1064100979Srwatson } 1065100979Srwatson } 1066100979Srwatson if (mpc->mpc_field_off != NULL) { 1067100979Srwatson slot = ffs(mac_policy_offsets_free); 1068100979Srwatson if (slot == 0) { 1069100979Srwatson MAC_POLICY_LIST_UNLOCK(); 1070100979Srwatson FREE(mpc->mpc_ops, M_MACOPVEC); 1071100979Srwatson mpc->mpc_ops = NULL; 1072100979Srwatson return (ENOMEM); 1073100979Srwatson } 1074100979Srwatson slot--; 1075100979Srwatson mac_policy_offsets_free &= ~(1 << slot); 1076100979Srwatson *mpc->mpc_field_off = slot; 1077100979Srwatson } 1078100979Srwatson mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; 1079100979Srwatson LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); 1080100979Srwatson 1081100979Srwatson /* Per-policy initialization. */ 1082100979Srwatson if (mpc->mpc_ops->mpo_init != NULL) 1083100979Srwatson (*(mpc->mpc_ops->mpo_init))(mpc); 1084100979Srwatson MAC_POLICY_LIST_UNLOCK(); 1085100979Srwatson 1086100979Srwatson printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, 1087100979Srwatson mpc->mpc_name); 1088100979Srwatson 1089100979Srwatson return (0); 1090100979Srwatson} 1091100979Srwatson 1092100979Srwatsonstatic int 1093100979Srwatsonmac_policy_unregister(struct mac_policy_conf *mpc) 1094100979Srwatson{ 1095100979Srwatson 1096104520Srwatson /* 1097104520Srwatson * If we fail the load, we may get a request to unload. Check 1098104520Srwatson * to see if we did the run-time registration, and if not, 1099104520Srwatson * silently succeed. 1100104520Srwatson */ 1101104520Srwatson MAC_POLICY_LIST_LOCK(); 1102104520Srwatson if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) { 1103104520Srwatson MAC_POLICY_LIST_UNLOCK(); 1104104520Srwatson return (0); 1105104520Srwatson } 1106100979Srwatson#if 0 1107100979Srwatson /* 1108100979Srwatson * Don't allow unloading modules with private data. 1109100979Srwatson */ 1110104520Srwatson if (mpc->mpc_field_off != NULL) { 1111104520Srwatson MAC_POLICY_LIST_UNLOCK(); 1112100979Srwatson return (EBUSY); 1113104520Srwatson } 1114100979Srwatson#endif 1115104520Srwatson /* 1116104520Srwatson * Only allow the unload to proceed if the module is unloadable 1117104520Srwatson * by its own definition. 1118104520Srwatson */ 1119104520Srwatson if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) { 1120104520Srwatson MAC_POLICY_LIST_UNLOCK(); 1121100979Srwatson return (EBUSY); 1122104520Srwatson } 1123104520Srwatson /* 1124104520Srwatson * Right now, we EBUSY if the list is in use. In the future, 1125104520Srwatson * for reliability reasons, we might want to sleep and wakeup 1126104520Srwatson * later to try again. 1127104520Srwatson */ 1128100979Srwatson if (mac_policy_list_busy > 0) { 1129100979Srwatson MAC_POLICY_LIST_UNLOCK(); 1130100979Srwatson return (EBUSY); 1131100979Srwatson } 1132100979Srwatson if (mpc->mpc_ops->mpo_destroy != NULL) 1133100979Srwatson (*(mpc->mpc_ops->mpo_destroy))(mpc); 1134100979Srwatson 1135100979Srwatson LIST_REMOVE(mpc, mpc_list); 1136100979Srwatson MAC_POLICY_LIST_UNLOCK(); 1137100979Srwatson 1138100979Srwatson FREE(mpc->mpc_ops, M_MACOPVEC); 1139100979Srwatson mpc->mpc_ops = NULL; 1140105474Srwatson mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED; 1141100979Srwatson 1142100979Srwatson printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, 1143100979Srwatson mpc->mpc_name); 1144100979Srwatson 1145100979Srwatson return (0); 1146100979Srwatson} 1147100979Srwatson 1148100979Srwatson/* 1149100979Srwatson * Define an error value precedence, and given two arguments, selects the 1150100979Srwatson * value with the higher precedence. 1151100979Srwatson */ 1152100979Srwatsonstatic int 1153100979Srwatsonerror_select(int error1, int error2) 1154100979Srwatson{ 1155100979Srwatson 1156100979Srwatson /* Certain decision-making errors take top priority. */ 1157100979Srwatson if (error1 == EDEADLK || error2 == EDEADLK) 1158100979Srwatson return (EDEADLK); 1159100979Srwatson 1160100979Srwatson /* Invalid arguments should be reported where possible. */ 1161100979Srwatson if (error1 == EINVAL || error2 == EINVAL) 1162100979Srwatson return (EINVAL); 1163100979Srwatson 1164100979Srwatson /* Precedence goes to "visibility", with both process and file. */ 1165100979Srwatson if (error1 == ESRCH || error2 == ESRCH) 1166100979Srwatson return (ESRCH); 1167100979Srwatson 1168100979Srwatson if (error1 == ENOENT || error2 == ENOENT) 1169100979Srwatson return (ENOENT); 1170100979Srwatson 1171100979Srwatson /* Precedence goes to DAC/MAC protections. */ 1172100979Srwatson if (error1 == EACCES || error2 == EACCES) 1173100979Srwatson return (EACCES); 1174100979Srwatson 1175100979Srwatson /* Precedence goes to privilege. */ 1176100979Srwatson if (error1 == EPERM || error2 == EPERM) 1177100979Srwatson return (EPERM); 1178100979Srwatson 1179100979Srwatson /* Precedence goes to error over success; otherwise, arbitrary. */ 1180100979Srwatson if (error1 != 0) 1181100979Srwatson return (error1); 1182100979Srwatson return (error2); 1183100979Srwatson} 1184100979Srwatson 1185104521Srwatsonstatic void 1186104521Srwatsonmac_init_label(struct label *label) 1187104521Srwatson{ 1188104521Srwatson 1189104521Srwatson bzero(label, sizeof(*label)); 1190104521Srwatson label->l_flags = MAC_FLAG_INITIALIZED; 1191104521Srwatson} 1192104521Srwatson 1193104521Srwatsonstatic void 1194104521Srwatsonmac_destroy_label(struct label *label) 1195104521Srwatson{ 1196104521Srwatson 1197104521Srwatson KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 1198104521Srwatson ("destroying uninitialized label")); 1199104521Srwatson 1200104521Srwatson bzero(label, sizeof(*label)); 1201104521Srwatson /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 1202104521Srwatson} 1203104521Srwatson 1204100979Srwatsonvoid 1205104527Srwatsonmac_init_bpfdesc(struct bpf_d *bpf_d) 1206104521Srwatson{ 1207104521Srwatson 1208104527Srwatson mac_init_label(&bpf_d->bd_label); 1209104527Srwatson MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label); 1210104521Srwatson#ifdef MAC_DEBUG 1211104527Srwatson atomic_add_int(&nmacbpfdescs, 1); 1212104521Srwatson#endif 1213104521Srwatson} 1214104521Srwatson 1215105694Srwatsonstatic void 1216105694Srwatsonmac_init_cred_label(struct label *label) 1217104521Srwatson{ 1218104521Srwatson 1219105694Srwatson mac_init_label(label); 1220105694Srwatson MAC_PERFORM(init_cred_label, label); 1221104521Srwatson#ifdef MAC_DEBUG 1222104521Srwatson atomic_add_int(&nmaccreds, 1); 1223104521Srwatson#endif 1224104521Srwatson} 1225104521Srwatson 1226104521Srwatsonvoid 1227105694Srwatsonmac_init_cred(struct ucred *cred) 1228105694Srwatson{ 1229105694Srwatson 1230105694Srwatson mac_init_cred_label(&cred->cr_label); 1231105694Srwatson} 1232105694Srwatson 1233105694Srwatsonvoid 1234104527Srwatsonmac_init_devfsdirent(struct devfs_dirent *de) 1235104521Srwatson{ 1236104521Srwatson 1237104527Srwatson mac_init_label(&de->de_label); 1238104527Srwatson MAC_PERFORM(init_devfsdirent_label, &de->de_label); 1239104521Srwatson#ifdef MAC_DEBUG 1240104527Srwatson atomic_add_int(&nmacdevfsdirents, 1); 1241104521Srwatson#endif 1242104521Srwatson} 1243104521Srwatson 1244105694Srwatsonstatic void 1245105694Srwatsonmac_init_ifnet_label(struct label *label) 1246104521Srwatson{ 1247104521Srwatson 1248105694Srwatson mac_init_label(label); 1249105694Srwatson MAC_PERFORM(init_ifnet_label, label); 1250104521Srwatson#ifdef MAC_DEBUG 1251104521Srwatson atomic_add_int(&nmacifnets, 1); 1252104521Srwatson#endif 1253104521Srwatson} 1254104521Srwatson 1255104521Srwatsonvoid 1256105694Srwatsonmac_init_ifnet(struct ifnet *ifp) 1257105694Srwatson{ 1258105694Srwatson 1259105694Srwatson mac_init_ifnet_label(&ifp->if_label); 1260105694Srwatson} 1261105694Srwatson 1262105694Srwatsonvoid 1263104527Srwatsonmac_init_ipq(struct ipq *ipq) 1264104521Srwatson{ 1265104521Srwatson 1266104527Srwatson mac_init_label(&ipq->ipq_label); 1267104527Srwatson MAC_PERFORM(init_ipq_label, &ipq->ipq_label); 1268104521Srwatson#ifdef MAC_DEBUG 1269104527Srwatson atomic_add_int(&nmacipqs, 1); 1270104521Srwatson#endif 1271104521Srwatson} 1272104521Srwatson 1273104527Srwatsonint 1274104527Srwatsonmac_init_mbuf(struct mbuf *m, int flag) 1275104527Srwatson{ 1276104528Srwatson int error; 1277104528Srwatson 1278104527Srwatson KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf")); 1279104527Srwatson 1280104527Srwatson mac_init_label(&m->m_pkthdr.label); 1281104527Srwatson 1282104528Srwatson MAC_CHECK(init_mbuf_label, &m->m_pkthdr.label, flag); 1283104528Srwatson if (error) { 1284104528Srwatson MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 1285104528Srwatson mac_destroy_label(&m->m_pkthdr.label); 1286104528Srwatson } 1287104528Srwatson 1288104527Srwatson#ifdef MAC_DEBUG 1289104528Srwatson if (error == 0) 1290104528Srwatson atomic_add_int(&nmacmbufs, 1); 1291104527Srwatson#endif 1292104528Srwatson return (error); 1293104527Srwatson} 1294104527Srwatson 1295104521Srwatsonvoid 1296104527Srwatsonmac_init_mount(struct mount *mp) 1297104521Srwatson{ 1298104521Srwatson 1299104527Srwatson mac_init_label(&mp->mnt_mntlabel); 1300104527Srwatson mac_init_label(&mp->mnt_fslabel); 1301104527Srwatson MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel); 1302104527Srwatson MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel); 1303104521Srwatson#ifdef MAC_DEBUG 1304104527Srwatson atomic_add_int(&nmacmounts, 1); 1305104521Srwatson#endif 1306104521Srwatson} 1307104521Srwatson 1308105694Srwatsonstatic void 1309105694Srwatsonmac_init_pipe_label(struct label *label) 1310105694Srwatson{ 1311105694Srwatson 1312105694Srwatson mac_init_label(label); 1313105694Srwatson MAC_PERFORM(init_pipe_label, label); 1314105694Srwatson#ifdef MAC_DEBUG 1315105694Srwatson atomic_add_int(&nmacpipes, 1); 1316105694Srwatson#endif 1317105694Srwatson} 1318105694Srwatson 1319104521Srwatsonvoid 1320104527Srwatsonmac_init_pipe(struct pipe *pipe) 1321104521Srwatson{ 1322104527Srwatson struct label *label; 1323104521Srwatson 1324104527Srwatson label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 1325104527Srwatson pipe->pipe_label = label; 1326104527Srwatson pipe->pipe_peer->pipe_label = label; 1327105694Srwatson mac_init_pipe_label(label); 1328104521Srwatson} 1329104521Srwatson 1330104541Srwatsonstatic int 1331104541Srwatsonmac_init_socket_label(struct label *label, int flag) 1332104521Srwatson{ 1333104541Srwatson int error; 1334104521Srwatson 1335104541Srwatson mac_init_label(label); 1336104541Srwatson 1337104541Srwatson MAC_CHECK(init_socket_label, label, flag); 1338104541Srwatson if (error) { 1339104541Srwatson MAC_PERFORM(destroy_socket_label, label); 1340104541Srwatson mac_destroy_label(label); 1341104541Srwatson } 1342104541Srwatson 1343104521Srwatson#ifdef MAC_DEBUG 1344104541Srwatson if (error == 0) 1345104541Srwatson atomic_add_int(&nmacsockets, 1); 1346104521Srwatson#endif 1347104541Srwatson 1348104541Srwatson return (error); 1349104521Srwatson} 1350104521Srwatson 1351104541Srwatsonstatic int 1352104541Srwatsonmac_init_socket_peer_label(struct label *label, int flag) 1353104541Srwatson{ 1354104541Srwatson int error; 1355104541Srwatson 1356104541Srwatson mac_init_label(label); 1357104541Srwatson 1358104541Srwatson MAC_CHECK(init_socket_peer_label, label, flag); 1359104541Srwatson if (error) { 1360104541Srwatson MAC_PERFORM(destroy_socket_label, label); 1361104541Srwatson mac_destroy_label(label); 1362104541Srwatson } 1363104541Srwatson 1364104541Srwatson return (error); 1365104541Srwatson} 1366104541Srwatson 1367104541Srwatsonint 1368104541Srwatsonmac_init_socket(struct socket *socket, int flag) 1369104541Srwatson{ 1370104541Srwatson int error; 1371104541Srwatson 1372104541Srwatson error = mac_init_socket_label(&socket->so_label, flag); 1373104541Srwatson if (error) 1374104541Srwatson return (error); 1375104541Srwatson 1376104541Srwatson error = mac_init_socket_peer_label(&socket->so_peerlabel, flag); 1377104541Srwatson if (error) 1378104541Srwatson mac_destroy_socket_label(&socket->so_label); 1379104541Srwatson 1380104541Srwatson return (error); 1381104541Srwatson} 1382104541Srwatson 1383105988Srwatsonvoid 1384105694Srwatsonmac_init_vnode_label(struct label *label) 1385104521Srwatson{ 1386104521Srwatson 1387104527Srwatson mac_init_label(label); 1388105694Srwatson MAC_PERFORM(init_vnode_label, label); 1389104521Srwatson#ifdef MAC_DEBUG 1390105694Srwatson atomic_add_int(&nmacvnodes, 1); 1391104521Srwatson#endif 1392104521Srwatson} 1393104521Srwatson 1394104521Srwatsonvoid 1395104527Srwatsonmac_init_vnode(struct vnode *vp) 1396104521Srwatson{ 1397104521Srwatson 1398105694Srwatson mac_init_vnode_label(&vp->v_label); 1399104521Srwatson} 1400104521Srwatson 1401104521Srwatsonvoid 1402104527Srwatsonmac_destroy_bpfdesc(struct bpf_d *bpf_d) 1403104521Srwatson{ 1404104521Srwatson 1405104527Srwatson MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label); 1406104527Srwatson mac_destroy_label(&bpf_d->bd_label); 1407104521Srwatson#ifdef MAC_DEBUG 1408104527Srwatson atomic_subtract_int(&nmacbpfdescs, 1); 1409104521Srwatson#endif 1410104521Srwatson} 1411104521Srwatson 1412105694Srwatsonstatic void 1413105694Srwatsonmac_destroy_cred_label(struct label *label) 1414104521Srwatson{ 1415104521Srwatson 1416105694Srwatson MAC_PERFORM(destroy_cred_label, label); 1417105694Srwatson mac_destroy_label(label); 1418104521Srwatson#ifdef MAC_DEBUG 1419104527Srwatson atomic_subtract_int(&nmaccreds, 1); 1420104521Srwatson#endif 1421104521Srwatson} 1422104521Srwatson 1423104521Srwatsonvoid 1424105694Srwatsonmac_destroy_cred(struct ucred *cred) 1425105694Srwatson{ 1426105694Srwatson 1427105694Srwatson mac_destroy_cred_label(&cred->cr_label); 1428105694Srwatson} 1429105694Srwatson 1430105694Srwatsonvoid 1431104527Srwatsonmac_destroy_devfsdirent(struct devfs_dirent *de) 1432104521Srwatson{ 1433104521Srwatson 1434104527Srwatson MAC_PERFORM(destroy_devfsdirent_label, &de->de_label); 1435104527Srwatson mac_destroy_label(&de->de_label); 1436104521Srwatson#ifdef MAC_DEBUG 1437104527Srwatson atomic_subtract_int(&nmacdevfsdirents, 1); 1438104521Srwatson#endif 1439104521Srwatson} 1440104521Srwatson 1441105694Srwatsonstatic void 1442105694Srwatsonmac_destroy_ifnet_label(struct label *label) 1443104521Srwatson{ 1444104521Srwatson 1445105694Srwatson MAC_PERFORM(destroy_ifnet_label, label); 1446105694Srwatson mac_destroy_label(label); 1447104521Srwatson#ifdef MAC_DEBUG 1448104527Srwatson atomic_subtract_int(&nmacifnets, 1); 1449104521Srwatson#endif 1450104521Srwatson} 1451104521Srwatson 1452104521Srwatsonvoid 1453105694Srwatsonmac_destroy_ifnet(struct ifnet *ifp) 1454105694Srwatson{ 1455105694Srwatson 1456105694Srwatson mac_destroy_ifnet_label(&ifp->if_label); 1457105694Srwatson} 1458105694Srwatson 1459105694Srwatsonvoid 1460104527Srwatsonmac_destroy_ipq(struct ipq *ipq) 1461104521Srwatson{ 1462104521Srwatson 1463104527Srwatson MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 1464104527Srwatson mac_destroy_label(&ipq->ipq_label); 1465104521Srwatson#ifdef MAC_DEBUG 1466104527Srwatson atomic_subtract_int(&nmacipqs, 1); 1467104521Srwatson#endif 1468104521Srwatson} 1469104521Srwatson 1470104527Srwatsonvoid 1471104527Srwatsonmac_destroy_mbuf(struct mbuf *m) 1472104521Srwatson{ 1473104521Srwatson 1474104527Srwatson MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 1475104527Srwatson mac_destroy_label(&m->m_pkthdr.label); 1476104521Srwatson#ifdef MAC_DEBUG 1477104527Srwatson atomic_subtract_int(&nmacmbufs, 1); 1478104521Srwatson#endif 1479104521Srwatson} 1480104521Srwatson 1481104527Srwatsonvoid 1482104527Srwatsonmac_destroy_mount(struct mount *mp) 1483104521Srwatson{ 1484104521Srwatson 1485104527Srwatson MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel); 1486104527Srwatson MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel); 1487104527Srwatson mac_destroy_label(&mp->mnt_fslabel); 1488104527Srwatson mac_destroy_label(&mp->mnt_mntlabel); 1489104521Srwatson#ifdef MAC_DEBUG 1490104527Srwatson atomic_subtract_int(&nmacmounts, 1); 1491104521Srwatson#endif 1492104521Srwatson} 1493104521Srwatson 1494105694Srwatsonstatic void 1495105694Srwatsonmac_destroy_pipe_label(struct label *label) 1496104521Srwatson{ 1497104521Srwatson 1498105694Srwatson MAC_PERFORM(destroy_pipe_label, label); 1499105694Srwatson mac_destroy_label(label); 1500104521Srwatson#ifdef MAC_DEBUG 1501104527Srwatson atomic_subtract_int(&nmacpipes, 1); 1502104521Srwatson#endif 1503104521Srwatson} 1504104521Srwatson 1505105694Srwatsonvoid 1506105694Srwatsonmac_destroy_pipe(struct pipe *pipe) 1507105694Srwatson{ 1508105694Srwatson 1509105694Srwatson mac_destroy_pipe_label(pipe->pipe_label); 1510105694Srwatson free(pipe->pipe_label, M_MACPIPELABEL); 1511105694Srwatson} 1512105694Srwatson 1513104541Srwatsonstatic void 1514104541Srwatsonmac_destroy_socket_label(struct label *label) 1515104521Srwatson{ 1516104521Srwatson 1517104541Srwatson MAC_PERFORM(destroy_socket_label, label); 1518104541Srwatson mac_destroy_label(label); 1519104521Srwatson#ifdef MAC_DEBUG 1520104527Srwatson atomic_subtract_int(&nmacsockets, 1); 1521104521Srwatson#endif 1522104521Srwatson} 1523104521Srwatson 1524104527Srwatsonstatic void 1525104541Srwatsonmac_destroy_socket_peer_label(struct label *label) 1526104541Srwatson{ 1527104541Srwatson 1528104541Srwatson MAC_PERFORM(destroy_socket_peer_label, label); 1529104541Srwatson mac_destroy_label(label); 1530104541Srwatson} 1531104541Srwatson 1532104541Srwatsonvoid 1533104541Srwatsonmac_destroy_socket(struct socket *socket) 1534104541Srwatson{ 1535104541Srwatson 1536104541Srwatson mac_destroy_socket_label(&socket->so_label); 1537104541Srwatson mac_destroy_socket_peer_label(&socket->so_peerlabel); 1538104541Srwatson} 1539104541Srwatson 1540105988Srwatsonvoid 1541105694Srwatsonmac_destroy_vnode_label(struct label *label) 1542104521Srwatson{ 1543104521Srwatson 1544105694Srwatson MAC_PERFORM(destroy_vnode_label, label); 1545104527Srwatson mac_destroy_label(label); 1546104521Srwatson#ifdef MAC_DEBUG 1547105694Srwatson atomic_subtract_int(&nmacvnodes, 1); 1548104521Srwatson#endif 1549104521Srwatson} 1550104521Srwatson 1551104521Srwatsonvoid 1552104527Srwatsonmac_destroy_vnode(struct vnode *vp) 1553104521Srwatson{ 1554104521Srwatson 1555105694Srwatson mac_destroy_vnode_label(&vp->v_label); 1556104521Srwatson} 1557104521Srwatson 1558105694Srwatsonstatic void 1559105694Srwatsonmac_copy_pipe_label(struct label *src, struct label *dest) 1560105694Srwatson{ 1561105694Srwatson 1562105694Srwatson MAC_PERFORM(copy_pipe_label, src, dest); 1563105694Srwatson} 1564105694Srwatson 1565105988Srwatsonvoid 1566105694Srwatsonmac_copy_vnode_label(struct label *src, struct label *dest) 1567105694Srwatson{ 1568105694Srwatson 1569105694Srwatson MAC_PERFORM(copy_vnode_label, src, dest); 1570105694Srwatson} 1571105694Srwatson 1572104522Srwatsonstatic int 1573105694Srwatsonmac_check_structmac_consistent(struct mac *mac) 1574104522Srwatson{ 1575105694Srwatson 1576105694Srwatson if (mac->m_buflen > MAC_MAX_LABEL_BUF_LEN) 1577105694Srwatson return (EINVAL); 1578105694Srwatson 1579105694Srwatson return (0); 1580105694Srwatson} 1581105694Srwatson 1582105694Srwatsonstatic int 1583105694Srwatsonmac_externalize_cred_label(struct label *label, char *elements, 1584105694Srwatson char *outbuf, size_t outbuflen, int flags) 1585105694Srwatson{ 1586104522Srwatson int error; 1587104522Srwatson 1588105694Srwatson MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen); 1589104522Srwatson 1590104522Srwatson return (error); 1591104522Srwatson} 1592104522Srwatson 1593104522Srwatsonstatic int 1594105694Srwatsonmac_externalize_ifnet_label(struct label *label, char *elements, 1595105694Srwatson char *outbuf, size_t outbuflen, int flags) 1596104522Srwatson{ 1597104522Srwatson int error; 1598104522Srwatson 1599105694Srwatson MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen); 1600104522Srwatson 1601104522Srwatson return (error); 1602104522Srwatson} 1603104522Srwatson 1604105694Srwatsonstatic int 1605105694Srwatsonmac_externalize_pipe_label(struct label *label, char *elements, 1606105694Srwatson char *outbuf, size_t outbuflen, int flags) 1607105694Srwatson{ 1608105694Srwatson int error; 1609105694Srwatson 1610105694Srwatson MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen); 1611105694Srwatson 1612105694Srwatson return (error); 1613105694Srwatson} 1614105694Srwatson 1615105694Srwatsonstatic int 1616105694Srwatsonmac_externalize_socket_label(struct label *label, char *elements, 1617105694Srwatson char *outbuf, size_t outbuflen, int flags) 1618105694Srwatson{ 1619105694Srwatson int error; 1620105694Srwatson 1621105694Srwatson MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen); 1622105694Srwatson 1623105694Srwatson return (error); 1624105694Srwatson} 1625105694Srwatson 1626105694Srwatsonstatic int 1627105694Srwatsonmac_externalize_socket_peer_label(struct label *label, char *elements, 1628105694Srwatson char *outbuf, size_t outbuflen, int flags) 1629105694Srwatson{ 1630105694Srwatson int error; 1631105694Srwatson 1632105694Srwatson MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen); 1633105694Srwatson 1634105694Srwatson return (error); 1635105694Srwatson} 1636105694Srwatson 1637105694Srwatsonstatic int 1638105694Srwatsonmac_externalize_vnode_label(struct label *label, char *elements, 1639105694Srwatson char *outbuf, size_t outbuflen, int flags) 1640105694Srwatson{ 1641105694Srwatson int error; 1642105694Srwatson 1643105694Srwatson MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen); 1644105694Srwatson 1645105694Srwatson return (error); 1646105694Srwatson} 1647105694Srwatson 1648105694Srwatsonstatic int 1649105694Srwatsonmac_internalize_cred_label(struct label *label, char *string) 1650105694Srwatson{ 1651105694Srwatson int error; 1652105694Srwatson 1653105694Srwatson MAC_INTERNALIZE(cred_label, label, string); 1654105694Srwatson 1655105694Srwatson return (error); 1656105694Srwatson} 1657105694Srwatson 1658105694Srwatsonstatic int 1659105694Srwatsonmac_internalize_ifnet_label(struct label *label, char *string) 1660105694Srwatson{ 1661105694Srwatson int error; 1662105694Srwatson 1663105694Srwatson MAC_INTERNALIZE(ifnet_label, label, string); 1664105694Srwatson 1665105694Srwatson return (error); 1666105694Srwatson} 1667105694Srwatson 1668105694Srwatsonstatic int 1669105694Srwatsonmac_internalize_pipe_label(struct label *label, char *string) 1670105694Srwatson{ 1671105694Srwatson int error; 1672105694Srwatson 1673105694Srwatson MAC_INTERNALIZE(pipe_label, label, string); 1674105694Srwatson 1675105694Srwatson return (error); 1676105694Srwatson} 1677105694Srwatson 1678105694Srwatsonstatic int 1679105694Srwatsonmac_internalize_socket_label(struct label *label, char *string) 1680105694Srwatson{ 1681105694Srwatson int error; 1682105694Srwatson 1683105694Srwatson MAC_INTERNALIZE(socket_label, label, string); 1684105694Srwatson 1685105694Srwatson return (error); 1686105694Srwatson} 1687105694Srwatson 1688105694Srwatsonstatic int 1689105694Srwatsonmac_internalize_vnode_label(struct label *label, char *string) 1690105694Srwatson{ 1691105694Srwatson int error; 1692105694Srwatson 1693105694Srwatson MAC_INTERNALIZE(vnode_label, label, string); 1694105694Srwatson 1695105694Srwatson return (error); 1696105694Srwatson} 1697105694Srwatson 1698104522Srwatson/* 1699104522Srwatson * Initialize MAC label for the first kernel process, from which other 1700104522Srwatson * kernel processes and threads are spawned. 1701104522Srwatson */ 1702104521Srwatsonvoid 1703104522Srwatsonmac_create_proc0(struct ucred *cred) 1704104522Srwatson{ 1705104522Srwatson 1706104522Srwatson MAC_PERFORM(create_proc0, cred); 1707104522Srwatson} 1708104522Srwatson 1709104522Srwatson/* 1710104522Srwatson * Initialize MAC label for the first userland process, from which other 1711104522Srwatson * userland processes and threads are spawned. 1712104522Srwatson */ 1713104522Srwatsonvoid 1714104522Srwatsonmac_create_proc1(struct ucred *cred) 1715104522Srwatson{ 1716104522Srwatson 1717104522Srwatson MAC_PERFORM(create_proc1, cred); 1718104522Srwatson} 1719104522Srwatson 1720104522Srwatsonvoid 1721104522Srwatsonmac_thread_userret(struct thread *td) 1722104522Srwatson{ 1723104522Srwatson 1724104522Srwatson MAC_PERFORM(thread_userret, td); 1725104522Srwatson} 1726104522Srwatson 1727104522Srwatson/* 1728104522Srwatson * When a new process is created, its label must be initialized. Generally, 1729104522Srwatson * this involves inheritence from the parent process, modulo possible 1730104522Srwatson * deltas. This function allows that processing to take place. 1731104522Srwatson */ 1732104522Srwatsonvoid 1733104522Srwatsonmac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 1734104522Srwatson{ 1735104522Srwatson 1736104522Srwatson MAC_PERFORM(create_cred, parent_cred, child_cred); 1737104522Srwatson} 1738104522Srwatson 1739104522Srwatsonvoid 1740100979Srwatsonmac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp) 1741100979Srwatson{ 1742100979Srwatson 1743100979Srwatson MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label); 1744100979Srwatson} 1745100979Srwatson 1746100979Srwatsonvoid 1747105988Srwatsonmac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, 1748105988Srwatson struct vnode *vp) 1749100979Srwatson{ 1750100979Srwatson 1751105988Srwatson MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de, 1752105988Srwatson &de->de_label, vp, &vp->v_label); 1753100979Srwatson} 1754100979Srwatson 1755105988Srwatsonint 1756105988Srwatsonmac_associate_vnode_extattr(struct mount *mp, struct vnode *vp) 1757100979Srwatson{ 1758100979Srwatson int error; 1759100979Srwatson 1760105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr"); 1761100979Srwatson 1762105988Srwatson MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp, 1763105988Srwatson &vp->v_label); 1764100979Srwatson 1765100979Srwatson return (error); 1766100979Srwatson} 1767100979Srwatson 1768100979Srwatsonvoid 1769105988Srwatsonmac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp) 1770100979Srwatson{ 1771100979Srwatson 1772105988Srwatson MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp, 1773105988Srwatson &vp->v_label); 1774100979Srwatson} 1775100979Srwatson 1776100979Srwatsonint 1777105988Srwatsonmac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1778105988Srwatson struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 1779100979Srwatson{ 1780105988Srwatson int error; 1781100979Srwatson 1782105988Srwatson ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr"); 1783105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr"); 1784100979Srwatson 1785105988Srwatson error = VOP_OPENEXTATTR(vp, cred, curthread); 1786105988Srwatson if (error == EOPNOTSUPP) { 1787105988Srwatson /* XXX: Optionally abort if transactions not supported. */ 1788105988Srwatson if (ea_warn_once == 0) { 1789105988Srwatson printf("Warning: transactions not supported " 1790105988Srwatson "in EA write.\n"); 1791105988Srwatson ea_warn_once = 1; 1792105988Srwatson } 1793105988Srwatson } else if (error) 1794100979Srwatson return (error); 1795100979Srwatson 1796105988Srwatson MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel, 1797105988Srwatson dvp, &dvp->v_label, vp, &vp->v_label, cnp); 1798100979Srwatson 1799105988Srwatson if (error) { 1800105988Srwatson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1801100979Srwatson return (error); 1802100979Srwatson } 1803100979Srwatson 1804105988Srwatson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1805100979Srwatson 1806105988Srwatson if (error == EOPNOTSUPP) 1807105988Srwatson error = 0; /* XXX */ 1808100979Srwatson 1809100979Srwatson return (error); 1810100979Srwatson} 1811100979Srwatson 1812100979Srwatsonstatic int 1813105988Srwatsonmac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1814105988Srwatson struct label *intlabel) 1815100979Srwatson{ 1816100979Srwatson int error; 1817100979Srwatson 1818105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr"); 1819100979Srwatson 1820105988Srwatson error = VOP_OPENEXTATTR(vp, cred, curthread); 1821105988Srwatson if (error == EOPNOTSUPP) { 1822105988Srwatson /* XXX: Optionally abort if transactions not supported. */ 1823105988Srwatson if (ea_warn_once == 0) { 1824105988Srwatson printf("Warning: transactions not supported " 1825105988Srwatson "in EA write.\n"); 1826105988Srwatson ea_warn_once = 1; 1827105988Srwatson } 1828105988Srwatson } else if (error) 1829105988Srwatson return (error); 1830100979Srwatson 1831105988Srwatson MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel); 1832100979Srwatson 1833105988Srwatson if (error) { 1834105988Srwatson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1835100979Srwatson return (error); 1836100979Srwatson } 1837100979Srwatson 1838105988Srwatson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1839100979Srwatson 1840105988Srwatson if (error == EOPNOTSUPP) 1841105988Srwatson error = 0; /* XXX */ 1842100979Srwatson 1843105988Srwatson return (error); 1844100979Srwatson} 1845100979Srwatson 1846100979Srwatsonvoid 1847100979Srwatsonmac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp) 1848100979Srwatson{ 1849100979Srwatson 1850100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1851100979Srwatson 1852100979Srwatson MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label); 1853100979Srwatson} 1854100979Srwatson 1855100979Srwatsonint 1856100979Srwatsonmac_execve_will_transition(struct ucred *old, struct vnode *vp) 1857100979Srwatson{ 1858105988Srwatson int result; 1859100979Srwatson 1860100979Srwatson result = 0; 1861100979Srwatson MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label); 1862100979Srwatson 1863100979Srwatson return (result); 1864100979Srwatson} 1865100979Srwatson 1866100979Srwatsonint 1867100979Srwatsonmac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags) 1868100979Srwatson{ 1869100979Srwatson int error; 1870100979Srwatson 1871100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1872100979Srwatson 1873100979Srwatson if (!mac_enforce_fs) 1874100979Srwatson return (0); 1875100979Srwatson 1876100979Srwatson MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags); 1877100979Srwatson return (error); 1878100979Srwatson} 1879100979Srwatson 1880100979Srwatsonint 1881100979Srwatsonmac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 1882100979Srwatson{ 1883100979Srwatson int error; 1884100979Srwatson 1885100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 1886100979Srwatson 1887100979Srwatson if (!mac_enforce_fs) 1888100979Srwatson return (0); 1889100979Srwatson 1890100979Srwatson MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 1891100979Srwatson return (error); 1892100979Srwatson} 1893100979Srwatson 1894100979Srwatsonint 1895100979Srwatsonmac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 1896100979Srwatson{ 1897100979Srwatson int error; 1898100979Srwatson 1899100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 1900100979Srwatson 1901100979Srwatson if (!mac_enforce_fs) 1902100979Srwatson return (0); 1903100979Srwatson 1904100979Srwatson MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1905100979Srwatson return (error); 1906100979Srwatson} 1907100979Srwatson 1908100979Srwatsonint 1909100979Srwatsonmac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1910100979Srwatson struct componentname *cnp, struct vattr *vap) 1911100979Srwatson{ 1912100979Srwatson int error; 1913100979Srwatson 1914100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1915100979Srwatson 1916100979Srwatson if (!mac_enforce_fs) 1917100979Srwatson return (0); 1918100979Srwatson 1919100979Srwatson MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 1920100979Srwatson return (error); 1921100979Srwatson} 1922100979Srwatson 1923100979Srwatsonint 1924100979Srwatsonmac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 1925100979Srwatson struct componentname *cnp) 1926100979Srwatson{ 1927100979Srwatson int error; 1928100979Srwatson 1929100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 1930100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 1931100979Srwatson 1932100979Srwatson if (!mac_enforce_fs) 1933100979Srwatson return (0); 1934100979Srwatson 1935100979Srwatson MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1936100979Srwatson &vp->v_label, cnp); 1937100979Srwatson return (error); 1938100979Srwatson} 1939100979Srwatson 1940100979Srwatsonint 1941100979Srwatsonmac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1942100979Srwatson acl_type_t type) 1943100979Srwatson{ 1944100979Srwatson int error; 1945100979Srwatson 1946100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1947100979Srwatson 1948100979Srwatson if (!mac_enforce_fs) 1949100979Srwatson return (0); 1950100979Srwatson 1951100979Srwatson MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1952100979Srwatson return (error); 1953100979Srwatson} 1954100979Srwatson 1955100979Srwatsonint 1956100979Srwatsonmac_check_vnode_exec(struct ucred *cred, struct vnode *vp) 1957100979Srwatson{ 1958100979Srwatson int error; 1959100979Srwatson 1960102102Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1961102102Srwatson 1962100979Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1963100979Srwatson return (0); 1964100979Srwatson 1965100979Srwatson MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label); 1966100979Srwatson 1967100979Srwatson return (error); 1968100979Srwatson} 1969100979Srwatson 1970100979Srwatsonint 1971100979Srwatsonmac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1972100979Srwatson{ 1973100979Srwatson int error; 1974100979Srwatson 1975100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1976100979Srwatson 1977100979Srwatson if (!mac_enforce_fs) 1978100979Srwatson return (0); 1979100979Srwatson 1980100979Srwatson MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1981100979Srwatson return (error); 1982100979Srwatson} 1983100979Srwatson 1984100979Srwatsonint 1985100979Srwatsonmac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1986100979Srwatson int attrnamespace, const char *name, struct uio *uio) 1987100979Srwatson{ 1988100979Srwatson int error; 1989100979Srwatson 1990100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1991100979Srwatson 1992100979Srwatson if (!mac_enforce_fs) 1993100979Srwatson return (0); 1994100979Srwatson 1995100979Srwatson MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1996100979Srwatson attrnamespace, name, uio); 1997100979Srwatson return (error); 1998100979Srwatson} 1999100979Srwatson 2000100979Srwatsonint 2001104529Srwatsonmac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2002104529Srwatson struct vnode *vp, struct componentname *cnp) 2003104529Srwatson{ 2004104529Srwatson int error; 2005104529Srwatson 2006104529Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link"); 2007104529Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link"); 2008104529Srwatson 2009104529Srwatson if (!mac_enforce_fs) 2010104529Srwatson return (0); 2011104529Srwatson 2012104529Srwatson MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp, 2013104529Srwatson &vp->v_label, cnp); 2014104529Srwatson return (error); 2015104529Srwatson} 2016104529Srwatson 2017104529Srwatsonint 2018100979Srwatsonmac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2019100979Srwatson struct componentname *cnp) 2020100979Srwatson{ 2021100979Srwatson int error; 2022100979Srwatson 2023100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 2024100979Srwatson 2025100979Srwatson if (!mac_enforce_fs) 2026100979Srwatson return (0); 2027100979Srwatson 2028100979Srwatson MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 2029100979Srwatson return (error); 2030100979Srwatson} 2031100979Srwatson 2032104546Srwatsonint 2033104546Srwatsonmac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) 2034100979Srwatson{ 2035104546Srwatson int error; 2036100979Srwatson 2037104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); 2038103514Srwatson 2039104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 2040104546Srwatson return (0); 2041104546Srwatson 2042104546Srwatson MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); 2043104546Srwatson return (error); 2044100979Srwatson} 2045100979Srwatson 2046104546Srwatsonvoid 2047104546Srwatsonmac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) 2048104546Srwatson{ 2049104546Srwatson int result = *prot; 2050104546Srwatson 2051104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); 2052104546Srwatson 2053104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 2054104546Srwatson return; 2055104546Srwatson 2056104546Srwatson MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, 2057104546Srwatson &result); 2058104546Srwatson 2059104546Srwatson *prot = result; 2060104546Srwatson} 2061104546Srwatson 2062100979Srwatsonint 2063104546Srwatsonmac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) 2064104546Srwatson{ 2065104546Srwatson int error; 2066104546Srwatson 2067104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); 2068104546Srwatson 2069104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 2070104546Srwatson return (0); 2071104546Srwatson 2072104546Srwatson MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); 2073104546Srwatson return (error); 2074104546Srwatson} 2075104546Srwatson 2076104546Srwatsonint 2077102112Srwatsonmac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode) 2078100979Srwatson{ 2079100979Srwatson int error; 2080100979Srwatson 2081102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 2082102112Srwatson 2083100979Srwatson if (!mac_enforce_fs) 2084100979Srwatson return (0); 2085100979Srwatson 2086102112Srwatson MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 2087102112Srwatson return (error); 2088102112Srwatson} 2089102112Srwatson 2090102112Srwatsonint 2091102129Srwatsonmac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2092102129Srwatson struct vnode *vp) 2093102112Srwatson{ 2094102112Srwatson int error; 2095102112Srwatson 2096102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 2097102112Srwatson 2098102112Srwatson if (!mac_enforce_fs) 2099102112Srwatson return (0); 2100102112Srwatson 2101102129Srwatson MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 2102102129Srwatson &vp->v_label); 2103100979Srwatson 2104100979Srwatson return (error); 2105100979Srwatson} 2106100979Srwatson 2107100979Srwatsonint 2108102129Srwatsonmac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2109102129Srwatson struct vnode *vp) 2110100979Srwatson{ 2111100979Srwatson int error; 2112100979Srwatson 2113102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 2114100979Srwatson 2115100979Srwatson if (!mac_enforce_fs) 2116100979Srwatson return (0); 2117100979Srwatson 2118102129Srwatson MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 2119102129Srwatson &vp->v_label); 2120102112Srwatson 2121100979Srwatson return (error); 2122100979Srwatson} 2123100979Srwatson 2124100979Srwatsonint 2125100979Srwatsonmac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 2126100979Srwatson{ 2127100979Srwatson int error; 2128100979Srwatson 2129100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 2130100979Srwatson 2131100979Srwatson if (!mac_enforce_fs) 2132100979Srwatson return (0); 2133100979Srwatson 2134100979Srwatson MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 2135100979Srwatson return (error); 2136100979Srwatson} 2137100979Srwatson 2138100979Srwatsonint 2139100979Srwatsonmac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 2140100979Srwatson{ 2141100979Srwatson int error; 2142100979Srwatson 2143100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 2144100979Srwatson 2145100979Srwatson if (!mac_enforce_fs) 2146100979Srwatson return (0); 2147100979Srwatson 2148100979Srwatson MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 2149100979Srwatson return (error); 2150100979Srwatson} 2151100979Srwatson 2152100979Srwatsonstatic int 2153100979Srwatsonmac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2154100979Srwatson struct label *newlabel) 2155100979Srwatson{ 2156100979Srwatson int error; 2157100979Srwatson 2158100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 2159100979Srwatson 2160100979Srwatson MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 2161100979Srwatson 2162100979Srwatson return (error); 2163100979Srwatson} 2164100979Srwatson 2165100979Srwatsonint 2166100979Srwatsonmac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2167100979Srwatson struct vnode *vp, struct componentname *cnp) 2168100979Srwatson{ 2169100979Srwatson int error; 2170100979Srwatson 2171100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 2172100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 2173100979Srwatson 2174100979Srwatson if (!mac_enforce_fs) 2175100979Srwatson return (0); 2176100979Srwatson 2177100979Srwatson MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 2178100979Srwatson &vp->v_label, cnp); 2179100979Srwatson return (error); 2180100979Srwatson} 2181100979Srwatson 2182100979Srwatsonint 2183100979Srwatsonmac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2184100979Srwatson struct vnode *vp, int samedir, struct componentname *cnp) 2185100979Srwatson{ 2186100979Srwatson int error; 2187100979Srwatson 2188100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 2189100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 2190100979Srwatson 2191100979Srwatson if (!mac_enforce_fs) 2192100979Srwatson return (0); 2193100979Srwatson 2194100979Srwatson MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 2195100979Srwatson vp != NULL ? &vp->v_label : NULL, samedir, cnp); 2196100979Srwatson return (error); 2197100979Srwatson} 2198100979Srwatson 2199100979Srwatsonint 2200100979Srwatsonmac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 2201100979Srwatson{ 2202100979Srwatson int error; 2203100979Srwatson 2204100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 2205100979Srwatson 2206100979Srwatson if (!mac_enforce_fs) 2207100979Srwatson return (0); 2208100979Srwatson 2209100979Srwatson MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 2210100979Srwatson return (error); 2211100979Srwatson} 2212100979Srwatson 2213100979Srwatsonint 2214100979Srwatsonmac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 2215100979Srwatson struct acl *acl) 2216100979Srwatson{ 2217100979Srwatson int error; 2218100979Srwatson 2219100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 2220100979Srwatson 2221100979Srwatson if (!mac_enforce_fs) 2222100979Srwatson return (0); 2223100979Srwatson 2224100979Srwatson MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 2225100979Srwatson return (error); 2226100979Srwatson} 2227100979Srwatson 2228100979Srwatsonint 2229100979Srwatsonmac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2230100979Srwatson int attrnamespace, const char *name, struct uio *uio) 2231100979Srwatson{ 2232100979Srwatson int error; 2233100979Srwatson 2234100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 2235100979Srwatson 2236100979Srwatson if (!mac_enforce_fs) 2237100979Srwatson return (0); 2238100979Srwatson 2239100979Srwatson MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 2240100979Srwatson attrnamespace, name, uio); 2241100979Srwatson return (error); 2242100979Srwatson} 2243100979Srwatson 2244100979Srwatsonint 2245100979Srwatsonmac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 2246100979Srwatson{ 2247100979Srwatson int error; 2248100979Srwatson 2249100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 2250100979Srwatson 2251100979Srwatson if (!mac_enforce_fs) 2252100979Srwatson return (0); 2253100979Srwatson 2254100979Srwatson MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 2255100979Srwatson return (error); 2256100979Srwatson} 2257100979Srwatson 2258100979Srwatsonint 2259100979Srwatsonmac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 2260100979Srwatson{ 2261100979Srwatson int error; 2262100979Srwatson 2263100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 2264100979Srwatson 2265100979Srwatson if (!mac_enforce_fs) 2266100979Srwatson return (0); 2267100979Srwatson 2268100979Srwatson MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 2269100979Srwatson return (error); 2270100979Srwatson} 2271100979Srwatson 2272100979Srwatsonint 2273100979Srwatsonmac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 2274100979Srwatson gid_t gid) 2275100979Srwatson{ 2276100979Srwatson int error; 2277100979Srwatson 2278100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 2279100979Srwatson 2280100979Srwatson if (!mac_enforce_fs) 2281100979Srwatson return (0); 2282100979Srwatson 2283100979Srwatson MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 2284100979Srwatson return (error); 2285100979Srwatson} 2286100979Srwatson 2287100979Srwatsonint 2288100979Srwatsonmac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2289100979Srwatson struct timespec atime, struct timespec mtime) 2290100979Srwatson{ 2291100979Srwatson int error; 2292100979Srwatson 2293100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 2294100979Srwatson 2295100979Srwatson if (!mac_enforce_fs) 2296100979Srwatson return (0); 2297100979Srwatson 2298100979Srwatson MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 2299100979Srwatson mtime); 2300100979Srwatson return (error); 2301100979Srwatson} 2302100979Srwatson 2303100979Srwatsonint 2304102129Srwatsonmac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2305102129Srwatson struct vnode *vp) 2306100979Srwatson{ 2307100979Srwatson int error; 2308100979Srwatson 2309100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 2310100979Srwatson 2311100979Srwatson if (!mac_enforce_fs) 2312100979Srwatson return (0); 2313100979Srwatson 2314102129Srwatson MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 2315102129Srwatson &vp->v_label); 2316100979Srwatson return (error); 2317100979Srwatson} 2318100979Srwatson 2319102112Srwatsonint 2320102129Srwatsonmac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 2321102129Srwatson struct vnode *vp) 2322102112Srwatson{ 2323102112Srwatson int error; 2324102112Srwatson 2325102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 2326102112Srwatson 2327102112Srwatson if (!mac_enforce_fs) 2328102112Srwatson return (0); 2329102112Srwatson 2330102129Srwatson MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 2331102129Srwatson &vp->v_label); 2332102112Srwatson 2333102112Srwatson return (error); 2334102112Srwatson} 2335102112Srwatson 2336100979Srwatson/* 2337100979Srwatson * When relabeling a process, call out to the policies for the maximum 2338100979Srwatson * permission allowed for each object type we know about in its 2339100979Srwatson * memory space, and revoke access (in the least surprising ways we 2340100979Srwatson * know) when necessary. The process lock is not held here. 2341100979Srwatson */ 2342100979Srwatsonstatic void 2343100979Srwatsonmac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 2344100979Srwatson{ 2345100979Srwatson 2346100979Srwatson /* XXX freeze all other threads */ 2347100979Srwatson mac_cred_mmapped_drop_perms_recurse(td, cred, 2348100979Srwatson &td->td_proc->p_vmspace->vm_map); 2349100979Srwatson /* XXX allow other threads to continue */ 2350100979Srwatson} 2351100979Srwatson 2352100979Srwatsonstatic __inline const char * 2353100979Srwatsonprot2str(vm_prot_t prot) 2354100979Srwatson{ 2355100979Srwatson 2356100979Srwatson switch (prot & VM_PROT_ALL) { 2357100979Srwatson case VM_PROT_READ: 2358100979Srwatson return ("r--"); 2359100979Srwatson case VM_PROT_READ | VM_PROT_WRITE: 2360100979Srwatson return ("rw-"); 2361100979Srwatson case VM_PROT_READ | VM_PROT_EXECUTE: 2362100979Srwatson return ("r-x"); 2363100979Srwatson case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 2364100979Srwatson return ("rwx"); 2365100979Srwatson case VM_PROT_WRITE: 2366100979Srwatson return ("-w-"); 2367100979Srwatson case VM_PROT_EXECUTE: 2368100979Srwatson return ("--x"); 2369100979Srwatson case VM_PROT_WRITE | VM_PROT_EXECUTE: 2370100979Srwatson return ("-wx"); 2371100979Srwatson default: 2372100979Srwatson return ("---"); 2373100979Srwatson } 2374100979Srwatson} 2375100979Srwatson 2376100979Srwatsonstatic void 2377100979Srwatsonmac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 2378100979Srwatson struct vm_map *map) 2379100979Srwatson{ 2380100979Srwatson struct vm_map_entry *vme; 2381104546Srwatson int result; 2382104546Srwatson vm_prot_t revokeperms; 2383100979Srwatson vm_object_t object; 2384100979Srwatson vm_ooffset_t offset; 2385100979Srwatson struct vnode *vp; 2386100979Srwatson 2387103136Srwatson if (!mac_mmap_revocation) 2388103136Srwatson return; 2389103136Srwatson 2390100979Srwatson vm_map_lock_read(map); 2391100979Srwatson for (vme = map->header.next; vme != &map->header; vme = vme->next) { 2392100979Srwatson if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 2393100979Srwatson mac_cred_mmapped_drop_perms_recurse(td, cred, 2394100979Srwatson vme->object.sub_map); 2395100979Srwatson continue; 2396100979Srwatson } 2397100979Srwatson /* 2398100979Srwatson * Skip over entries that obviously are not shared. 2399100979Srwatson */ 2400100979Srwatson if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 2401100979Srwatson !vme->max_protection) 2402100979Srwatson continue; 2403100979Srwatson /* 2404100979Srwatson * Drill down to the deepest backing object. 2405100979Srwatson */ 2406100979Srwatson offset = vme->offset; 2407100979Srwatson object = vme->object.vm_object; 2408100979Srwatson if (object == NULL) 2409100979Srwatson continue; 2410100979Srwatson while (object->backing_object != NULL) { 2411100979Srwatson object = object->backing_object; 2412100979Srwatson offset += object->backing_object_offset; 2413100979Srwatson } 2414100979Srwatson /* 2415100979Srwatson * At the moment, vm_maps and objects aren't considered 2416100979Srwatson * by the MAC system, so only things with backing by a 2417100979Srwatson * normal object (read: vnodes) are checked. 2418100979Srwatson */ 2419100979Srwatson if (object->type != OBJT_VNODE) 2420100979Srwatson continue; 2421100979Srwatson vp = (struct vnode *)object->handle; 2422100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2423104546Srwatson result = vme->max_protection; 2424104546Srwatson mac_check_vnode_mmap_downgrade(cred, vp, &result); 2425100979Srwatson VOP_UNLOCK(vp, 0, td); 2426100979Srwatson /* 2427100979Srwatson * Find out what maximum protection we may be allowing 2428100979Srwatson * now but a policy needs to get removed. 2429100979Srwatson */ 2430100979Srwatson revokeperms = vme->max_protection & ~result; 2431100979Srwatson if (!revokeperms) 2432100979Srwatson continue; 2433102949Sbde printf("pid %ld: revoking %s perms from %#lx:%ld " 2434102949Sbde "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 2435102949Sbde prot2str(revokeperms), (u_long)vme->start, 2436102949Sbde (long)(vme->end - vme->start), 2437100979Srwatson prot2str(vme->max_protection), prot2str(vme->protection)); 2438100979Srwatson vm_map_lock_upgrade(map); 2439100979Srwatson /* 2440100979Srwatson * This is the really simple case: if a map has more 2441100979Srwatson * max_protection than is allowed, but it's not being 2442100979Srwatson * actually used (that is, the current protection is 2443100979Srwatson * still allowed), we can just wipe it out and do 2444100979Srwatson * nothing more. 2445100979Srwatson */ 2446100979Srwatson if ((vme->protection & revokeperms) == 0) { 2447100979Srwatson vme->max_protection -= revokeperms; 2448100979Srwatson } else { 2449100979Srwatson if (revokeperms & VM_PROT_WRITE) { 2450100979Srwatson /* 2451100979Srwatson * In the more complicated case, flush out all 2452100979Srwatson * pending changes to the object then turn it 2453100979Srwatson * copy-on-write. 2454100979Srwatson */ 2455100979Srwatson vm_object_reference(object); 2456100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2457100979Srwatson vm_object_page_clean(object, 2458100979Srwatson OFF_TO_IDX(offset), 2459100979Srwatson OFF_TO_IDX(offset + vme->end - vme->start + 2460100979Srwatson PAGE_MASK), 2461100979Srwatson OBJPC_SYNC); 2462100979Srwatson VOP_UNLOCK(vp, 0, td); 2463100979Srwatson vm_object_deallocate(object); 2464100979Srwatson /* 2465100979Srwatson * Why bother if there's no read permissions 2466100979Srwatson * anymore? For the rest, we need to leave 2467100979Srwatson * the write permissions on for COW, or 2468100979Srwatson * remove them entirely if configured to. 2469100979Srwatson */ 2470100979Srwatson if (!mac_mmap_revocation_via_cow) { 2471100979Srwatson vme->max_protection &= ~VM_PROT_WRITE; 2472100979Srwatson vme->protection &= ~VM_PROT_WRITE; 2473100979Srwatson } if ((revokeperms & VM_PROT_READ) == 0) 2474100979Srwatson vme->eflags |= MAP_ENTRY_COW | 2475100979Srwatson MAP_ENTRY_NEEDS_COPY; 2476100979Srwatson } 2477100979Srwatson if (revokeperms & VM_PROT_EXECUTE) { 2478100979Srwatson vme->max_protection &= ~VM_PROT_EXECUTE; 2479100979Srwatson vme->protection &= ~VM_PROT_EXECUTE; 2480100979Srwatson } 2481100979Srwatson if (revokeperms & VM_PROT_READ) { 2482100979Srwatson vme->max_protection = 0; 2483100979Srwatson vme->protection = 0; 2484100979Srwatson } 2485100979Srwatson pmap_protect(map->pmap, vme->start, vme->end, 2486100979Srwatson vme->protection & ~revokeperms); 2487100979Srwatson vm_map_simplify_entry(map, vme); 2488100979Srwatson } 2489100979Srwatson vm_map_lock_downgrade(map); 2490100979Srwatson } 2491100979Srwatson vm_map_unlock_read(map); 2492100979Srwatson} 2493100979Srwatson 2494100979Srwatson/* 2495100979Srwatson * When the subject's label changes, it may require revocation of privilege 2496100979Srwatson * to mapped objects. This can't be done on-the-fly later with a unified 2497100979Srwatson * buffer cache. 2498100979Srwatson */ 2499100979Srwatsonstatic void 2500100979Srwatsonmac_relabel_cred(struct ucred *cred, struct label *newlabel) 2501100979Srwatson{ 2502100979Srwatson 2503100979Srwatson MAC_PERFORM(relabel_cred, cred, newlabel); 2504100979Srwatson} 2505100979Srwatson 2506100979Srwatsonvoid 2507100979Srwatsonmac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 2508100979Srwatson{ 2509100979Srwatson 2510100979Srwatson MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 2511100979Srwatson} 2512100979Srwatson 2513100979Srwatsonvoid 2514100979Srwatsonmac_create_ifnet(struct ifnet *ifnet) 2515100979Srwatson{ 2516100979Srwatson 2517100979Srwatson MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2518100979Srwatson} 2519100979Srwatson 2520100979Srwatsonvoid 2521100979Srwatsonmac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2522100979Srwatson{ 2523100979Srwatson 2524100979Srwatson MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2525100979Srwatson} 2526100979Srwatson 2527100979Srwatsonvoid 2528100979Srwatsonmac_create_socket(struct ucred *cred, struct socket *socket) 2529100979Srwatson{ 2530100979Srwatson 2531100979Srwatson MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2532100979Srwatson} 2533100979Srwatson 2534100979Srwatsonvoid 2535100979Srwatsonmac_create_pipe(struct ucred *cred, struct pipe *pipe) 2536100979Srwatson{ 2537100979Srwatson 2538100979Srwatson MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2539100979Srwatson} 2540100979Srwatson 2541100979Srwatsonvoid 2542100979Srwatsonmac_create_socket_from_socket(struct socket *oldsocket, 2543100979Srwatson struct socket *newsocket) 2544100979Srwatson{ 2545100979Srwatson 2546100979Srwatson MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2547100979Srwatson newsocket, &newsocket->so_label); 2548100979Srwatson} 2549100979Srwatson 2550100979Srwatsonstatic void 2551100979Srwatsonmac_relabel_socket(struct ucred *cred, struct socket *socket, 2552100979Srwatson struct label *newlabel) 2553100979Srwatson{ 2554100979Srwatson 2555100979Srwatson MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2556100979Srwatson} 2557100979Srwatson 2558100979Srwatsonstatic void 2559100979Srwatsonmac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2560100979Srwatson{ 2561100979Srwatson 2562100979Srwatson MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2563100979Srwatson} 2564100979Srwatson 2565100979Srwatsonvoid 2566100979Srwatsonmac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2567100979Srwatson{ 2568100979Srwatson 2569100979Srwatson MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label, 2570100979Srwatson socket, &socket->so_peerlabel); 2571100979Srwatson} 2572100979Srwatson 2573100979Srwatsonvoid 2574100979Srwatsonmac_set_socket_peer_from_socket(struct socket *oldsocket, 2575100979Srwatson struct socket *newsocket) 2576100979Srwatson{ 2577100979Srwatson 2578100979Srwatson MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2579100979Srwatson &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2580100979Srwatson} 2581100979Srwatson 2582100979Srwatsonvoid 2583100979Srwatsonmac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2584100979Srwatson{ 2585100979Srwatson 2586100979Srwatson MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2587100979Srwatson datagram, &datagram->m_pkthdr.label); 2588100979Srwatson} 2589100979Srwatson 2590100979Srwatsonvoid 2591100979Srwatsonmac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2592100979Srwatson{ 2593100979Srwatson 2594100979Srwatson MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label, 2595100979Srwatson fragment, &fragment->m_pkthdr.label); 2596100979Srwatson} 2597100979Srwatson 2598100979Srwatsonvoid 2599100979Srwatsonmac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2600100979Srwatson{ 2601100979Srwatson 2602100979Srwatson MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2603100979Srwatson &ipq->ipq_label); 2604100979Srwatson} 2605100979Srwatson 2606100979Srwatsonvoid 2607100979Srwatsonmac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2608100979Srwatson{ 2609100979Srwatson 2610100979Srwatson MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label, 2611100979Srwatson newmbuf, &newmbuf->m_pkthdr.label); 2612100979Srwatson} 2613100979Srwatson 2614100979Srwatsonvoid 2615100979Srwatsonmac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2616100979Srwatson{ 2617100979Srwatson 2618100979Srwatson MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2619100979Srwatson &mbuf->m_pkthdr.label); 2620100979Srwatson} 2621100979Srwatson 2622100979Srwatsonvoid 2623100979Srwatsonmac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2624100979Srwatson{ 2625100979Srwatson 2626100979Srwatson MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2627100979Srwatson &mbuf->m_pkthdr.label); 2628100979Srwatson} 2629100979Srwatson 2630100979Srwatsonvoid 2631100979Srwatsonmac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2632100979Srwatson{ 2633100979Srwatson 2634100979Srwatson MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2635100979Srwatson &mbuf->m_pkthdr.label); 2636100979Srwatson} 2637100979Srwatson 2638100979Srwatsonvoid 2639100979Srwatsonmac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2640100979Srwatson struct mbuf *newmbuf) 2641100979Srwatson{ 2642100979Srwatson 2643100979Srwatson MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, 2644100979Srwatson &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf, 2645100979Srwatson &newmbuf->m_pkthdr.label); 2646100979Srwatson} 2647100979Srwatson 2648100979Srwatsonvoid 2649100979Srwatsonmac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2650100979Srwatson{ 2651100979Srwatson 2652100979Srwatson MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label, 2653100979Srwatson newmbuf, &newmbuf->m_pkthdr.label); 2654100979Srwatson} 2655100979Srwatson 2656100979Srwatsonint 2657100979Srwatsonmac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2658100979Srwatson{ 2659100979Srwatson int result; 2660100979Srwatson 2661100979Srwatson result = 1; 2662100979Srwatson MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label, 2663100979Srwatson ipq, &ipq->ipq_label); 2664100979Srwatson 2665100979Srwatson return (result); 2666100979Srwatson} 2667100979Srwatson 2668100979Srwatsonvoid 2669100979Srwatsonmac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2670100979Srwatson{ 2671100979Srwatson 2672100979Srwatson MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2673100979Srwatson &ipq->ipq_label); 2674100979Srwatson} 2675100979Srwatson 2676100979Srwatsonvoid 2677100979Srwatsonmac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2678100979Srwatson{ 2679100979Srwatson 2680100979Srwatson MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2681100979Srwatson &mbuf->m_pkthdr.label); 2682100979Srwatson} 2683100979Srwatson 2684100979Srwatsonvoid 2685100979Srwatsonmac_create_mount(struct ucred *cred, struct mount *mp) 2686100979Srwatson{ 2687100979Srwatson 2688100979Srwatson MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2689100979Srwatson &mp->mnt_fslabel); 2690100979Srwatson} 2691100979Srwatson 2692100979Srwatsonvoid 2693100979Srwatsonmac_create_root_mount(struct ucred *cred, struct mount *mp) 2694100979Srwatson{ 2695100979Srwatson 2696100979Srwatson MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2697100979Srwatson &mp->mnt_fslabel); 2698100979Srwatson} 2699100979Srwatson 2700100979Srwatsonint 2701100979Srwatsonmac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2702100979Srwatson{ 2703100979Srwatson int error; 2704100979Srwatson 2705100979Srwatson if (!mac_enforce_network) 2706100979Srwatson return (0); 2707100979Srwatson 2708100979Srwatson MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2709100979Srwatson &ifnet->if_label); 2710100979Srwatson 2711100979Srwatson return (error); 2712100979Srwatson} 2713100979Srwatson 2714100979Srwatsonstatic int 2715100979Srwatsonmac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2716100979Srwatson{ 2717100979Srwatson int error; 2718100979Srwatson 2719100979Srwatson MAC_CHECK(check_cred_relabel, cred, newlabel); 2720100979Srwatson 2721100979Srwatson return (error); 2722100979Srwatson} 2723100979Srwatson 2724100979Srwatsonint 2725100979Srwatsonmac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2726100979Srwatson{ 2727100979Srwatson int error; 2728100979Srwatson 2729100979Srwatson if (!mac_enforce_process) 2730100979Srwatson return (0); 2731100979Srwatson 2732100979Srwatson MAC_CHECK(check_cred_visible, u1, u2); 2733100979Srwatson 2734100979Srwatson return (error); 2735100979Srwatson} 2736100979Srwatson 2737100979Srwatsonint 2738100979Srwatsonmac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2739100979Srwatson{ 2740100979Srwatson int error; 2741100979Srwatson 2742100979Srwatson if (!mac_enforce_network) 2743100979Srwatson return (0); 2744100979Srwatson 2745100979Srwatson KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr")); 2746100979Srwatson if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED)) 2747105598Sbrooks if_printf(ifnet, "not initialized\n"); 2748100979Srwatson 2749100979Srwatson MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2750100979Srwatson &mbuf->m_pkthdr.label); 2751100979Srwatson 2752100979Srwatson return (error); 2753100979Srwatson} 2754100979Srwatson 2755100979Srwatsonint 2756100979Srwatsonmac_check_mount_stat(struct ucred *cred, struct mount *mount) 2757100979Srwatson{ 2758100979Srwatson int error; 2759100979Srwatson 2760100979Srwatson if (!mac_enforce_fs) 2761100979Srwatson return (0); 2762100979Srwatson 2763100979Srwatson MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2764100979Srwatson 2765100979Srwatson return (error); 2766100979Srwatson} 2767100979Srwatson 2768100979Srwatsonint 2769100979Srwatsonmac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2770100979Srwatson void *data) 2771100979Srwatson{ 2772100979Srwatson int error; 2773100979Srwatson 2774104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2775104269Srwatson 2776104269Srwatson if (!mac_enforce_pipe) 2777104269Srwatson return (0); 2778104269Srwatson 2779100979Srwatson MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2780100979Srwatson 2781100979Srwatson return (error); 2782100979Srwatson} 2783100979Srwatson 2784100979Srwatsonint 2785102115Srwatsonmac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2786100979Srwatson{ 2787100979Srwatson int error; 2788100979Srwatson 2789104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2790104269Srwatson 2791104269Srwatson if (!mac_enforce_pipe) 2792104269Srwatson return (0); 2793104269Srwatson 2794102115Srwatson MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2795100979Srwatson 2796100979Srwatson return (error); 2797100979Srwatson} 2798100979Srwatson 2799102115Srwatsonint 2800102115Srwatsonmac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2801102115Srwatson{ 2802102115Srwatson int error; 2803102115Srwatson 2804104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2805104269Srwatson 2806104269Srwatson if (!mac_enforce_pipe) 2807104269Srwatson return (0); 2808104269Srwatson 2809102115Srwatson MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2810102115Srwatson 2811102115Srwatson return (error); 2812102115Srwatson} 2813102115Srwatson 2814100979Srwatsonstatic int 2815100979Srwatsonmac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2816100979Srwatson struct label *newlabel) 2817100979Srwatson{ 2818100979Srwatson int error; 2819100979Srwatson 2820104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2821104269Srwatson 2822104269Srwatson if (!mac_enforce_pipe) 2823104269Srwatson return (0); 2824104269Srwatson 2825100979Srwatson MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2826100979Srwatson 2827100979Srwatson return (error); 2828100979Srwatson} 2829100979Srwatson 2830100979Srwatsonint 2831102115Srwatsonmac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2832102115Srwatson{ 2833102115Srwatson int error; 2834102115Srwatson 2835104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2836104269Srwatson 2837104269Srwatson if (!mac_enforce_pipe) 2838104269Srwatson return (0); 2839104269Srwatson 2840102115Srwatson MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2841102115Srwatson 2842102115Srwatson return (error); 2843102115Srwatson} 2844102115Srwatson 2845102115Srwatsonint 2846102115Srwatsonmac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2847102115Srwatson{ 2848102115Srwatson int error; 2849102115Srwatson 2850104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2851104269Srwatson 2852104269Srwatson if (!mac_enforce_pipe) 2853104269Srwatson return (0); 2854104269Srwatson 2855102115Srwatson MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2856102115Srwatson 2857102115Srwatson return (error); 2858102115Srwatson} 2859102115Srwatson 2860102115Srwatsonint 2861100979Srwatsonmac_check_proc_debug(struct ucred *cred, struct proc *proc) 2862100979Srwatson{ 2863100979Srwatson int error; 2864100979Srwatson 2865102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2866102103Srwatson 2867100979Srwatson if (!mac_enforce_process) 2868100979Srwatson return (0); 2869100979Srwatson 2870100979Srwatson MAC_CHECK(check_proc_debug, cred, proc); 2871100979Srwatson 2872100979Srwatson return (error); 2873100979Srwatson} 2874100979Srwatson 2875100979Srwatsonint 2876100979Srwatsonmac_check_proc_sched(struct ucred *cred, struct proc *proc) 2877100979Srwatson{ 2878100979Srwatson int error; 2879100979Srwatson 2880102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2881102103Srwatson 2882100979Srwatson if (!mac_enforce_process) 2883100979Srwatson return (0); 2884100979Srwatson 2885100979Srwatson MAC_CHECK(check_proc_sched, cred, proc); 2886100979Srwatson 2887100979Srwatson return (error); 2888100979Srwatson} 2889100979Srwatson 2890100979Srwatsonint 2891100979Srwatsonmac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2892100979Srwatson{ 2893100979Srwatson int error; 2894100979Srwatson 2895102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2896102103Srwatson 2897100979Srwatson if (!mac_enforce_process) 2898100979Srwatson return (0); 2899100979Srwatson 2900100979Srwatson MAC_CHECK(check_proc_signal, cred, proc, signum); 2901100979Srwatson 2902100979Srwatson return (error); 2903100979Srwatson} 2904100979Srwatson 2905100979Srwatsonint 2906100979Srwatsonmac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2907100979Srwatson struct sockaddr *sockaddr) 2908100979Srwatson{ 2909100979Srwatson int error; 2910100979Srwatson 2911100979Srwatson if (!mac_enforce_socket) 2912100979Srwatson return (0); 2913100979Srwatson 2914100979Srwatson MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2915100979Srwatson sockaddr); 2916100979Srwatson 2917100979Srwatson return (error); 2918100979Srwatson} 2919100979Srwatson 2920100979Srwatsonint 2921100979Srwatsonmac_check_socket_connect(struct ucred *cred, struct socket *socket, 2922100979Srwatson struct sockaddr *sockaddr) 2923100979Srwatson{ 2924100979Srwatson int error; 2925100979Srwatson 2926100979Srwatson if (!mac_enforce_socket) 2927100979Srwatson return (0); 2928100979Srwatson 2929100979Srwatson MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2930100979Srwatson sockaddr); 2931100979Srwatson 2932100979Srwatson return (error); 2933100979Srwatson} 2934100979Srwatson 2935100979Srwatsonint 2936101933Srwatsonmac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2937100979Srwatson{ 2938100979Srwatson int error; 2939100979Srwatson 2940100979Srwatson if (!mac_enforce_socket) 2941100979Srwatson return (0); 2942100979Srwatson 2943101933Srwatson MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2944101933Srwatson &mbuf->m_pkthdr.label); 2945101933Srwatson 2946100979Srwatson return (error); 2947100979Srwatson} 2948100979Srwatson 2949100979Srwatsonint 2950101933Srwatsonmac_check_socket_listen(struct ucred *cred, struct socket *socket) 2951100979Srwatson{ 2952100979Srwatson int error; 2953100979Srwatson 2954100979Srwatson if (!mac_enforce_socket) 2955100979Srwatson return (0); 2956100979Srwatson 2957101933Srwatson MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2958100979Srwatson return (error); 2959100979Srwatson} 2960100979Srwatson 2961104571Srwatsonint 2962104571Srwatsonmac_check_socket_receive(struct ucred *cred, struct socket *so) 2963104571Srwatson{ 2964104571Srwatson int error; 2965104571Srwatson 2966104571Srwatson if (!mac_enforce_socket) 2967104571Srwatson return (0); 2968104571Srwatson 2969104571Srwatson MAC_CHECK(check_socket_receive, cred, so, &so->so_label); 2970104571Srwatson 2971104571Srwatson return (error); 2972104571Srwatson} 2973104571Srwatson 2974100979Srwatsonstatic int 2975100979Srwatsonmac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2976100979Srwatson struct label *newlabel) 2977100979Srwatson{ 2978100979Srwatson int error; 2979100979Srwatson 2980100979Srwatson MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2981100979Srwatson newlabel); 2982100979Srwatson 2983100979Srwatson return (error); 2984100979Srwatson} 2985100979Srwatson 2986100979Srwatsonint 2987104571Srwatsonmac_check_socket_send(struct ucred *cred, struct socket *so) 2988104571Srwatson{ 2989104571Srwatson int error; 2990104571Srwatson 2991104571Srwatson if (!mac_enforce_socket) 2992104571Srwatson return (0); 2993104571Srwatson 2994104571Srwatson MAC_CHECK(check_socket_send, cred, so, &so->so_label); 2995104571Srwatson 2996104571Srwatson return (error); 2997104571Srwatson} 2998104571Srwatson 2999104571Srwatsonint 3000100979Srwatsonmac_check_socket_visible(struct ucred *cred, struct socket *socket) 3001100979Srwatson{ 3002100979Srwatson int error; 3003100979Srwatson 3004100979Srwatson if (!mac_enforce_socket) 3005100979Srwatson return (0); 3006105694Srwatson 3007100979Srwatson MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 3008105694Srwatson 3009100979Srwatson return (error); 3010100979Srwatson} 3011100979Srwatson 3012100979Srwatsonint 3013106024Srwatsonmac_check_system_reboot(struct ucred *cred, int howto) 3014106024Srwatson{ 3015106024Srwatson int error; 3016106024Srwatson 3017106024Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_reboot"); 3018106024Srwatson 3019106045Srwatson if (!mac_enforce_system) 3020106024Srwatson return (0); 3021106024Srwatson 3022106024Srwatson MAC_CHECK(check_system_reboot, cred, howto); 3023106045Srwatson 3024106024Srwatson return (error); 3025106024Srwatson} 3026106024Srwatson 3027106024Srwatsonint 3028106023Srwatsonmac_check_system_swapon(struct ucred *cred, struct vnode *vp) 3029106023Srwatson{ 3030106023Srwatson int error; 3031106023Srwatson 3032106023Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon"); 3033106023Srwatson 3034106045Srwatson if (!mac_enforce_system) 3035106023Srwatson return (0); 3036106023Srwatson 3037106023Srwatson MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label); 3038106023Srwatson return (error); 3039106023Srwatson} 3040106023Srwatson 3041106023Srwatsonint 3042106025Srwatsonmac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 3043106025Srwatson void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 3044106025Srwatson{ 3045106025Srwatson int error; 3046106025Srwatson 3047106025Srwatson /* 3048106025Srwatson * XXXMAC: We're very much like to assert the SYSCTL_LOCK here, 3049106025Srwatson * but since it's not exported from kern_sysctl.c, we can't. 3050106025Srwatson */ 3051106045Srwatson if (!mac_enforce_system) 3052106025Srwatson return (0); 3053106025Srwatson 3054106025Srwatson MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp, 3055106025Srwatson inkernel, new, newlen); 3056106025Srwatson 3057106025Srwatson return (error); 3058106025Srwatson} 3059106025Srwatson 3060106025Srwatsonint 3061100979Srwatsonmac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 3062100979Srwatson struct ifnet *ifnet) 3063100979Srwatson{ 3064105694Srwatson char *elements, *buffer; 3065105694Srwatson struct mac mac; 3066100979Srwatson int error; 3067100979Srwatson 3068105694Srwatson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 3069100979Srwatson if (error) 3070100979Srwatson return (error); 3071100979Srwatson 3072105694Srwatson error = mac_check_structmac_consistent(&mac); 3073105694Srwatson if (error) 3074105694Srwatson return (error); 3075105694Srwatson 3076105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3077105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3078105694Srwatson if (error) { 3079105694Srwatson free(elements, M_MACTEMP); 3080105694Srwatson return (error); 3081105694Srwatson } 3082105694Srwatson 3083105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3084105694Srwatson error = mac_externalize_ifnet_label(&ifnet->if_label, elements, 3085105694Srwatson buffer, mac.m_buflen, M_WAITOK); 3086105694Srwatson if (error == 0) 3087105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3088105694Srwatson 3089105694Srwatson free(buffer, M_MACTEMP); 3090105694Srwatson free(elements, M_MACTEMP); 3091105694Srwatson 3092105694Srwatson return (error); 3093100979Srwatson} 3094100979Srwatson 3095100979Srwatsonint 3096100979Srwatsonmac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 3097100979Srwatson struct ifnet *ifnet) 3098100979Srwatson{ 3099100979Srwatson struct label intlabel; 3100105694Srwatson struct mac mac; 3101105694Srwatson char *buffer; 3102100979Srwatson int error; 3103100979Srwatson 3104105694Srwatson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 3105100979Srwatson if (error) 3106100979Srwatson return (error); 3107100979Srwatson 3108105694Srwatson error = mac_check_structmac_consistent(&mac); 3109100979Srwatson if (error) 3110100979Srwatson return (error); 3111100979Srwatson 3112105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3113105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3114105694Srwatson if (error) { 3115105694Srwatson free(buffer, M_MACTEMP); 3116105694Srwatson return (error); 3117105694Srwatson } 3118105694Srwatson 3119105694Srwatson mac_init_ifnet_label(&intlabel); 3120105694Srwatson error = mac_internalize_ifnet_label(&intlabel, buffer); 3121105694Srwatson free(buffer, M_MACTEMP); 3122105694Srwatson if (error) { 3123105694Srwatson mac_destroy_ifnet_label(&intlabel); 3124105694Srwatson return (error); 3125105694Srwatson } 3126105694Srwatson 3127100979Srwatson /* 3128100979Srwatson * XXX: Note that this is a redundant privilege check, since 3129100979Srwatson * policies impose this check themselves if required by the 3130100979Srwatson * policy. Eventually, this should go away. 3131100979Srwatson */ 3132100979Srwatson error = suser_cred(cred, 0); 3133105694Srwatson if (error) { 3134105694Srwatson mac_destroy_ifnet_label(&intlabel); 3135105694Srwatson return (error); 3136105694Srwatson } 3137100979Srwatson 3138100979Srwatson MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 3139100979Srwatson &intlabel); 3140105694Srwatson if (error) { 3141105694Srwatson mac_destroy_ifnet_label(&intlabel); 3142105694Srwatson return (error); 3143105694Srwatson } 3144100979Srwatson 3145100979Srwatson MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 3146100979Srwatson 3147105694Srwatson mac_destroy_ifnet_label(&intlabel); 3148105694Srwatson return (0); 3149100979Srwatson} 3150100979Srwatson 3151100979Srwatsonvoid 3152100979Srwatsonmac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp) 3153100979Srwatson{ 3154100979Srwatson 3155100979Srwatson MAC_PERFORM(create_devfs_vnode, de, &de->de_label, vp, &vp->v_label); 3156100979Srwatson} 3157100979Srwatson 3158100979Srwatsonvoid 3159100979Srwatsonmac_create_devfs_device(dev_t dev, struct devfs_dirent *de) 3160100979Srwatson{ 3161100979Srwatson 3162100979Srwatson MAC_PERFORM(create_devfs_device, dev, de, &de->de_label); 3163100979Srwatson} 3164100979Srwatson 3165104533Srwatsonvoid 3166104533Srwatsonmac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd, 3167104533Srwatson struct devfs_dirent *de) 3168104533Srwatson{ 3169104533Srwatson 3170104533Srwatson MAC_PERFORM(create_devfs_symlink, cred, dd, &dd->de_label, de, 3171104533Srwatson &de->de_label); 3172104533Srwatson} 3173104533Srwatson 3174100979Srwatsonvoid 3175100979Srwatsonmac_create_devfs_directory(char *dirname, int dirnamelen, 3176100979Srwatson struct devfs_dirent *de) 3177100979Srwatson{ 3178100979Srwatson 3179100979Srwatson MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de, 3180100979Srwatson &de->de_label); 3181100979Srwatson} 3182100979Srwatson 3183100979Srwatsonint 3184100979Srwatsonmac_setsockopt_label_set(struct ucred *cred, struct socket *so, 3185105694Srwatson struct mac *mac) 3186100979Srwatson{ 3187100979Srwatson struct label intlabel; 3188105694Srwatson char *buffer; 3189100979Srwatson int error; 3190100979Srwatson 3191105694Srwatson error = mac_check_structmac_consistent(mac); 3192100979Srwatson if (error) 3193100979Srwatson return (error); 3194100979Srwatson 3195105694Srwatson buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3196105694Srwatson error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); 3197105694Srwatson if (error) { 3198105694Srwatson free(buffer, M_MACTEMP); 3199105694Srwatson return (error); 3200105694Srwatson } 3201105694Srwatson 3202105694Srwatson mac_init_socket_label(&intlabel, M_WAITOK); 3203105694Srwatson error = mac_internalize_socket_label(&intlabel, buffer); 3204105694Srwatson free(buffer, M_MACTEMP); 3205105694Srwatson if (error) { 3206105694Srwatson mac_destroy_socket_label(&intlabel); 3207105694Srwatson return (error); 3208105694Srwatson } 3209105694Srwatson 3210100979Srwatson mac_check_socket_relabel(cred, so, &intlabel); 3211100979Srwatson if (error) { 3212105694Srwatson mac_destroy_socket_label(&intlabel); 3213100979Srwatson return (error); 3214100979Srwatson } 3215100979Srwatson 3216100979Srwatson mac_relabel_socket(cred, so, &intlabel); 3217100979Srwatson 3218105694Srwatson mac_destroy_socket_label(&intlabel); 3219100979Srwatson return (0); 3220100979Srwatson} 3221100979Srwatson 3222100979Srwatsonint 3223100979Srwatsonmac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 3224100979Srwatson{ 3225100979Srwatson int error; 3226100979Srwatson 3227104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 3228104269Srwatson 3229100979Srwatson error = mac_check_pipe_relabel(cred, pipe, label); 3230100979Srwatson if (error) 3231100979Srwatson return (error); 3232100979Srwatson 3233100979Srwatson mac_relabel_pipe(cred, pipe, label); 3234100979Srwatson 3235100979Srwatson return (0); 3236100979Srwatson} 3237100979Srwatson 3238100979Srwatsonint 3239100979Srwatsonmac_getsockopt_label_get(struct ucred *cred, struct socket *so, 3240105694Srwatson struct mac *mac) 3241100979Srwatson{ 3242105694Srwatson char *buffer, *elements; 3243105694Srwatson int error; 3244100979Srwatson 3245105694Srwatson error = mac_check_structmac_consistent(mac); 3246105694Srwatson if (error) 3247105694Srwatson return (error); 3248105694Srwatson 3249105694Srwatson elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3250105694Srwatson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3251105694Srwatson if (error) { 3252105694Srwatson free(elements, M_MACTEMP); 3253105694Srwatson return (error); 3254105694Srwatson } 3255105694Srwatson 3256105694Srwatson buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3257105694Srwatson error = mac_externalize_socket_label(&so->so_label, elements, 3258105694Srwatson buffer, mac->m_buflen, M_WAITOK); 3259105694Srwatson if (error == 0) 3260105694Srwatson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3261105694Srwatson 3262105694Srwatson free(buffer, M_MACTEMP); 3263105694Srwatson free(elements, M_MACTEMP); 3264105694Srwatson 3265105694Srwatson return (error); 3266100979Srwatson} 3267100979Srwatson 3268100979Srwatsonint 3269100979Srwatsonmac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 3270105694Srwatson struct mac *mac) 3271100979Srwatson{ 3272105694Srwatson char *elements, *buffer; 3273105694Srwatson int error; 3274100979Srwatson 3275105694Srwatson error = mac_check_structmac_consistent(mac); 3276105694Srwatson if (error) 3277105694Srwatson return (error); 3278105694Srwatson 3279105694Srwatson elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3280105694Srwatson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3281105694Srwatson if (error) { 3282105694Srwatson free(elements, M_MACTEMP); 3283105694Srwatson return (error); 3284105694Srwatson } 3285105694Srwatson 3286105694Srwatson buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3287105694Srwatson error = mac_externalize_socket_peer_label(&so->so_peerlabel, 3288105694Srwatson elements, buffer, mac->m_buflen, M_WAITOK); 3289105694Srwatson if (error == 0) 3290105694Srwatson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3291105694Srwatson 3292105694Srwatson free(buffer, M_MACTEMP); 3293105694Srwatson free(elements, M_MACTEMP); 3294105694Srwatson 3295105694Srwatson return (error); 3296100979Srwatson} 3297100979Srwatson 3298100979Srwatson/* 3299100979Srwatson * Implementation of VOP_SETLABEL() that relies on extended attributes 3300100979Srwatson * to store label data. Can be referenced by filesystems supporting 3301100979Srwatson * extended attributes. 3302100979Srwatson */ 3303100979Srwatsonint 3304100979Srwatsonvop_stdsetlabel_ea(struct vop_setlabel_args *ap) 3305100979Srwatson{ 3306100979Srwatson struct vnode *vp = ap->a_vp; 3307100979Srwatson struct label *intlabel = ap->a_label; 3308100979Srwatson int error; 3309100979Srwatson 3310100979Srwatson ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 3311100979Srwatson 3312105988Srwatson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3313105988Srwatson return (EOPNOTSUPP); 3314100979Srwatson 3315105988Srwatson error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel); 3316100979Srwatson if (error) 3317100979Srwatson return (error); 3318100979Srwatson 3319100979Srwatson mac_relabel_vnode(ap->a_cred, vp, intlabel); 3320100979Srwatson 3321100979Srwatson return (0); 3322100979Srwatson} 3323100979Srwatson 3324100979Srwatsonstatic int 3325100979Srwatsonvn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 3326100979Srwatson{ 3327100979Srwatson int error; 3328100979Srwatson 3329100979Srwatson if (vp->v_mount == NULL) { 3330100979Srwatson /* printf("vn_setlabel: null v_mount\n"); */ 3331103314Snjl if (vp->v_type != VNON) 3332103314Snjl printf("vn_setlabel: null v_mount with non-VNON\n"); 3333100979Srwatson return (EBADF); 3334100979Srwatson } 3335100979Srwatson 3336100979Srwatson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3337100979Srwatson return (EOPNOTSUPP); 3338100979Srwatson 3339100979Srwatson /* 3340100979Srwatson * Multi-phase commit. First check the policies to confirm the 3341100979Srwatson * change is OK. Then commit via the filesystem. Finally, 3342100979Srwatson * update the actual vnode label. Question: maybe the filesystem 3343100979Srwatson * should update the vnode at the end as part of VOP_SETLABEL()? 3344100979Srwatson */ 3345100979Srwatson error = mac_check_vnode_relabel(cred, vp, intlabel); 3346100979Srwatson if (error) 3347100979Srwatson return (error); 3348100979Srwatson 3349100979Srwatson /* 3350100979Srwatson * VADMIN provides the opportunity for the filesystem to make 3351100979Srwatson * decisions about who is and is not able to modify labels 3352100979Srwatson * and protections on files. This might not be right. We can't 3353100979Srwatson * assume VOP_SETLABEL() will do it, because we might implement 3354100979Srwatson * that as part of vop_stdsetlabel_ea(). 3355100979Srwatson */ 3356100979Srwatson error = VOP_ACCESS(vp, VADMIN, cred, curthread); 3357100979Srwatson if (error) 3358100979Srwatson return (error); 3359100979Srwatson 3360100979Srwatson error = VOP_SETLABEL(vp, intlabel, cred, curthread); 3361100979Srwatson if (error) 3362100979Srwatson return (error); 3363100979Srwatson 3364100979Srwatson return (0); 3365100979Srwatson} 3366100979Srwatson 3367105694Srwatsonint 3368105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3369105694Srwatson{ 3370105694Srwatson char *elements, *buffer; 3371105694Srwatson struct mac mac; 3372105694Srwatson struct proc *tproc; 3373105694Srwatson struct ucred *tcred; 3374105694Srwatson int error; 3375105694Srwatson 3376105694Srwatson error = copyin(SCARG(uap, mac_p), &mac, sizeof(mac)); 3377105694Srwatson if (error) 3378105694Srwatson return (error); 3379105694Srwatson 3380105694Srwatson error = mac_check_structmac_consistent(&mac); 3381105694Srwatson if (error) 3382105694Srwatson return (error); 3383105694Srwatson 3384105694Srwatson tproc = pfind(uap->pid); 3385105694Srwatson if (tproc == NULL) 3386105694Srwatson return (ESRCH); 3387105694Srwatson 3388105694Srwatson tcred = NULL; /* Satisfy gcc. */ 3389105694Srwatson error = p_cansee(td, tproc); 3390105694Srwatson if (error == 0) 3391105694Srwatson tcred = crhold(tproc->p_ucred); 3392105694Srwatson PROC_UNLOCK(tproc); 3393105694Srwatson if (error) 3394105694Srwatson return (error); 3395105694Srwatson 3396105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3397105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3398105694Srwatson if (error) { 3399105694Srwatson free(elements, M_MACTEMP); 3400105694Srwatson crfree(tcred); 3401105694Srwatson return (error); 3402105694Srwatson } 3403105694Srwatson 3404105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3405105694Srwatson error = mac_externalize_cred_label(&tcred->cr_label, elements, 3406105694Srwatson buffer, mac.m_buflen, M_WAITOK); 3407105694Srwatson if (error == 0) 3408105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3409105694Srwatson 3410105694Srwatson free(buffer, M_MACTEMP); 3411105694Srwatson free(elements, M_MACTEMP); 3412105694Srwatson crfree(tcred); 3413105694Srwatson return (error); 3414105694Srwatson} 3415105694Srwatson 3416100979Srwatson/* 3417100979Srwatson * MPSAFE 3418100979Srwatson */ 3419100979Srwatsonint 3420100894Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3421100894Srwatson{ 3422105694Srwatson char *elements, *buffer; 3423105694Srwatson struct mac mac; 3424100979Srwatson int error; 3425100894Srwatson 3426105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3427105694Srwatson if (error) 3428105694Srwatson return (error); 3429105694Srwatson 3430105694Srwatson error = mac_check_structmac_consistent(&mac); 3431105694Srwatson if (error) 3432105694Srwatson return (error); 3433105694Srwatson 3434105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3435105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3436105694Srwatson if (error) { 3437105694Srwatson free(elements, M_MACTEMP); 3438105694Srwatson return (error); 3439105694Srwatson } 3440105694Srwatson 3441105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3442105694Srwatson error = mac_externalize_cred_label(&td->td_ucred->cr_label, 3443105694Srwatson elements, buffer, mac.m_buflen, M_WAITOK); 3444100979Srwatson if (error == 0) 3445105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3446100979Srwatson 3447105694Srwatson free(buffer, M_MACTEMP); 3448105694Srwatson free(elements, M_MACTEMP); 3449100979Srwatson return (error); 3450100979Srwatson} 3451100979Srwatson 3452100979Srwatson/* 3453100979Srwatson * MPSAFE 3454100979Srwatson */ 3455100979Srwatsonint 3456100979Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3457100979Srwatson{ 3458100979Srwatson struct ucred *newcred, *oldcred; 3459105694Srwatson struct label intlabel; 3460100979Srwatson struct proc *p; 3461105694Srwatson struct mac mac; 3462105694Srwatson char *buffer; 3463100979Srwatson int error; 3464100979Srwatson 3465105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3466100979Srwatson if (error) 3467100979Srwatson return (error); 3468100979Srwatson 3469105694Srwatson error = mac_check_structmac_consistent(&mac); 3470100979Srwatson if (error) 3471100979Srwatson return (error); 3472100979Srwatson 3473105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3474105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3475105694Srwatson if (error) { 3476105694Srwatson free(buffer, M_MACTEMP); 3477105694Srwatson return (error); 3478105694Srwatson } 3479105694Srwatson 3480105694Srwatson mac_init_cred_label(&intlabel); 3481105694Srwatson error = mac_internalize_cred_label(&intlabel, buffer); 3482105694Srwatson free(buffer, M_MACTEMP); 3483105694Srwatson if (error) { 3484105694Srwatson mac_destroy_cred_label(&intlabel); 3485105694Srwatson return (error); 3486105694Srwatson } 3487105694Srwatson 3488100979Srwatson newcred = crget(); 3489100979Srwatson 3490100979Srwatson p = td->td_proc; 3491100979Srwatson PROC_LOCK(p); 3492100979Srwatson oldcred = p->p_ucred; 3493100979Srwatson 3494100979Srwatson error = mac_check_cred_relabel(oldcred, &intlabel); 3495100979Srwatson if (error) { 3496100979Srwatson PROC_UNLOCK(p); 3497100979Srwatson crfree(newcred); 3498105694Srwatson goto out; 3499100979Srwatson } 3500100979Srwatson 3501100979Srwatson setsugid(p); 3502100979Srwatson crcopy(newcred, oldcred); 3503100979Srwatson mac_relabel_cred(newcred, &intlabel); 3504102136Srwatson p->p_ucred = newcred; 3505100979Srwatson 3506102136Srwatson /* 3507102136Srwatson * Grab additional reference for use while revoking mmaps, prior 3508102136Srwatson * to releasing the proc lock and sharing the cred. 3509102136Srwatson */ 3510102136Srwatson crhold(newcred); 3511100979Srwatson PROC_UNLOCK(p); 3512102136Srwatson 3513105694Srwatson if (mac_enforce_vm) { 3514105694Srwatson mtx_lock(&Giant); 3515105694Srwatson mac_cred_mmapped_drop_perms(td, newcred); 3516105694Srwatson mtx_unlock(&Giant); 3517105694Srwatson } 3518102136Srwatson 3519102136Srwatson crfree(newcred); /* Free revocation reference. */ 3520100979Srwatson crfree(oldcred); 3521105694Srwatson 3522105694Srwatsonout: 3523105694Srwatson mac_destroy_cred_label(&intlabel); 3524105694Srwatson return (error); 3525100979Srwatson} 3526100979Srwatson 3527100979Srwatson/* 3528100979Srwatson * MPSAFE 3529100979Srwatson */ 3530100979Srwatsonint 3531100979Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3532100979Srwatson{ 3533105694Srwatson char *elements, *buffer; 3534105694Srwatson struct label intlabel; 3535100979Srwatson struct file *fp; 3536105694Srwatson struct mac mac; 3537100979Srwatson struct vnode *vp; 3538100979Srwatson struct pipe *pipe; 3539105694Srwatson short label_type; 3540100979Srwatson int error; 3541100979Srwatson 3542105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3543105694Srwatson if (error) 3544105694Srwatson return (error); 3545100979Srwatson 3546105694Srwatson error = mac_check_structmac_consistent(&mac); 3547105694Srwatson if (error) 3548105694Srwatson return (error); 3549105694Srwatson 3550105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3551105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3552105694Srwatson if (error) { 3553105694Srwatson free(elements, M_MACTEMP); 3554105694Srwatson return (error); 3555105694Srwatson } 3556105694Srwatson 3557105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3558105694Srwatson mtx_lock(&Giant); /* VFS */ 3559100979Srwatson error = fget(td, SCARG(uap, fd), &fp); 3560100979Srwatson if (error) 3561100979Srwatson goto out; 3562100979Srwatson 3563105694Srwatson label_type = fp->f_type; 3564100979Srwatson switch (fp->f_type) { 3565100979Srwatson case DTYPE_FIFO: 3566100979Srwatson case DTYPE_VNODE: 3567100979Srwatson vp = (struct vnode *)fp->f_data; 3568100979Srwatson 3569105694Srwatson mac_init_vnode_label(&intlabel); 3570105694Srwatson 3571100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3572105988Srwatson mac_copy_vnode_label(&vp->v_label, &intlabel); 3573100979Srwatson VOP_UNLOCK(vp, 0, td); 3574105694Srwatson 3575100979Srwatson break; 3576100979Srwatson case DTYPE_PIPE: 3577100979Srwatson pipe = (struct pipe *)fp->f_data; 3578105694Srwatson 3579105694Srwatson mac_init_pipe_label(&intlabel); 3580105694Srwatson 3581105694Srwatson PIPE_LOCK(pipe); 3582105694Srwatson mac_copy_pipe_label(pipe->pipe_label, &intlabel); 3583105694Srwatson PIPE_UNLOCK(pipe); 3584100979Srwatson break; 3585100979Srwatson default: 3586100979Srwatson error = EINVAL; 3587105694Srwatson fdrop(fp, td); 3588105694Srwatson goto out; 3589100979Srwatson } 3590105694Srwatson fdrop(fp, td); 3591100979Srwatson 3592105694Srwatson switch (label_type) { 3593105694Srwatson case DTYPE_FIFO: 3594105694Srwatson case DTYPE_VNODE: 3595105694Srwatson if (error == 0) 3596105694Srwatson error = mac_externalize_vnode_label(&intlabel, 3597105694Srwatson elements, buffer, mac.m_buflen, M_WAITOK); 3598105694Srwatson mac_destroy_vnode_label(&intlabel); 3599105694Srwatson break; 3600105694Srwatson case DTYPE_PIPE: 3601105694Srwatson error = mac_externalize_pipe_label(&intlabel, elements, 3602105694Srwatson buffer, mac.m_buflen, M_WAITOK); 3603105694Srwatson mac_destroy_pipe_label(&intlabel); 3604105694Srwatson break; 3605105694Srwatson default: 3606105694Srwatson panic("__mac_get_fd: corrupted label_type"); 3607105694Srwatson } 3608105694Srwatson 3609100979Srwatson if (error == 0) 3610105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3611100979Srwatson 3612105694Srwatsonout: 3613105694Srwatson mtx_unlock(&Giant); /* VFS */ 3614105694Srwatson free(buffer, M_MACTEMP); 3615105694Srwatson free(elements, M_MACTEMP); 3616100979Srwatson 3617100979Srwatson return (error); 3618100979Srwatson} 3619100979Srwatson 3620100979Srwatson/* 3621100979Srwatson * MPSAFE 3622100979Srwatson */ 3623100979Srwatsonint 3624100979Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3625100979Srwatson{ 3626105694Srwatson char *elements, *buffer; 3627100979Srwatson struct nameidata nd; 3628105694Srwatson struct label intlabel; 3629105694Srwatson struct mac mac; 3630100979Srwatson int error; 3631100979Srwatson 3632105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3633105694Srwatson if (error) 3634105694Srwatson return (error); 3635105694Srwatson 3636105694Srwatson error = mac_check_structmac_consistent(&mac); 3637105694Srwatson if (error) 3638105694Srwatson return (error); 3639105694Srwatson 3640105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3641105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3642105694Srwatson if (error) { 3643105694Srwatson free(elements, M_MACTEMP); 3644105694Srwatson return (error); 3645105694Srwatson } 3646105694Srwatson 3647105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3648105694Srwatson mtx_lock(&Giant); /* VFS */ 3649105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3650105694Srwatson td); 3651100979Srwatson error = namei(&nd); 3652100979Srwatson if (error) 3653100979Srwatson goto out; 3654100979Srwatson 3655105694Srwatson mac_init_vnode_label(&intlabel); 3656105988Srwatson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3657105988Srwatson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3658105988Srwatson mac.m_buflen, M_WAITOK); 3659105694Srwatson 3660100979Srwatson NDFREE(&nd, 0); 3661105694Srwatson mac_destroy_vnode_label(&intlabel); 3662105694Srwatson 3663105694Srwatson if (error == 0) 3664105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3665105694Srwatson 3666105694Srwatsonout: 3667105694Srwatson mtx_unlock(&Giant); /* VFS */ 3668105694Srwatson 3669105694Srwatson free(buffer, M_MACTEMP); 3670105694Srwatson free(elements, M_MACTEMP); 3671105694Srwatson 3672105694Srwatson return (error); 3673105694Srwatson} 3674105694Srwatson 3675105694Srwatson/* 3676105694Srwatson * MPSAFE 3677105694Srwatson */ 3678105694Srwatsonint 3679105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3680105694Srwatson{ 3681105694Srwatson char *elements, *buffer; 3682105694Srwatson struct nameidata nd; 3683105694Srwatson struct label intlabel; 3684105694Srwatson struct mac mac; 3685105694Srwatson int error; 3686105694Srwatson 3687105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3688100979Srwatson if (error) 3689105694Srwatson return (error); 3690105694Srwatson 3691105694Srwatson error = mac_check_structmac_consistent(&mac); 3692105694Srwatson if (error) 3693105694Srwatson return (error); 3694105694Srwatson 3695105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3696105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3697105694Srwatson if (error) { 3698105694Srwatson free(elements, M_MACTEMP); 3699105694Srwatson return (error); 3700105694Srwatson } 3701105694Srwatson 3702105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3703105694Srwatson mtx_lock(&Giant); /* VFS */ 3704105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3705105694Srwatson td); 3706105694Srwatson error = namei(&nd); 3707105694Srwatson if (error) 3708100979Srwatson goto out; 3709100979Srwatson 3710105694Srwatson mac_init_vnode_label(&intlabel); 3711105988Srwatson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3712105988Srwatson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3713105988Srwatson mac.m_buflen, M_WAITOK); 3714105694Srwatson NDFREE(&nd, 0); 3715105694Srwatson mac_destroy_vnode_label(&intlabel); 3716100979Srwatson 3717105694Srwatson if (error == 0) 3718105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3719105694Srwatson 3720100979Srwatsonout: 3721105694Srwatson mtx_unlock(&Giant); /* VFS */ 3722105694Srwatson 3723105694Srwatson free(buffer, M_MACTEMP); 3724105694Srwatson free(elements, M_MACTEMP); 3725105694Srwatson 3726100979Srwatson return (error); 3727100979Srwatson} 3728100979Srwatson 3729100979Srwatson/* 3730100979Srwatson * MPSAFE 3731100979Srwatson */ 3732100979Srwatsonint 3733100979Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3734100979Srwatson{ 3735105694Srwatson struct label intlabel; 3736105694Srwatson struct pipe *pipe; 3737100979Srwatson struct file *fp; 3738100979Srwatson struct mount *mp; 3739100979Srwatson struct vnode *vp; 3740105694Srwatson struct mac mac; 3741105694Srwatson char *buffer; 3742100979Srwatson int error; 3743100979Srwatson 3744105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3745100979Srwatson if (error) 3746105694Srwatson return (error); 3747100979Srwatson 3748105694Srwatson error = mac_check_structmac_consistent(&mac); 3749100979Srwatson if (error) 3750105694Srwatson return (error); 3751100979Srwatson 3752105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3753105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3754105694Srwatson if (error) { 3755105694Srwatson free(buffer, M_MACTEMP); 3756105694Srwatson return (error); 3757105694Srwatson } 3758105694Srwatson 3759105694Srwatson mtx_lock(&Giant); /* VFS */ 3760105694Srwatson 3761105694Srwatson error = fget(td, SCARG(uap, fd), &fp); 3762100979Srwatson if (error) 3763105694Srwatson goto out; 3764100979Srwatson 3765100979Srwatson switch (fp->f_type) { 3766100979Srwatson case DTYPE_FIFO: 3767100979Srwatson case DTYPE_VNODE: 3768105694Srwatson mac_init_vnode_label(&intlabel); 3769105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3770105694Srwatson if (error) { 3771105694Srwatson mac_destroy_vnode_label(&intlabel); 3772105694Srwatson break; 3773105694Srwatson } 3774105694Srwatson 3775100979Srwatson vp = (struct vnode *)fp->f_data; 3776100979Srwatson error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3777105694Srwatson if (error != 0) { 3778105694Srwatson mac_destroy_vnode_label(&intlabel); 3779100979Srwatson break; 3780105694Srwatson } 3781100979Srwatson 3782100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3783100979Srwatson error = vn_setlabel(vp, &intlabel, td->td_ucred); 3784100979Srwatson VOP_UNLOCK(vp, 0, td); 3785100979Srwatson vn_finished_write(mp); 3786105694Srwatson 3787105694Srwatson mac_destroy_vnode_label(&intlabel); 3788100979Srwatson break; 3789105694Srwatson 3790100979Srwatson case DTYPE_PIPE: 3791105694Srwatson mac_init_pipe_label(&intlabel); 3792105694Srwatson error = mac_internalize_pipe_label(&intlabel, buffer); 3793105694Srwatson if (error == 0) { 3794105694Srwatson pipe = (struct pipe *)fp->f_data; 3795105694Srwatson PIPE_LOCK(pipe); 3796105694Srwatson error = mac_pipe_label_set(td->td_ucred, pipe, 3797105694Srwatson &intlabel); 3798105694Srwatson PIPE_UNLOCK(pipe); 3799105694Srwatson } 3800105694Srwatson 3801105694Srwatson mac_destroy_pipe_label(&intlabel); 3802100979Srwatson break; 3803105694Srwatson 3804100979Srwatson default: 3805100979Srwatson error = EINVAL; 3806100979Srwatson } 3807100979Srwatson 3808100979Srwatson fdrop(fp, td); 3809105694Srwatsonout: 3810105694Srwatson mtx_unlock(&Giant); /* VFS */ 3811105694Srwatson 3812105694Srwatson free(buffer, M_MACTEMP); 3813105694Srwatson 3814100979Srwatson return (error); 3815100979Srwatson} 3816100979Srwatson 3817100979Srwatson/* 3818100979Srwatson * MPSAFE 3819100979Srwatson */ 3820100979Srwatsonint 3821100979Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3822100979Srwatson{ 3823105694Srwatson struct label intlabel; 3824100979Srwatson struct nameidata nd; 3825100979Srwatson struct mount *mp; 3826105694Srwatson struct mac mac; 3827105694Srwatson char *buffer; 3828100979Srwatson int error; 3829100979Srwatson 3830105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3831100979Srwatson if (error) 3832105694Srwatson return (error); 3833100979Srwatson 3834105694Srwatson error = mac_check_structmac_consistent(&mac); 3835100979Srwatson if (error) 3836105694Srwatson return (error); 3837100979Srwatson 3838105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3839105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3840105694Srwatson if (error) { 3841105694Srwatson free(buffer, M_MACTEMP); 3842105694Srwatson return (error); 3843105694Srwatson } 3844105694Srwatson 3845105694Srwatson mac_init_vnode_label(&intlabel); 3846105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3847105694Srwatson free(buffer, M_MACTEMP); 3848105694Srwatson if (error) { 3849105694Srwatson mac_destroy_vnode_label(&intlabel); 3850105694Srwatson return (error); 3851105694Srwatson } 3852105694Srwatson 3853105694Srwatson mtx_lock(&Giant); /* VFS */ 3854105694Srwatson 3855105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3856105694Srwatson td); 3857100979Srwatson error = namei(&nd); 3858105694Srwatson if (error == 0) { 3859105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3860105694Srwatson if (error == 0) 3861105694Srwatson error = vn_setlabel(nd.ni_vp, &intlabel, 3862105694Srwatson td->td_ucred); 3863105694Srwatson vn_finished_write(mp); 3864105694Srwatson } 3865105694Srwatson 3866105694Srwatson NDFREE(&nd, 0); 3867105694Srwatson mtx_unlock(&Giant); /* VFS */ 3868105694Srwatson mac_destroy_vnode_label(&intlabel); 3869105694Srwatson 3870105694Srwatson return (error); 3871105694Srwatson} 3872105694Srwatson 3873105694Srwatson/* 3874105694Srwatson * MPSAFE 3875105694Srwatson */ 3876105694Srwatsonint 3877105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3878105694Srwatson{ 3879105694Srwatson struct label intlabel; 3880105694Srwatson struct nameidata nd; 3881105694Srwatson struct mount *mp; 3882105694Srwatson struct mac mac; 3883105694Srwatson char *buffer; 3884105694Srwatson int error; 3885105694Srwatson 3886105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3887100979Srwatson if (error) 3888105694Srwatson return (error); 3889105694Srwatson 3890105694Srwatson error = mac_check_structmac_consistent(&mac); 3891100979Srwatson if (error) 3892105694Srwatson return (error); 3893100979Srwatson 3894105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3895105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3896105694Srwatson if (error) { 3897105694Srwatson free(buffer, M_MACTEMP); 3898105694Srwatson return (error); 3899105694Srwatson } 3900105694Srwatson 3901105694Srwatson mac_init_vnode_label(&intlabel); 3902105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3903105694Srwatson free(buffer, M_MACTEMP); 3904105694Srwatson if (error) { 3905105694Srwatson mac_destroy_vnode_label(&intlabel); 3906105694Srwatson return (error); 3907105694Srwatson } 3908105694Srwatson 3909105694Srwatson mtx_lock(&Giant); /* VFS */ 3910105694Srwatson 3911105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3912105694Srwatson td); 3913105694Srwatson error = namei(&nd); 3914105694Srwatson if (error == 0) { 3915105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3916105694Srwatson if (error == 0) 3917105694Srwatson error = vn_setlabel(nd.ni_vp, &intlabel, 3918105694Srwatson td->td_ucred); 3919105694Srwatson vn_finished_write(mp); 3920105694Srwatson } 3921105694Srwatson 3922100979Srwatson NDFREE(&nd, 0); 3923105694Srwatson mtx_unlock(&Giant); /* VFS */ 3924105694Srwatson mac_destroy_vnode_label(&intlabel); 3925105694Srwatson 3926100979Srwatson return (error); 3927100979Srwatson} 3928100979Srwatson 3929105694Srwatson/* 3930105694Srwatson * MPSAFE 3931105694Srwatson */ 3932102123Srwatsonint 3933102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap) 3934102123Srwatson{ 3935102123Srwatson struct mac_policy_conf *mpc; 3936102123Srwatson char target[MAC_MAX_POLICY_NAME]; 3937102123Srwatson int error; 3938102123Srwatson 3939102123Srwatson error = copyinstr(SCARG(uap, policy), target, sizeof(target), NULL); 3940102123Srwatson if (error) 3941102123Srwatson return (error); 3942102123Srwatson 3943102123Srwatson error = ENOSYS; 3944102123Srwatson MAC_POLICY_LIST_BUSY(); 3945102123Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3946102123Srwatson if (strcmp(mpc->mpc_name, target) == 0 && 3947102123Srwatson mpc->mpc_ops->mpo_syscall != NULL) { 3948102123Srwatson error = mpc->mpc_ops->mpo_syscall(td, 3949102123Srwatson SCARG(uap, call), SCARG(uap, arg)); 3950102123Srwatson goto out; 3951102123Srwatson } 3952102123Srwatson } 3953102123Srwatson 3954102123Srwatsonout: 3955102123Srwatson MAC_POLICY_LIST_UNBUSY(); 3956102123Srwatson return (error); 3957102123Srwatson} 3958102123Srwatson 3959100979SrwatsonSYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3960100979SrwatsonSYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3961100979Srwatson 3962100979Srwatson#else /* !MAC */ 3963100979Srwatson 3964100979Srwatsonint 3965105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3966105694Srwatson{ 3967105694Srwatson 3968105694Srwatson return (ENOSYS); 3969105694Srwatson} 3970105694Srwatson 3971105694Srwatsonint 3972100979Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3973100979Srwatson{ 3974100979Srwatson 3975100894Srwatson return (ENOSYS); 3976100894Srwatson} 3977100894Srwatson 3978100894Srwatsonint 3979100894Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3980100894Srwatson{ 3981100894Srwatson 3982100894Srwatson return (ENOSYS); 3983100894Srwatson} 3984100894Srwatson 3985100894Srwatsonint 3986100894Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3987100894Srwatson{ 3988100894Srwatson 3989100894Srwatson return (ENOSYS); 3990100894Srwatson} 3991100894Srwatson 3992100894Srwatsonint 3993100894Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3994100894Srwatson{ 3995100894Srwatson 3996100894Srwatson return (ENOSYS); 3997100894Srwatson} 3998100894Srwatson 3999100894Srwatsonint 4000105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 4001105694Srwatson{ 4002105694Srwatson 4003105694Srwatson return (ENOSYS); 4004105694Srwatson} 4005105694Srwatson 4006105694Srwatsonint 4007100894Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 4008100894Srwatson{ 4009100894Srwatson 4010100894Srwatson return (ENOSYS); 4011100894Srwatson} 4012100894Srwatson 4013100894Srwatsonint 4014100894Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 4015100894Srwatson{ 4016100894Srwatson 4017100894Srwatson return (ENOSYS); 4018100894Srwatson} 4019100979Srwatson 4020102123Srwatsonint 4021105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 4022105694Srwatson{ 4023105694Srwatson 4024105694Srwatson return (ENOSYS); 4025105694Srwatson} 4026105694Srwatson 4027105694Srwatsonint 4028102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap) 4029102123Srwatson{ 4030102123Srwatson 4031102123Srwatson return (ENOSYS); 4032102123Srwatson} 4033102123Srwatson 4034105694Srwatson#endif 4035